安卓第三方登录之微信登录

一般我们的app中除了账号密码登录以外,还会提供第三方快捷登录。而微信授权登录就是最长使用的一种。你可以用友盟的第三方登录,这是对微信平台的登录的一个二次封装,接口更简单。这里给出一个地址友盟的第三方登录。友盟的第三方登录比较简单,但是可能会出现不稳定,我之前的项目中就有过这种情况,可能是当时在维护,但大部分情况还是没有问题的。今天着重聊一下微信官方平台的微信登录的集成方式。
微信官方平台的集成文档

关于创建应用,成为开发者,获取签名这几步是要在集成微信登录之前需要准备的,具体的可以参考这位作者,感谢这位博主,里面有很详细的步骤。
安卓第三方登录之微信登录(图文详解)

微信登录集成步骤

1、引入微信SDK依赖

1)在build.gradle的dependencies中添加如下依赖

compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'

2、申明应用权限

<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、向微信注册APP

public class MyApplication extends Application {

 public static IWXAPI mWxApi;

@Override
public void onCreate() {
    super.onCreate();
    registerToWX();
}

private void registerToWX() {
    //第二个参数是指你应用在微信开放平台上的AppID
    mWxApi = WXAPIFactory.createWXAPI(this, MainConstant.WX.WEIXIN_APP_ID, false);
    // 将该app注册到微信
    mWxApi.registerApp(MainConstant.WX.WEIXIN_APP_ID);
   }
}

4、请求微信授权登录

  //先判断是否安装微信APP,按照微信的说法,目前移动应用上微信登录只提供原生的登录方式,需要用户安装微信客户端才能配合使用。
     if (!WXUtils.isWXAppInstalled()) {
          ToastUtils.showToast("您还未安装微信客户端");
          return;
      }
    //微信登录
    public void wxLogin() {
        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "diandi_wx_login";
        //像微信发送请求
        MyApplication.mWxApi.sendReq(req);
    }

这个方法就是调用微信登录界面来进行确认登录的。

5、创建WXEntryActivity.java来接收微信的响应事件

  • WXEntryActivity是一个Activity,用来接收微信的响应信息。这里有几个需要注意的地方:

  • 它必须在"包名.wxapi"这个包下,如:你的应用包名为:com.xx.test,则WXEntryActivity所在的包名必须为com.xx.test.wxapi。这里和签名一样,很重要,你如果名字错了,或者包名的位置错了,都是不能回调的,切记

  • 创建后在AndroidManifest.xml文件中对WXEntryActivity进行设置:

 
        <activity
            android:name=".wxapi.WXEntryActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:exported="true"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />
  • WXEntryActivity的具体实现,主要是处理微信和app通信的不同event。
public class WXEntryActivity extends WXCallbackActivity implements IWXAPIEventHandler, IWXLoginView {
    private static final String TAG = "WXEntryActivity";
    private static final int RETURN_MSG_TYPE_LOGIN = 1; //登录
    private static final int RETURN_MSG_TYPE_SHARE = 2; //分享
    private Context mContext;

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

        mContext = this;
        //这句没有写,是不能执行回调的方法的
        MyApplication.mWxApi.handleIntent(getIntent(), this);
    }
    


    // 微信发送请求到第三方应用时,会回调到该方法
    @Override
    public void onReq(BaseReq baseReq) {

    }

    // 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
    //app发送消息给微信,处理返回消息的回调
    @Override
    public void onResp(BaseResp baseResp) {
        Log.i(TAG, "onResp:------>");
        Log.i(TAG, "error_code:---->" + baseResp.errCode);
        int type = baseResp.getType(); //类型:分享还是登录
        switch (baseResp.errCode) {
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                //用户拒绝授权
                ToastUtils.showToast(mContext, "拒绝授权微信登录");
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                //用户取消
                String message = "";
                if (type == RETURN_MSG_TYPE_LOGIN) {
                    message = "取消了微信登录";
                } else if (type == RETURN_MSG_TYPE_SHARE) {
                    message = "取消了微信分享";
                }
                ToastUtils.showToast(mContext, message);
                break;
            case BaseResp.ErrCode.ERR_OK:
                //用户同意
                if (type == RETURN_MSG_TYPE_LOGIN) {
                //用户换取access_token的code,仅在ErrCode为0时有效
                    String code = ((SendAuth.Resp) baseResp).code;
                    Log.i(TAG, "code:------>" + code);

                    //这里拿到了这个code,去做2次网络请求获取access_token和用户个人信息
                WXLoginUtils().getWXLoginResult(code, this);

                } else if (type == RETURN_MSG_TYPE_SHARE) {
                    ToastUtils.showToast(mContext, "微信分享成功");
                }
                break;
        }
    }
}

