Android第三方登录_微信

参考资料

1.Android接入指南(微信官方):
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417751808&token=&lang=zh_CN
2.Android开发第三方登录–微信登录
https://blog.csdn.net/pkandroid/article/details/72974552?utm_source=itdadao&utm_medium=referral
3.Android 微信登录
https://blog.csdn.net/pkandroid/article/details/72974552?utm_source=itdadao&utm_medium=referral
4.EventBus框架简单使用
https://www.jianshu.com/p/f9ae5691e1bb
5.Android 一个改善的okHttp封装库
https://blog.csdn.net/lmj623565791/article/details/49734867/
6.微信token的存储(未实现,仅了解)
https://www.csdn.net/article/2014-08-15/2821220-weixin
https://www.cnblogs.com/penglei-it/p/wx_yh.html

EventBus是一种用于Android的发布/订阅事件总线。它有很多优点:简化应用组件间的通信;解耦事件的发送者和接收者;避免复杂和容易出错的依赖和生命周期的问题;很快,专门为高性能优化过等等。

如果,当前没有微信登录权限,可以使用官方demo的appid和包名及签名来进行练习,这就意味着你需要修改自己应用程序的包名。

Android Studio如何在debug模式下进行签名测试

signingConfigs {
    debug {
        storeFile file("../debug.keystore")
    }
}

或者

File--ProjectStructure--app--Signing添加签名文件--Build Types进行添加设置即可

代码

码云:https://gitee.com/zhangtao3/android_thirdlogin

准备

微信开放平台申请appid,认真正确填写包名和签名(至少保证在调用微信登录之前包名和签名一定要是正确的),微信登录需要认证开发者才能申请开通,认证开发者需付费。
>>>签名生成工具<<<

开始

1.添加依赖

implementation 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'(包含统计功能)
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'

2.AndroidManifest添加权限

<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"/>

3.在MyApplication注册到微信

private void initWeiXin() {
        // 通过WXAPIFactory工厂,获取IWxApi实例
        wxApi = WXAPIFactory.createWXAPI(MyApplication.getAppContext(), GlobalData.WX_APP_ID, true);
        // 将应用的AppID注册到微信
        wxApi.registerApp(GlobalData.WX_APP_ID);
    }

4.发送请求或响应到微信(微信登录)

 private void loginWeixin() {
        if (MyApplication.wxApi.isWXAppInstalled() && MyApplication.wxApi.isWXAppSupportAPI()) {
            final SendAuth.Req req = new SendAuth.Req();
            req.scope = "snsapi_userinfo";//应用授权作用域
            req.state = "wechat_sdk_demo";//用于保持请求和回调的状态,授权请求后原样带回给第三方。
            MyApplication.wxApi.sendReq(req);
        } else {
            ToastUtils.showShortToast("未安装微信");
        }
    }

5.接收微信的请求及返回值(接受登录回调),参照接入指南操作3步即可

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //注意:
        //第三方开发者如果使用透明界面来实现WXEntryActivity,需要判断handleIntent的返回值,如果返回值为false,则说明入参不合法未被SDK处理,应finish当前透明界面,避免外部通过传递非法参数的Intent导致停留在透明界面,引起用户的疑惑
        try {
            boolean result = MyApplication.wxApi.handleIntent(getIntent(), this);
            if (!result) {
                Log.d(GlobalData.TAG, "参数不合法,未被SDK处理,退出");
                finish();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        MyApplication.wxApi.handleIntent(data, this);
    }

    //
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        MyApplication.wxApi.handleIntent(intent, this);
        finish();
    }

    @Override
    public void onReq(BaseReq baseReq) {
        Log.d("wx_onReq", baseReq.toString());
    }

    @Override
    public void onResp(BaseResp baseResp) {
        String result = new Gson().toJson(baseResp);
        Log.d(GlobalData.TAG, "wx_onResp:" + result);
        switch (baseResp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                //发送EventBus事件
                String code = ((SendAuth.Resp) baseResp).code;
                EventBus.getDefault().post(new MessageEvent(code));
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                // 取消
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                // 拒绝
                ToastUtils.showShortToast("取消微信登录");
                break;
            default:
                break;
        }
        finish();
    }
}

