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

一般我們的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和用戶個人信息的代碼

通過第二步獲取的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ù)提交給后臺即可拄衰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末它褪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子翘悉,更是在濱河造成了極大的恐慌茫打,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妖混,死亡現(xiàn)場離奇詭異老赤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)制市,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門抬旺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人祥楣,你說我怎么就攤上這事开财。” “怎么了荣堰?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵床未,是天一觀的道長竭翠。 經(jīng)常有香客問我振坚,道長,這世上最難降的妖魔是什么斋扰? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任渡八,我火速辦了婚禮,結(jié)果婚禮上传货,老公的妹妹穿的比我還像新娘屎鳍。我一直安慰自己,他們只是感情好问裕,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布逮壁。 她就那樣靜靜地躺著,像睡著了一般粮宛。 火紅的嫁衣襯著肌膚如雪窥淆。 梳的紋絲不亂的頭發(fā)上卖宠,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機(jī)與錄音忧饭,去河邊找鬼扛伍。 笑死,一個胖子當(dāng)著我的面吹牛词裤,可吹牛的內(nèi)容都是我干的刺洒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼吼砂,長吁一口氣:“原來是場噩夢啊……” “哼逆航!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起帅刊,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤纸泡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后赖瞒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體女揭,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年栏饮,在試婚紗的時候發(fā)現(xiàn)自己被綠了吧兔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡袍嬉,死狀恐怖境蔼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情伺通,我是刑警寧澤箍土,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站罐监,受9級特大地震影響吴藻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弓柱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一沟堡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧矢空,春花似錦碧磅、人聲如沸窜骄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春复亏,著一層夾襖步出監(jiān)牢的瞬間绢彤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工蜓耻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留茫舶,地道東北人。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓刹淌,卻偏偏與公主長得像饶氏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子有勾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容