Android Deep Link


Android Deep Link

官网参考文档

使用场景

用户在网页点击了一个链接以后,直接引导用户在本地应用中查看对应的内容。

原理

当我们点击或者自动化的网络请求会生成一个web URI intent,Android系统按照一定顺序去处理这个请求。
处理顺序为:1.打开所有可以处理本URL应用中用户默认选择的;2.打开唯一能处理这个URL的应用;3.将所有可以处理这个URL的应用展示在Dialog中让用户选择

基本步骤

  1. 在manifest文件中定义IntentFilter
  2. 建立对应处理的Activity
  3. (对于Android App Link而言)将本地内容与URL地址通过服务器上的Digital Asset Links文件关联起来

辅助工具

Android Studio的App Link Assistant使用说明:官方使用指南

分类

Deep Link,Android App Link

配置

  1. 在Manifest中增加intent filter
    • : ACTION_VIEW
    • : 包含BROWSABLE,DEFAULT.BROWSABLE(必须包含,才可以处理来至l浏览器的Intent Filter)
    • : 指定可以响应的URI信息,至少包含scheme标签,可以使用path,pathPattern或者pathPrefix去处理相似的URI
    // 可以响应example://gizmos 和 http://www.example.com/gizmos的Activity
    <activity  android:name="com.example.android.GizmosActivity" android:label="@string/title_gizmos" >
        <intent-filter android:label="@string/filter_view_http_gizmos">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            
            <data android:scheme="http" android:host="www.example.com" android:pathPrefix="/gizmos" />
            
        intent-filter>
        <intent-filter android:label="@string/filter_view_example_gizmos">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            
            <data android:scheme="example" android:host="gizmos" />
        intent-filter>
    activity>

注意点
同一个Intent Filter中的会进行合并组合


  ...
  "https" android:host="www.example.com" />
  "app" android:host="open.my.app" />

// 会生成app://www.example.com 和 https://open.my.app

从Intent获取数据

一旦系统通过Intent Filter打开你的界面,可以从Intent中获取数据

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Intent intent = getIntent();
    String action = intent.getAction();
    Uri data = intent.getData();
}

mainfest文件里定义了定义了应用与网页的关系和如何处理这些链接

测试配置

$ adb shell am start
        -W -a android.intent.action.VIEW         -d <URI> <PACKAGE>
  • 原因:将自己的应用作为URI的默认处理应用,从而减少弹出选择处理对应应用的对话框
  • 本质:一种特殊的Deep Link
  • 查看本机已经支持Android App Link的应用
adb shell dumpsys package domain-preferred-apps
或
adb shell dumpsys package d
  • 安装应用后系统至少需要20s去自动认证

第一步:在mainfest中定义可以处理的URI
第二步:认证URL与app,让系统认证你拥有这个url,系统自动的将URL定位至你的应用

认证步骤

App端开启认证能力

在任一IntentFilter中添加android:autoVerify=”true”,6.0及以上系统自动认证所有符合如下条件IntentFilter中的URL,步骤如下
1. 查找所有有

Action: android.intent.action.VIEW
Categories: android.intent.category.BROWSABLE
Data scheme: http or https,host为URL域名

标签的IntentFilter
2. 对在1过程中找到的所有URL,Android会向对应的网址https://hostname/.well-known/assetlinks.json中的Digital Asset Links file认证。
3. 只有当找到所有在AndroidMainfest中的网址时都被认证时,才能作为对应URL唯一响应App

服务端发布认证文件

  • 发布的地址:https://domain.name/.well-known/assetlinks.json
  • 需要标明文件类型:content-type application/json
  • 需要https获取
  • 可以直接获取,不能有任何的重定位(比如301或者302)而且可以被robots抓取
  • 如果你的应用支持多个网址,在每个对应网址下都要放置对应文件
  • 网址要公众网,避免不能被正确获取
[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": { "namespace": "android_app", "package_name": "com.example", "sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"] } }]

package_name:build.gradle file文件中的application id
sha256_cert_fingerprints:keystore的密匙,可以使用keytool -list -v -keystore my-release-key.keystore获取

Android App Link组合情况说明

  • 一个Actvity对应多个URL
<activity android:name=”MainActivity”>
    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="http" android:host="www.example.com" />
      <data android:scheme="https" />
    intent-filter>
activity>
  • 复杂的子域名
<activity android:name=”MainActivity”>
    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="https" android:host="www.example.com" />
      <data android:scheme="https" android:host="mobile.example.com" />
    intent-filter>
activity>
// 特例对于*.example.com的服务器端文件需要放置在example.com中
<activity android:name=”MainActivity”>
    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="https" android:host="*.example.com" />
    intent-filter>
activity>
  • 一个RUL对应多个App
    在服务器文件配置
[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": { "namespace": "android_app", "package_name": "com.example.puppies.app", "sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"] } },
  {
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": { "namespace": "android_app", "package_name": "com.example.monkeys.app", "sha256_cert_fingerprints": ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"] } }]
  • 一个App对应多个域名
    在各个域名添加.well-known/assetlinks.json文件

测试Android App Link是否配置成功

检测应用端是否配置正确

adb shell am start -a android.intent.action.VIEW 
    -c android.intent.category.BROWSABLE 
    -d "http://domain.name:optional_port"

检测服务器文件是否配置成功

https://digitalassetlinks.googleapis.com/v1/statements:list?
   source.web.site=https://domain.name:optional_port&
   relation=delegate_permission/common.handle_all_urls

DeepLink与Android App Link区别

  • deeplink 是一个intent filter让用户直接进入应用中的某个页面。在有多个可以处理的应用时会弹出一个对话框让你选择对应的处理应用
  • Android App Link是一个经过认证的基于你的url的特殊deeplink,可以立即调起你的应用,而不必弹出对话框选择

建议

  • 跳转界面的设置:android:noHistory=”true”

注意点

  • 标签的匹配模式需要注意

微信等问题记录

  • qq浏览器,uc浏览器拦截http与https协议的web URI intent,chrome正常
  • 微信内置浏览器拦截web URI intent,可以借助应用宝的微下载实现基本跳转,微下载扩展功能的使用条件
    扩展条件