6.在完成步骤五之前,需要在MainAvtivity注册EventBus,就收EventsBus

 // 注册EventBus
 EventBus.getDefault().register(this);
// 接受EventBus
@Subscribe(threadMode = ThreadMode.MAIN)
    public void Event(MessageEvent messageEvent) {
        // 获取微信授权code
        String code = messageEvent.getMessage();
        // 获取token,openid
        // 获取个人信息
        getWxToken(code);
    }

7.获取token

// 通过code获取access_token
private void getWxToken(String code) {
        Map<String, String> params = new HashMap<>();
        params.put("appid", GlobalData.WX_APP_ID);
        params.put("secret", GlobalData.WX_APP_SECRET);
        params.put("code", code);
        params.put("grant_type", "authorization_code");

        //{"access_token":"11_-T4RsKGs8-SXKCtdYUkaHpx5AZyTCmaQRk6SWR0ZcwKYjcvY0eDJljhx683N1aNJ2j0bO8ndnu8ZuQGTlooPxB8dR8iK_g81sggRH6ZhPEA",
        // "expires_in":7200,"refresh_token":"11_Vn-rr9i57WDrH4YjxWg_R1qdRfXZusmAwXvl7WSJfvGeMRYx215dKbtWKFh9LA0Bothg6mIRTp_yJjuP3cbBaEhjoZAhT_l3aHnJGGpnAUc",
        // "openid":"xxx","scope":"snsapi_userinfo","unionid":"xxx"}
        OkHttpUtils.getInstance().getRequestAsync(GlobalData.WX_GET_TOKEN, params, new OkHttpUtils.MyOkHttpCall() {
            @Override
            public void success(Call call, Response response) throws IOException {
                // response.body()只可调用一次
                final String resultString = response.body().string();
                Log.d(GlobalData.TAG, "http_wx_getToken: " + resultString);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            JSONObject resultObj = new JSONObject(resultString);
                            if (resultObj.getString("access_token") != null) {
                                String access_token = resultObj.getString("access_token");
                                String openid = resultObj.getString("openid");
                                getWxUserInfo(access_token, openid);
                            } else {
                                Log.e(GlobalData.TAG, "run_err: " + resultObj.toString());
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        });
    }

8.获取个人信息

// 获取用户个人信息(UnionID机制)
private void getWxUserInfo(String access_token, String openid) {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", access_token);
        params.put("openid", openid);
        //{"openid":"xxx","nickname":"Animal_1","sex":1,"language":"zh_CN","city":"Xi'an","province":"Shaanxi","country":"CN",
        // "headimgurl":"http:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/DYAIOgq83erSSvDC5t1xWD7CiaicGFtZptRtwPKP969ygibS212MnSG72Cv9XoehOKCSQBIepsjYp3ricDPGzic923g\/132",
        // "privilege":[],"unionid":"xxxxx"}
        OkHttpUtils.getInstance().getRequestAsync(GlobalData.WX_GET_USER_INFO, params, new OkHttpUtils.MyOkHttpCall() {
            @Override
            public void success(Call call, Response response) throws IOException {
                // response.body()只可调用一次
                final String resultString = response.body().string();
                Log.d(GlobalData.TAG, "http_wx_getUserInfo: " + resultString);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            JSONObject resultObj = new JSONObject(resultString);
                            if (resultObj.getString("nickname") != null) {
                                tv_result.setText("微信nickname:" + resultObj.getString("nickname"));
                            } else {
                                Log.e(GlobalData.TAG, "run_err: " + resultObj.toString());
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        });
    }

结束

参照网上资源基本就可以很快实现,我一开始没有正确的应用签名,导致一直吊不起微信授权页面,纠结了好久,网上的解决方案是清理缓存或者卸载微信重新尝试,我使用的模拟器,重新安装后依旧没有授权页面,画面一闪而逝,但是各种数据都能拿到,好在正确填写签名后,别人的可以正常使用。所以也就这样了。

猜你喜欢

转载自blog.csdn.net/a564239493/article/details/80786929