一般我們的app中除了賬號密碼登錄以外炭剪,還會提供第三方快捷登錄。而微信授權(quán)登錄就是最長使用的一種翔脱。你可以用友盟的第三方登錄奴拦,這是對微信平臺的登錄的一個二次封裝,接口更簡單届吁。這里給出一個地址友盟的第三方登錄错妖。友盟的第三方登錄比較簡單绿鸣,但是可能會出現(xiàn)不穩(wěn)定,我之前的項(xiàng)目中就有過這種情況暂氯,可能是當(dāng)時在維護(hù)潮模,但大部分情況還是沒有問題的。今天著重聊一下微信官方平臺的微信登錄的集成方式株旷。
微信官方平臺的集成文檔
關(guān)于創(chuàng)建應(yīng)用再登,成為開發(fā)者,獲取簽名這幾步是要在集成微信登錄之前需要準(zhǔn)備的晾剖,具體的可以參考這位作者锉矢,感謝這位博主,里面有很詳細(xì)的步驟齿尽。
安卓第三方登錄之微信登錄(圖文詳解)
微信登錄集成步驟
1沽损、引入微信SDK依賴
1)在build.gradle的dependencies中添加如下依賴
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
2、申明應(yīng)用權(quán)限
<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() {
//第二個參數(shù)是指你應(yīng)用在微信開放平臺上的AppID
mWxApi = WXAPIFactory.createWXAPI(this, MainConstant.WX.WEIXIN_APP_ID, false);
// 將該app注冊到微信
mWxApi.registerApp(MainConstant.WX.WEIXIN_APP_ID);
}
}
4绵估、請求微信授權(quán)登錄
//先判斷是否安裝微信APP,按照微信的說法,目前移動應(yīng)用上微信登錄只提供原生的登錄方式卡骂,需要用戶安裝微信客戶端才能配合使用国裳。
if (!WXUtils.isWXAppInstalled()) {
ToastUtils.showToast("您還未安裝微信客戶端");
return;
}
//微信登錄
public void wxLogin() {
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "diandi_wx_login";
//像微信發(fā)送請求
MyApplication.mWxApi.sendReq(req);
}
這個方法就是調(diào)用微信登錄界面來進(jìn)行確認(rèn)登錄的。
5全跨、創(chuàng)建WXEntryActivity.java來接收微信的響應(yīng)事件
WXEntryActivity是一個Activity缝左,用來接收微信的響應(yīng)信息。這里有幾個需要注意的地方:
它必須在"包名.wxapi"這個包下浓若,如:你的應(yīng)用包名為:com.xx.test渺杉,則WXEntryActivity所在的包名必須為com.xx.test.wxapi。這里和簽名一樣挪钓,很重要是越,你如果名字錯了,或者包名的位置錯了碌上,都是不能回調(diào)的倚评,切記
創(chuàng)建后在AndroidManifest.xml文件中對WXEntryActivity進(jìn)行設(shè)置:
<!--微信-->
<activity
android:name=".wxapi.WXEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
- WXEntryActivity的具體實(shí)現(xiàn),主要是處理微信和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;
//這句沒有寫,是不能執(zhí)行回調(diào)的方法的
MyApplication.mWxApi.handleIntent(getIntent(), this);
}
// 微信發(fā)送請求到第三方應(yīng)用時蔓纠,會回調(diào)到該方法
@Override
public void onReq(BaseReq baseReq) {
}
// 第三方應(yīng)用發(fā)送到微信的請求處理后的響應(yīng)結(jié)果,會回調(diào)到該方法
//app發(fā)送消息給微信吗蚌,處理返回消息的回調(diào)
@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:
//用戶拒絕授權(quán)
ToastUtils.showToast(mContext, "拒絕授權(quán)微信登錄");
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次網(wǎng)絡(luò)請求獲取access_token和用戶個人信息
WXLoginUtils().getWXLoginResult(code, this);
} else if (type == RETURN_MSG_TYPE_SHARE) {
ToastUtils.showToast(mContext, "微信分享成功");
}
break;
}
}
}
當(dāng)微信授權(quán)第三登錄后蚯妇,會自動調(diào)用WXEntryActivity的onResp方法敷燎,可以在((SendAuth.Resp) resp).code得到“授權(quán)臨時票據(jù)code”,之后可以通過code參數(shù)加上AppID和AppSecret等暂筝,通過API換取access_token,再通過access_token進(jìn)行接口調(diào)用,比如獲取用戶個人信息等
下面是獲取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<String, Object> 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<WXAccessTokenBean>() {
@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(); //接口調(diào)用憑證
String openid = wxAccessTokenBean.getOpenid(); //授權(quán)用戶唯一標(biāo)識
//當(dāng)且僅當(dāng)該移動應(yīng)用已獲得該用戶的userinfo授權(quán)時,才會出現(xiàn)該字段
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);
}
});
}
/**
* 獲取微信登錄饭豹,用戶授權(quán)后的個人信息
*
* @param access_token
* @param openid
* @param unionid
*/
private void getWXUserInfo(final String access_token, final String openid, final String unionid) {
Map<String, Object> 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<WXUserInfoBean>() {
@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);
}
});
}
最后拿到微信登錄返回的數(shù)據(jù)鸵赖,調(diào)用你自己的APP的登錄接口,把數(shù)據(jù)提交給后臺即可拄衰。