Android 從 Web 喚起 APP

吳小龍同學發表於2018-04-08

前言

Android 從 Web 喚起 APP
知乎在手機瀏覽器開啟,會有個 App 內開啟的按鈕,點選直接開啟且跳轉到該詳情頁,是不是有點神奇,是如何做到的呢?

效果預覽

Android 從 Web 喚起 APP

Uri Scheme

配置 intent-filter

AndroidManifest.xml

<activity android:name=".MainActivity">
    <!-- 需要新增下面的intent-filter配置 -->
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:host="myhost"
            android:path="/main"
            android:port="1024"
            android:scheme="myscheme" />
    </intent-filter>
</activity>
複製程式碼

測試網頁

main 下新建 assets 檔案,寫了簡單的 Html 網頁用於 WebView 展示,來進行測試。

index.html:

<html>
<head>
    <meta charset="UTF-8">
</head>
<body>
<h1>這是一個 WebView</h1>

<a href="market://details?id=com.tencent.mm">open app with market</a>
<br/>
<br/>

<a href="myscheme://myhost:1024/main?key1=value1&key2=value2">open app with Uri Scheme</a>

<br/>
<br/>


</body>
</html>
複製程式碼

Web View 載入:

webView.loadUrl("file:///android_asset/index.html");
複製程式碼

目標頁面

接受引數,做相應的處理。

Intent intent = getIntent();
if (null != intent && null != intent.getData()) {
    // uri 就相當於 web 頁面中的連結
    Uri uri = intent.getData();
    Log.e(TAG, "uri=" +uri);
    String scheme = uri.getScheme();
    String host = uri.getHost();
    int port = uri.getPort();
    String path = uri.getPath();
    String key1 = uri.getQueryParameter("key1");
    String key2 = uri.getQueryParameter("key2");
    Log.e(TAG, "scheme=" + scheme + ",host=" + host
            + ",port=" + port + ",path=" + path
            + ",query=" + uri.getQuery()
            + ",key1=" + key1 + ",key2=" + key2);
}
複製程式碼

列印訊息如下:

uri=myscheme://myhost:1024/main?key1=value1&key2=value2
scheme=myscheme,host=myhost,port=1024,path=/main,query=key1=value1&key2=value2,key1=value1,key2=value2
複製程式碼

原理

myscheme://myhost:1024/main?key1=value1&key2=value2,通過一個連結,為什麼能啟動相應的 APP 呢?Web 喚起 Android app 的實現及原理,一文說到關鍵程式碼在 Android 6.0 的原生瀏覽器的 shouldOverrideUrlLoading 方法,核心實現在 UrlHandler 這個類中。程式碼如下:

final static String SCHEME_WTAI = "wtai://wp/";
final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
boolean shouldOverrideUrlLoading(Tab tab, WebView view, String url) {
    if (view.isPrivateBrowsingEnabled()) {
        // Don't allow urls to leave the browser app when in
        // private browsing mode
        return false;
    }
    if (url.startsWith(SCHEME_WTAI)) {
        // wtai://wp/mc;number
        // number=string(phone-number)
        if (url.startsWith(SCHEME_WTAI_MC)) {
            Intent intent = new Intent(Intent.ACTION_VIEW,
                    Uri.parse(WebView.SCHEME_TEL +
                            url.substring(SCHEME_WTAI_MC.length())));
            mActivity.startActivity(intent);
            // before leaving BrowserActivity, close the empty child tab.
            // If a new tab is created through JavaScript open to load this
            // url, we would like to close it as we will load this url in a
            // different Activity.
            mController.closeEmptyTab();
            return true;
        }
        //……
    }
複製程式碼

原始碼

公眾號「吳小龍同學」回覆「SchemeSample」,獲取這次練習的完整示例。

Deep Links

Android 從 Web 喚起 APP

如圖,在 Android M 之前,如果點選一個連結有多個 APP 符合,會彈出一個對話方塊,詢問使用者使用哪個應用開啟 - 包括瀏覽器應用。谷歌在Android M 上實現了一個自動認證(auto-verify)機制,讓開發者可以避開這個彈出框,使使用者不必去選擇一個列表,直接跳轉到他們的 APP。

建立

Android M的App Links實現詳解

Android M App Links: 實現, 缺陷以及解決辦法

我沒有驗證,因為我玩不起來,有條件更新下 Deep Links 這塊內容,可以自己搭個本地伺服器。

弊端

需要 Android M

需要 Android 6.0(minSdkVersion 級別23)及更高版本上的才能使用。

.well-known/assetlinks.json

開發者必須維護一個與app相關聯的網站,通過在以下位置託管數字資產連結 JSON 檔案來宣告您的網站與您的意圖過濾器之間的關係:

https://domain.name/.well-known/assetlinks.json
複製程式碼

參考

Android 使用Scheme實現從網頁啟動APP

Deep Link是什麼

Android移動開發者必須知道的Deep Linking技術

Handling Android App Links

公眾號

我的公眾號:吳小龍同學,歡迎交流~

Android 從 Web 喚起 APP

相關文章