原文:Android M App Links: implementation, drawbacks and solutions
在上次的I/O大會上,谷歌宣布了Android M 支持app鏈接(App Links)颈抚,谷歌正在不遺余力的推動深度鏈接(deep linking)眷昆。這將對Android M的用戶體驗造成深遠的積極影響,用戶點擊一個web鏈接就能直接跳轉到app旧乞。
在Android M之前,點擊一個鏈接會產(chǎn)生一個彈出框,詢問用戶打開哪個應用 - 包括瀏覽器應用份帐。但是谷歌在Android M 實現(xiàn)了一個自動認證(auto-verify)機制,讓開發(fā)者可以避開這個彈出框楣导,使用戶不必去選擇一個列表废境,直接跳轉到他們的app。
在app的manifest中添加 auto-verify(左邊)并且在web服務器上添加一個statements JSON 文件(右邊)就可以讓你的web鏈接打開一個app筒繁。
譯者注:statements JSON 文件即一個叫statements.json的文件噩凹,后面會提到。
要找到谷歌的App Links文檔與理解它需要花點時間(你只能搜索“Android M App Links”關鍵詞才能找到)毡咏。這個文檔目前只是簡要的描述了這個話題驮宴,但是我們將幫助你詳細了解實現(xiàn)的細節(jié),它的缺陷以及如何使用我們的smart links解決這些問題呕缭。HOKO的每個客戶端目前都已經(jīng)支持谷歌的App Link堵泽,輕松加愉快。
什么是App Links恢总?
谷歌的App Link讓用戶在點擊一個普通web鏈接的時候可以打開指定app的指定頁面迎罗,前提是這個app已經(jīng)安裝并且經(jīng)過了驗證,否則會顯示一個打開選項的彈出框片仿。自此纹安,在安卓中打開一個鏈接的用戶體驗大大提高,用戶可以在鏈接與app之間快速切換。
比如厢岂,點擊谷歌關于食譜的移動搜索結果或者一個別人發(fā)來的食譜鏈接會直接導航你到與該鏈接域名相關的app的食譜頁面光督。
而點擊一條推特的web鏈接會直接帶你到Twitter應用的相關推文頁面。
注:用頁面形容app的屏貌似也不太準確哈~
web鏈接可以在任意地方發(fā)送塔粒,發(fā)布可帽,或者打開,因為他們就是普通的鏈接窗怒,而且如果出現(xiàn)了什么錯誤映跟,則會像平常一樣用瀏覽器打開這個web頁面。
實現(xiàn)App Links其實非常簡單扬虚,但是首先你需要保證滿足一些列需求:
有一個注冊了的域名
域名的SSL通道
具有上傳JSON文件到域名的能力
Android Studio 1.3 Preview (download)
Gradle 版本 — com.android.tools.build:gradle:1.3.0-beta3
設置 compileSdkVersion 為 android-MNC
buildToolsVersion — 23.0.0 rc2
如果以上要求全都滿足努隙,只需按照以下三步就可以讓App Links 工作在你的app上。
- 在app中激活App links
讓我們通過告訴安卓系統(tǒng)去驗證app與域名之間的關系來激活App Links 吧辜昵。從此不再又任何的彈出框荸镊,因為我們已經(jīng)在app中注冊了該域名。找到AndroidManifest.xml文件堪置,在處理深度鏈接路由的activity(第三步將講解如何創(chuàng)建這樣的Activity)中添加android:autoVerify="true"到intent-filter:
<activity
android:name="com.your.app.activity.ParseDeepLinkActivity"
...>
<intent-filter android:autoVerify="true">
<data android:scheme="http" android:host="yourdomain.com" />
<data android:scheme="https" android:host="yourdomain.com" />
...
</intent-filter>
</activity>
這個配置告訴安卓去驗證一個文件躬存,這個文件地址是https://yourdomain.com/.well-known/statements.json。如果存在這個文件舀锨,同時驗證成功岭洲,那么用戶點擊該域名之下的鏈接時,就可以直接到app坎匿,彈出框就可以避免盾剩。否則app就沒有成為默認選項,彈出框就會呈現(xiàn)給用戶替蔬。下一步告私,我們將學會如何構建這個文件。
- 上傳web-app關聯(lián)文件(statements.json)
基于安全的原因承桥,這個文件必須通過SSL的GET請求獲得驻粟。你可以代開一個文本編輯器,然后寫入如下形式的JSON:
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.mycompany.myapp",
"sha256_cert_fingerprints": ["6C:EC:C5:0E:34:AE....EB:0C:9B"]
}
}]
可以在AndroidManifest.xml 文件中找到app的package name凶异。你還需要通過在終端中執(zhí)行ava keytool 產(chǎn)生一個sha256指紋:
keytool -list -v -keystore /path/to/app/release-key.keystore
你需要向keystore添加持有app release keys的 app路徑蜀撑。這個路徑依賴于項目設置,因此不同的app是不同的唠帝⊥鸵矗可以在谷歌的文檔中找到更多關于如何找到keystore的信息玄柏。
最后襟衰,上傳這個文件到服務器的/.well-known/statements.json。為了避免今后每個app鏈接請求都訪問網(wǎng)絡粪摘,安卓只會在app安裝的時候檢查這個文件瀑晒。如果你能在請求https://yourdomain.com/.well-known/statements.json 的時候看到這個文件(替換成自己的域名哈)绍坝,那么可以繼續(xù)下一步了。
注:目前可以通過http獲得這個文件苔悦,但是在M最終版里則只能通過HTTPS驗證轩褐。確保你的web站點支持HTTPS請求。
- 在app中處理深度鏈接
到現(xiàn)在玖详,如果你已經(jīng)有了一個處理深度鏈接的activity把介,那么我們已經(jīng)準備好處理app links了。
如果沒有蟋座,你需要創(chuàng)建一個能處理深度鏈接的activity拗踢。這個activity的目的是為了實現(xiàn)一種這樣的機制:負責捕獲與解析深度鏈接,同時轉發(fā)用戶到正確的視圖向臀。
<activity
android:name="com.your.app.activity.ParseDeepLinkActivity"
android:alwaysRetainTaskState="true"
android:launchMode="singleTask"
android:noHistory="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter android:autoVerify="true">
<data android:scheme="http" android:host="yourdomain.com" />
<data android:scheme="https" android:host="yourdomain.com" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
public class ParseDeepLinkActivity extends Activity {
public static final String PRODUCTS_DEEP_LINK = "/products";
public static final String XMAS_DEEP_LINK = "/campaigns/xmas";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Extrapolates the deeplink data
Intent intent = getIntent();
Uri deeplink = intent.getData();
// Parse the deeplink and take the adequate action
if (deeplink != null) {
parseDeepLink(deeplink);
}
}
private void parseDeepLink(Uri deeplink) {
// The path of the deep link, e.g. '/products/123?coupon=save90'
String path = deeplink.getPath();
if (path.startsWith(PRODUCTS_DEEP_LINK)) {
// Handles a product deep link
Intent intent = new Intent(this, ProductActivity.class);
intent.putExtra("id", deeplink.getLastPathSegment()); // 123
intent.putExtra("coupon", deeplink.getQueryParameter("coupon")); // save90
startActivity(intent);
} else if (XMAS_DEEP_LINK.equals(path)) {
// Handles a special xmas deep link
startActivity(new Intent(this, XmasCampaign.class));
} else {
// Fall back to the main activity
startActivity(new Intent(context, MainActivity.class));
}
}
}
ParseDeepLinkActivity.java hosted with ? by GitHub
讓我們先從在AndroidManifest.xml 文件中添加名為ParseDeepLinkActivity的activity開始巢墅。安卓系統(tǒng)會在每次存在一個https://yourdomain.com開頭的深度鏈接時調(diào)用這個activity。
注意yourdomain.com 與 www.yourdomain.com 被看成兩個不同的域名券膀,因此你需要為每個域名添加一對http/https:
<data android:scheme="http" android:host="yourdomain.com" />
<data android:scheme="https" android:host="yourdomain.com" />
<data android:scheme="http" android:host="www.yourdomain.com" />
<data android:scheme="https" android:host="www.yourdomain.com" />
當這個activity創(chuàng)建的時候君纫,我們調(diào)用getIntent()獲得它的intent并調(diào)用getData()獲得這次調(diào)用的URI。然后芹彬,我們把這個URI傳遞到一個匹配路徑與行為的方法中蓄髓。
在此例子中,我們有一個/products 的路徑以及一個 /campaigns/xmas/路徑舒帮。
對于前者双吆,我們需要接續(xù)URI并檢查URI引用的是哪個產(chǎn)品,最后讓用戶轉向負責顯示產(chǎn)品新的的視圖会前。我們使用deeplink.getLastPathSegment()來獲取產(chǎn)品的id(路徑的最后一個參數(shù))好乐,使用getQueryParameter("coupon") 來檢查是否有coupon參數(shù)。最后一步則是觸發(fā)顯示產(chǎn)品的activity瓦宜。
而對于后面一個蔚万,則只是簡單的調(diào)用處理 xmas campaign邏輯的activity。你可以嘗試執(zhí)行下面的命令測試這個activity:
-W -a android.intent.action.VIEW
-d "https://yourdomain.com/products/123?coupon=save90" com.example.android
這應該會打開模擬器活著設備上的app临庇,并調(diào)用ParseDeepLinkActivity來接續(xù)鏈接反璃。確保現(xiàn)在你的網(wǎng)站上存在web-app 關聯(lián)文件 假夺。
App Links的缺陷
App Links是開發(fā)者的一大福音淮蜈,但是也有幾個讓你猶豫不決的缺陷:
App Links只能工作在谷歌的Android M上
在配置好了app對App Links的支持之后,只有運行Android M的用戶才能體驗到這項技術的好處已卷。之前安卓版本的用戶無法直接點擊鏈接進入app梧田,而是回到瀏覽器的web頁面。
但是HOKO為Android 1.6之后的設備提供了移動深度鏈接。自此你的深度鏈接將可以在幾乎所有的安卓設備上工作裁眯,即使它們并沒有運行Android M鹉梨。
要使用App Links開發(fā)者必須維護一個與app相關聯(lián)的網(wǎng)站
這對于那些小型開發(fā)者而言是個壞消息,因為他們沒有能力為app維護一個網(wǎng)站穿稳,但是它們?nèi)匀幌Mㄟ^web鏈接獲得流量存皂。
HOKO 就是解決這個問題的辦法,因為它扮演著開發(fā)者網(wǎng)站的角色逢艘,每個app維護在不同的子域名下旦袋。這樣,開發(fā)者只需創(chuàng)建smart link并發(fā)布他們的URL它改,每個URL將無縫的打開相應的app猜憎。
app與網(wǎng)站的關聯(lián)是通過開發(fā)者網(wǎng)站下的一個配置文件實現(xiàn)的
有了HOKO,你可以跳過這煩人的一步搔课,因為我們已經(jīng)實現(xiàn)胰柑。而且,我們的服務器在安全和性能方面都是業(yè)內(nèi)頂尖的配置爬泥,可以為這個配置提供更快速的服務柬讨。
要讓你的app支持深度鏈接,學些更多關于HOKO的知識袍啡。
另外踩官,還可以查看我們的Apple's Universal Links 詳細指南!