有次面試時宰睡,面試官問了一個如何在WebView點擊超鏈接啟動類型QQ類似第三方應(yīng)用租冠,我當(dāng)時的回答是用WebView與js交互可以做到垄惧。面試官聽了沒再說什么搓谆,應(yīng)該是答案不是他期望的炒辉。今天發(fā)現(xiàn)原來可以這樣實現(xiàn),記錄一下泉手。
在Web開發(fā)中黔寇,啟動QQ來臨時會話,可以通過一個URL鏈接
<a target="_blank" >啟動QQ</a>
把20178888換成你的QQ號即可斩萌。在Android手機(jī)有些瀏覽器里這樣也可以正常被調(diào)用缝裤。
但如果我們要使用Webview展示W(wǎng)eb頁面,頁面里包含了上面的鏈接颊郎,卻無法正常的啟動QQ憋飞。
我們可以在WebView里重載 setWebViewClient
方法
mWebView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
這樣Webview里面的超鏈接要是被觸發(fā)了,Webview會去加載替代默認(rèn)瀏覽器加載姆吭。
http://wpa.qq.com/msgrd?v=3&uin=748895431&site=qq&menu=yes
這個鏈接我們看起來這是一個很正常的http請求榛做,通過抓包發(fā)現(xiàn)調(diào)用的QQ不僅僅是進(jìn)行一次http的請求,實際還發(fā)送了這么一個請求:mqqwpa://im/chat開頭的内狸。
mqqwpa:// 這部分URL的部分检眯,叫做URL的sechme部分。
這里就比較好理解為什么會跳到騰訊應(yīng)用寶官網(wǎng)昆淡,http://wpa.qq.com/
是騰訊應(yīng)用寶的官網(wǎng)锰瘸,這是第一次請求,
由于它接著再次請求的協(xié)議不是http而是mqqwpa://im/chat昂灵。
而實際上真正調(diào)用QQ的是mqqwpa://im/chat避凝,這時我們應(yīng)該使用一個Intent來操作調(diào)用原生的QQ舞萄。
我們需要捕獲這些url,當(dāng)遇到普通網(wǎng)頁交給Webview處理恕曲,走正常流程鹏氧;當(dāng)遇到以mqqwpa開頭的,交給默認(rèn)瀏覽器處理佩谣。
這樣WebView點擊超鏈啟動QQ問題就解決了。
下面我們來看實現(xiàn)方式:
其實我們重載 shouldInterceptRequest 方法实蓬,來截獲其他的sechme處理即可茸俭。
webView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (url.startsWith("http") || url.startsWith("https")) { //http和https協(xié)議開頭的執(zhí)行正常的流程
return super.shouldInterceptRequest(view, url);
} else { //其他的URL則會開啟一個Acitity然后去調(diào)用原生APP
Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(in);
return null;
}
}
});
完整代碼:
mWebView = (ProgressWebView) findViewById(R.id.baseweb_webview);
mWebView.getSettings().setJavaScriptEnabled(true);
String url ="http://wpa.qq.com/msgrd?v=3&uin=748895431&site=qq&menu=yes";
mWebView.loadUrl(url);
mWebView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (url.startsWith("http") || url.startsWith("https")) { //http和https協(xié)議開頭的執(zhí)行正常的流程
return super.shouldInterceptRequest(view, url);
} else { //其他的URL則會開啟一個Acitity然后去調(diào)用原生APP
Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(in);
return null;
}
}
});
[END]