当微信授权第三登录后,会自动调用WXEntryActivity的onResp方法,可以在((SendAuth.Resp) resp).code得到“授权临时票据code”,之后可以通过code参数加上AppID和AppSecret等,通过API换取access_token,再通过access_token进行接口调用,比如获取用户个人信息等

下面是获取access_token和用户个人信息的代码

  • 通过code获取access_token
    获取第一步的code后,请求以下链接获取access_token:
    https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

通过第二步获取的access_token和openid来获取用户信息
https://api.weixin.qq.com//sns/userinfo

 /**
     * 获取access_token:
     *
     * @param code 用户或取access_token的code,仅在ErrCode为0时有效
     */
    private void getAccessToken(final String code) {
        Map params = new HashMap();
        params.put("appid", MainConstant.WX.WEIXIN_APP_ID);
        params.put("secret", MainConstant.WX.WEIXIN_APP_SECRET);
        params.put("code", code);
        params.put("grant_type", "authorization_code");
        HttpUtils.getWXAccessTokenBean(URLConstant.URL_WX_BASE, params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber() {
                    @Override
                    public void onCompleted() {
                        Log.i(TAG, "onCompleted:-------->");
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        Log.i(TAG, "onError:-------->" + throwable.getMessage());
                    }

                    @Override
                    public void onNext(WXAccessTokenBean wxAccessTokenBean) {
                        Log.i(TAG, "onNext: ----->");
                        String access_token = wxAccessTokenBean.getAccess_token(); //接口调用凭证
                        String openid = wxAccessTokenBean.getOpenid(); //授权用户唯一标识
                        //当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段
                        String unionid = wxAccessTokenBean.getUnionid();
                        Log.i(TAG, "access_token:----->" + access_token);
                        Log.i(TAG, "openid:----->" + openid);
                        Log.i(TAG, "unionid:----->" + unionid);
                        getWXUserInfo(access_token, openid, unionid);
                    }
                });
    }
/**
     * 获取微信登录,用户授权后的个人信息
     *
     * @param access_token
     * @param openid
     * @param unionid
     */
    private void getWXUserInfo(final String access_token, final String openid, final String unionid) {
        Map params = new HashMap();
        params.put("access_token", access_token);
        params.put("openid", openid);
        HttpUtils.getWXUserInfoBean(URLConstant.URL_WX_BASE, params)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber() {
                    @Override
                    public void onCompleted() {
                        Log.i(TAG, "getWXUserInfo:--------> onCompleted");
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        Log.i(TAG, "getWXUserInfo:--------> onError" + throwable.getMessage());
                    }

                    @Override
                    public void onNext(WXUserInfoBean wxUserInfoBean) {
                        Log.i(TAG, "getWXUserInfo:--------> onNext");
                        String country = wxUserInfoBean.getCountry(); //国家
                        String province = wxUserInfoBean.getProvince(); //省
                        String city = wxUserInfoBean.getCity(); //市
                        String nickname = wxUserInfoBean.getNickname(); //用户名
                        int sex = wxUserInfoBean.getSex(); //性别
                        String headimgurl = wxUserInfoBean.getHeadimgurl(); //头像url
                        Log.i(TAG, "country:-------->" + country);
                        Log.i(TAG, "province:-------->" + province);
                        Log.i(TAG, "city:-------->" + city);
                        Log.i(TAG, "nickname:-------->" + nickname);
                        Log.i(TAG, "sex:-------->" + sex);
                        Log.i(TAG, "headimgurl:-------->" + headimgurl);
                    }
                });
    }

最后拿到微信登录返回的数据,调用你自己的APP的登录接口,把数据提交给后台即可。



链接:https://www.jianshu.com/p/57128969e7eb

你可能感兴趣的:(安卓第三方登录之微信登录)