Android webview一鍵登錄手機(jī)QQ(2018.11)

前言

不知道什么時(shí)候開始, QQ oauth登陸, 不再讓你在網(wǎng)頁(yè)輸入賬號(hào)密碼了. 頁(yè)面提示正在拉起QQ手機(jī)版. 然后程序就在這里沒(méi)有然后了.

可能有人會(huì)問(wèn), 為什么不使用QQ sdk做登陸. 這里提2點(diǎn):

  • Android, iOS, Web 3端需要打通, 才能確保一個(gè)QQ用戶唯一.
  • 平臺(tái)sdk, 封裝了QQ登陸, 對(duì)外多個(gè)應(yīng)用提供. 比如常見的游戲sdk.

搜索了下這個(gè)sdk就無(wú)法QQ登陸了, 應(yīng)該是QQ web頁(yè)面不讓輸入賬號(hào)密碼之后出現(xiàn)的.
QQ只有一鍵登錄,無(wú)法輸入賬號(hào)密碼

解決問(wèn)題

首先在webviewshouldOverrideUrlLoading(WebView view, String url)方法里打印下url. 會(huì)發(fā)現(xiàn)輸出

wtloginmqq://ptlogin/qlogin?p=xxxxxxxxxxxxxxxxxxxxxxxxxxxx

這是個(gè)非http開頭的地址, 內(nèi)嵌的webview無(wú)法識(shí)別. 可以聯(lián)想到QQ應(yīng)該是走了定制的uri協(xié)議來(lái)跳轉(zhuǎn)手機(jī)QQ. 我們可以通過(guò)intent來(lái)讓系統(tǒng)幫我們跳轉(zhuǎn)到QQ.

if (url.startsWith("wtloginmqq://ptlogin/qlogin")) {
  Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
  startActivity(intent);
}

加了上述代碼, 就能啟動(dòng)QQ并登陸了. 登陸完了, 還會(huì)提示跳轉(zhuǎn)到瀏覽器. 但是這樣有個(gè)問(wèn)題, 我們應(yīng)用拿不到oauth要用到的code了.

既然QQ會(huì)登陸完畢會(huì)跳轉(zhuǎn)瀏覽器, 那就讓我們應(yīng)用也能接收url跳轉(zhuǎn).

<activity
    android:name=".ui.activity.QQActivity"
    android:label="@string/app_name"
    android:screenOrientation="portrait"
    android:theme="@style/TransparentTheme">
    <intent-filter>
        <category android:name="android.intent.category.DEFAULT"/>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="https" android:host="ssl.ptlogin2.qq.com" android:path="/jump"/>
    </intent-filter>
</activity>

開始測(cè)試時(shí)只加了scheme限定, 得到地址規(guī)則后, 再加的hostpath限定符.

然后QQ登陸完畢后, 就是提示應(yīng)用選擇框


這里在做登陸前, 加個(gè)引導(dǎo)讓用戶點(diǎn)自己應(yīng)用, 否則沒(méi)有后續(xù)了.

選擇我們的應(yīng)用, 在對(duì)應(yīng)的上述我們定義的QQActivity的onCreate或onNewIntent(如果該activity在棧里出現(xiàn)過(guò))里就能響應(yīng)了. 通過(guò)intent取出url, 找了url特征字符沒(méi)有發(fā)現(xiàn)tokencode. 才發(fā)現(xiàn)在系統(tǒng)瀏覽器里最終會(huì)跳轉(zhuǎn)到我們指定的REDIRECT_URI. 我們讓之前那個(gè)內(nèi)嵌webview的執(zhí)行

mWebView.loadUrl(intent.getData().toString());

shouldOverrideUrlLoading里就能攔截到REDIRECT_URI, 以前不能跳轉(zhuǎn)的代碼就又續(xù)上了...

當(dāng)然我們也可以自己發(fā)起http請(qǐng)求, 獲取跳轉(zhuǎn)地址. 代碼如下

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        if (Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() != null) { 
                        String url = intent.getData().toString();
            StringRequest request = new StringRequest();
            request.setMethod("GET");
            request.setUrl(url);
            request.setListener(new Listener<String>() {
                @Override
                public void onResponse(int code, String response, Map<String, String> headers) {
                    if (code == 302 && headers.containsKey("Location")) {
                        String url = headers.get("Location");
                        //url結(jié)果為http://你填的REDIRECT_URI?code=aaaaaaaaaaa&state=bbbb
                    }
                }

                @Override
                public void onError(Response.ResponseError error) {
                    int w = 0;
                }
            });
            AsyncHttp.get().executeAsync(request);
        }
    }

備注: 測(cè)試手機(jī)小米mix2, 未測(cè)過(guò)其它手機(jī)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 7,295評(píng)論 0 17
  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,172評(píng)論 3 119
  • 水上的雙人瑜伽 水上的雙人瑜伽 宇宙夫婦真的是越來(lái)越甜,記得最深刻的就是兩個(gè)人在水上的雙人瑜伽。 自然互動(dòng) 不管是...
    瘦身寶典閱讀 2,027評(píng)論 0 1

友情鏈接更多精彩內(nèi)容