天天看點

[簡單實用系列] 微信第三方登入

目前微信/微網誌作為第三方登入也比較流行,也有整合第三方登入的方式比如sharesdk,友盟之類的。但是項目中獨立整合第三方登入對熟悉相關的SDK也是有意義的。

微信登入/分享的文檔路徑為https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319167&token=ba3e4911036eb232f54ab39efc023930d7cfc60e&lang=zh_CN

APP添加微信登入需要如下步驟:

1.申請APP ID

2.下載下傳上面路徑中的android開發包,并将wxapi檔案夾加入工程中

3.在manifest中添加如下代碼

<activity
    android:name=".wxapi.WXEntryActivity"
    android:exported="true"
    android:label="@string/app_name"
    android:launchMode="singleTop"
    android:screenOrientation="portrait">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="AppID"/>
    </intent-filter>
</activity>
           

4.在需要添加微信登入的頁面中添加如下代碼

private IWXAPI api;
onCreate() -> initWX(); ->
private void initWX() {
  api = WXAPIFactory.createWXAPI(LoginActivity.this, null);
  api.registerApp(WXAppContants.APP_ID);
}
           

5.點選微信登入按鈕

icon_wechat.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "*****";//可以為package name
        api.sendReq(req);
    }
});
           

6.通過上面代碼就可以彈出微信第三方授權頁面了,點選确認即可。然後進入WXEntryActivity頁面onResp函數

@Override
public void onResp(BaseResp baseResp) {
    int result = 0;
    switch (baseResp.errCode) {
        case BaseResp.ErrCode.ERR_OK:
            result = R.string.errcode_success;
            try {
                SendAuth.Resp sendResp = (SendAuth.Resp) baseResp;
                // 參考文檔 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317853&token=&lang=zh_CN 内容
                <span style="background-color: rgb(51, 51, 255);">**通過 https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code 擷取内容</span>
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            break;
        case BaseResp.ErrCode.ERR_USER_CANCEL:
            result = R.string.errcode_cancel;
            finish();
            break;
        case BaseResp.ErrCode.ERR_AUTH_DENIED:
            result = R.string.errcode_deny;
            finish();
            break;
        default:
            result = R.string.errcode_unknown;
            finish();
            break;
    }


    Toast.makeText(this, result, Toast.LENGTH_LONG).show();
}
           

7.在上面**中傳回如下内容:

"access_token":"ACCESS_TOKEN", 

"expires_in":7200, 

"refresh_token":"REFRESH_TOKEN", 

"openid":"OPENID", 

"scope":"SCOPE" 

}

8.有了上面内容後即可擷取個人資訊,參考https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

private void doGetUserInfo(JSONObject response) {
    HashMap<String, Object> paramMap = new HashMap<String, Object>();
    paramMap.put("openid", response.optString("openid"));
    paramMap.put("access_token", response.optString("access_token"));
    paramMap.put("lang", "zh_CN");
    String url = "https://api.weixin.qq.com/sns/userinfo?access_token=%1$s&openid=%2$s&;
    new WXUserInfoTask().execute(String.format(url,
            response.optString("access_token"),
            response.optString("openid")));
}
           
class WXUserInfoTask extends AsyncTask<String, Void, String> {


    protected String doInBackground(String... urls) {
        try {
            URL url = new URL(urls[0]);
            HttpURLConnection conn = (HttpURLConnection) url
                    .openConnection();
            conn.setConnectTimeout(5000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            if (conn.getResponseCode() == 200) {
                InputStream is = conn.getInputStream();
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len = 0;
                StringBuffer strBuffer = new StringBuffer();
                while ((len = is.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, len);
                }


                return new String(outputStream.toByteArray());
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    protected void onPostExecute(String strInfo) {
        if (strInfo == null) {
            CommonUtil.showToast(WXEntryActivity.this,
                    R.string.str_error_wxinfo);
            finish();
        } else {
            // 這裡即可對使用者資訊做相關處理
        }
    }
}
           

其中上面的**也可參考上面的方式處理

注意點:

1.如果無法顯示授權頁面的話,應該是注冊資訊不對導緻。故可以确認相關資訊。

包括需要輸入正确的編譯參數SHA值,區分是debug版本還是release版本