前言
不知道什么時(shí)候開始, QQ oauth登陸, 不再讓你在網(wǎng)頁(yè)輸入賬號(hào)密碼了. 頁(yè)面提示正在拉起QQ手機(jī)版
. 然后程序就在這里沒有然后了.
可能有人會(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)題
首先在webview
的shouldOverrideUrlLoading(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ī)則后, 再加的host
和path
限定符.
然后QQ登陸完畢后, 就是提示應(yīng)用選擇框
選擇我們的應(yīng)用, 在對(duì)應(yīng)的上述我們定義的QQActivity的onCreate或onNewIntent(如果該activity在棧里出現(xiàn)過(guò))里就能響應(yīng)了. 通過(guò)intent
取出url
, 找了url
特征字符沒有發(fā)現(xiàn)token
或code
. 才發(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ī)