一般我们的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" />
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和用户个人信息的代码
通过第二步获取的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的登录接口,把数据提交给后台即可。