• 详解Android微信登录与分享


    Android 使用微信登录、分享功能

    具体的文档详情微信官网上介绍(微信官网文档),本人直接按照项目部署步骤进行讲解:

    第一步:申请你的AppID;

    第二步:依赖

    dependencies {
        compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:1.0.2'
    }

    或者:

    dependencies {
        compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:1.0.2'
    }

    这两个依赖包的区别是前者包含统计功能,后者没有。

    第三步:在AndroidManifest.xml中加入必须的权限

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    第四步:注册到微信,微信的SDK在使用之前需要调用代码进行注册,注册可以是在调用微信SDK的Activity,但最好还是放到入口Activity或者Application中;

    WxApplication.java

    public static String APP_ID="你的APPID";
    public static IWXAPI api;
    public void onCreate() {
            super.onCreate();
            api = WXAPIFactory.createWXAPI(this, APP_ID, true);
            api.registerApp(APP_ID);  
    }  

    第五步:微信登录。

      5.1 点击你的微信登录按钮,进行微信授权,首先需要获取一个code值,在包名下新建一个包,这里必须这样,不能随意命名,比如你的项目包名是:come.shenhua.wx则新建的包为come.shenhua.wx.wxapi在该包下创建一个WXEntryActivity继承IWXAPIEventHandler;(注意Activity的命名也不能随意更改)

    LoginActivity.java

      

    private void onClickWeChatLogin() {
            if (WxApplicaiton.api == null) {
                WxApplication.api = WXAPIFactory.createWXAPI(this, WxApplication.APP_ID, true);
            }
            if (!WxApplication.api.isWXAppInstalled()) {
                ToastUtils.toast("您手机尚未安装微信,请安装后再登录");
                return;
            }
            WxApplication.api.registerApp(WxApplication.APP_ID);
            SendAuth.Req req = new SendAuth.Req();
            req.scope = "snsapi_userinfo";
            req.state = "wechat_sdk_xb_live_state";//官方说明:用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
            WxApplication.api.sendReq(req);
        }

      在AndroidManifest.xml中加入,(android:exported="true" 一定不能少)

    <activity
                android:name=".wxapi.WXEntryActivity"
                android:exported="true" />
    WXEntryActivity.java
    public class WXEntryActivity extends AppCompatActivity implements IWXAPIEventHandler {
        public static final String TAG = WXEntryActivity.class.getSimpleName();
        public static String code;
        public static BaseResp resp = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_wxentry);
            boolean handleIntent = XBLiveApplication.api.handleIntent(getIntent(), this);
         //下面代码是判断微信分享后返回WXEnteryActivity的,如果handleIntent==false,说明没有调用IWXAPIEventHandler,则需要在这里销毁这个透明的Activity;
    if(handleIntent==false){ Log.d(TAG, "onCreate: "+handleIntent); finish(); } } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); XBLiveApplication.api.handleIntent(intent, this); } @Override public void onReq(BaseReq baseReq) { Log.d(TAG, "onReq: "); finish(); } @Override public void onResp(BaseResp baseResp) { if (baseResp != null) { resp = baseResp; code = ((SendAuth.Resp) baseResp).code; //即为所需的code } switch (baseResp.errCode) { case BaseResp.ErrCode.ERR_OK: Log.d(TAG, "onResp: 成功"); finish(); break; case BaseResp.ErrCode.ERR_USER_CANCEL: Log.d(TAG, "onResp: 用户取消"); finish(); break; case BaseResp.ErrCode.ERR_AUTH_DENIED: Log.d(TAG, "onResp: 发送请求被拒绝"); finish(); break; } }

    resp和code定义成全局变量,在WXEntryWActivity页面销毁后登录页面会走onResume()方法,在这里开始其他操作

      5.2 拿到code后在登录页面通过code获取access_token,官网的说法是:“access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新”,所以拿到access_token后再次请求进行refresh_token,刷新后拿到access_token即可发送请求获取微信用户信息了;

      获取access_token的URL:AccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=你的appid&secret=你的AppSecret&code=授权获取到的code&grant_type=authorization_code";

      刷新access_token的URL:Refresh_tokenUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=你的appid&grant_type=refresh_token&refresh_token=上一步请求到的access_token;

      获取用户信息URL:UserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=刷新的access_token&openid=刷新access_token时获取的openid;

    
    
     @Override
        protected void onResume() {
            Log.d(TAG, "onResume: 1");
            super.onResume();
            //这里的判断是为了区分如果不是不是从WXEntryActivity页面销毁重启的,不走下面的代码
            if (WXEntryActivity.resp != null) {
                if (WXEntryActivity.resp.getType() == ConstantsAPI.COMMAND_SENDAUTH) {
                    Thread thread = new Thread(downloadRun);
                    thread.start();
                    try {
                        thread.join();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    
        public Runnable downloadRun = new Runnable() {
    
            @Override
            public void run() {
                WXGetAccessToken();
            }
        };
    
        //根据code获取access_token,这里用第三方volley框架进行post请求
        private void WXGetAccessToken() {
            String getAccessTokenUrl = AccessTokenUrl;
            StringRequest request = new StringRequest(Request.Method.GET, getAccessTokenUrl, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Log.d(TAG, "onResponse: " + response);
                    Gson gson = new Gson();
                    WeChatLoginTokenModel tokenModel = gson.fromJson(response, WeChatLoginTokenModel.class);
                    refresh_token = tokenModel.getRefresh_token();
                    WXGetRefreshAccessToken();
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
    
                }
            });
            request.setTag("weChatGetToken");
            XBLiveApplication.getHttpRequestQueue().add(request);
        }
    
        //拿到access_token后再次发送请求进行刷新access_token,拿到access_refresh和openid
        private void WXGetRefreshAccessToken() {
            String getRefresh_tokenUrl =Refresh_tokenUrl ;
            StringRequest request = new StringRequest(Request.Method.GET, getRefresh_tokenUrl, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Gson gson = new Gson();
                    WeChatLoginTokenModel tokenModel = gson.fromJson(response, WeChatLoginTokenModel.class);
                    String access_token = tokenModel.getAccess_token();
                    String openid = tokenModel.getOpenid();
                    WXGetUserInfo(access_token, openid);
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
    
                }
            });
            request.setTag("weChatGetRefreshToken");
            XBLiveApplication.getHttpRequestQueue().add(request);
        }
    
        //获取用户信息
        private void WXGetUserInfo(String access_token, String openid) {
            String getUserInfoUrl =UserInfoUr;
            StringRequest request = new StringRequest(Request.Method.GET, getUserInfoUrl, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Log.d(TAG, "onResponse3: " + response);
                    Gson gson = new Gson();
                    WeChatUserInfoModel userInfoModel = gson.fromJson(response, WeChatUserInfoModel.class);
                    String city = userInfoModel.getCity();
                    String userName = userInfoModel.getNickname();
                    String userIcon = userInfoModel.getHeadimgurl();
                    int sex = userInfoModel.getSex();//1:男;0:女;2:未知
                    String province = userInfoModel.getProvince();
                    openId_WX = userInfoModel.getOpenid();
                    ToastUtils.toast("登录成功");
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
    
                }
            });
        //下面代码是volley框架注册,请忽视 request.setTag(
    "weChatGetUserInfo"); XBLiveApplication.getHttpRequestQueue().add(request); }

    注意一点:在做测试时,微信的应用签名必须要保持一致,比如你在官网填写的是没有打包签名的应用签名,你测试的APP也没有打包签名,那么是没有问题,但是如果你微信官网上填写的是已经上线经过打包签名的应用签名,那你在做测试时必须要用打包签名的应用去做测试。

     第六步:微信分享到朋友圈、微信好友、添加微信收藏:

     分享收藏基本完全一样,也是需要先进行注册的,如果之前已经进行了注册就不需要注册,否则在调用分享的Activity中或者全局Application中进行注册;scene 有一下三种:

    SendMessageToWX.Req.WXSceneSession;分享到微信好友
    SendMessageToWX.Req.WXSceneTimeline;分享到微信朋友圈
    SendMessageToWX.Req.WXSceneFavorite;添加到微信收藏夹

      分享纯文本内容:

                  // 初始化一个WXTextObject对象
                            WXTextObject textObj = new WXTextObject();
                            textObj.text = text;
    
                            // 用WXTextObject对象初始化一个WXMediaMessage对象
                            WXMediaMessage msg = new WXMediaMessage();
                            msg.mediaObject = textObj;
                            // 发送文本类型的消息时,title字段不起作用
                            // msg.title = "Will be ignored";
                            msg.description = text;
    
                            // 构造一个Req
                            SendMessageToWX.Req req = new SendMessageToWX.Req();
                            req.transaction = buildTransaction("text"); // transaction字段用于唯一标识一个请求
                            req.message = msg;
                            req.scene = isTimelineCb.isChecked() ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
                            
                            // 调用api接口发送数据到微信
                            api.sendReq(req);

    分享音乐:

                    WXMusicObject music = new WXMusicObject();
                                music.musicUrl="http://staff2.ustc.edu.cn/~wdw/softdown/index.asp/0042515_05.ANDY.mp3";
    
                                WXMediaMessage msg = new WXMediaMessage();
                                msg.mediaObject = music;
                                msg.title = "Music Title ";
                                msg.description = "Music Album ";
    
                                Bitmap thumb = BitmapFactory.decodeResource(getResources(), R.drawable.send_music_thumb);
                                msg.thumbData = Util.bmpToByteArray(thumb, true);
    
                                SendMessageToWX.Req req = new SendMessageToWX.Req();
                                req.transaction = buildTransaction("music");
                                req.message = msg;
                                req.scene = isTimelineCb.isChecked() ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
                                api.sendReq(req);

    分享网页:

                            WXWebpageObject webpage = new WXWebpageObject();
                                            webpage.webpageUrl = "http://www.qq.com";
                                            WXMediaMessage msg = new WXMediaMessage(webpage);
                                            msg.title = "WebPage Title ";
                                            msg.description = "WebPage Description ";
                                            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.send_music_thumb);
                                            Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true);
                                            bmp.recycle();
                                            msg.thumbData = Util.bmpToByteArray(thumbBmp, true);
                                            SendMessageToWX.Req req = new SendMessageToWX.Req();
                                            req.transaction = buildTransaction("webpage");
                                            req.message = msg;
                                            req.scene = mTargetScene;
                                            api.sendReq(req);

    具体可参照官网Demo。(可分享纯文本内容,照片,音乐,视频,网页,链接等等)

      楼主在测试时发现,如果我分享的网页要显示一张图片,官方Demo给的是一张本地照片,而我的是图片地址,我做了一下处理:

      点击分享时先加载图片,写了一个while循环,直到拿到bitmap为止;

        case R.id.line_share_wechat:
                    if (!api.isWXAppInstalled()) {
                        ToastUtils.toast("您手机尚未安装微信,请安装后再登录");
                        return;
                    }
                    if (api == null) {
                        api = WXAPIFactory.createWXAPI(this,APP_ID, true);
                    }
                    mTargetScene = SendMessageToWX.Req.WXSceneSession;//share to wx
                    gotoDownLoadSharePic();break;

      

    private void gotoDownLoadSharePic() {
            new Thread() {
                @Override
                public void run() {
                    URL url = null;
                    try {
                        url = new URL(thumb);
                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                        conn.setDoInput(true);
                        conn.connect();
                        InputStream inputStream = conn.getInputStream();
                        bmp = BitmapFactory.decodeStream(inputStream);
    
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
            while (bmp == null) {
                Log.d(TAG, "onClick: bmp=" + bmp);
            }
            goToShareToWeChat(mTargetScene);
        }
    
        private void goToShareToWeChat(int targetScene) {
            WXWebpageObject mWebPage = new WXWebpageObject();
            mWebPage.webpageUrl = Constants.SHARE_QQ_URL + vid;
            msg = new WXMediaMessage(mWebPage);
            if (targetScene == SendMessageToWX.Req.WXSceneTimeline || targetScene == SendMessageToWX.Req.WXSceneFavorite) {
                msg.title = mTitleContent;
            } else {
                msg.title = name;
                msg.description = mTitleContent;
            }
            msg.setThumbImage(bmp);
            SendMessageToWX.Req req = new SendMessageToWX.Req();
            req.transaction = buildTransaction("webpage");
            req.message = msg;
            req.scene = targetScene;
            api.sendReq(req);
        }
  • 相关阅读:
    账户余额查询SQL(分类帐)
    基本值集定义
    EBS 各模块数据传送至总帐 需要运行的请求
    OU、库存组织与子库存
    AP 付款凭证
    WIP 完工入库单
    R12客户表结构分析
    ORACEL R12 总账和子账的关系
    JavaScript(转)
    ftp服务自动上传6410版子上的开发环境的设置
  • 原文地址:https://www.cnblogs.com/shen-hua/p/6343736.html
Copyright © 2020-2023  润新知