验证Android应用链接

Android应用链接是一种特殊类型的深层链接,可让您的网站网址立即在Android应用中打开相应的内容(无需用户选择应用)。

要将Android应用程序链接添加到您的应用程序,请定义使用HTTP URL打开应用程序内容的意图过滤器(如创建应用程序内容的深层链接中所述),并验证您是否拥有应用程序和网站URL(如本指南中所述))。 如果系统成功验证您拥有URL,系统会自动将这些URL意图路由到您的应用程序。

要验证您的应用和网站的所有权,需要执行以下步骤:

  • 请求清单中的自动应用链接验证。 这向Android系统发出信号,表明它应该验证您的应用是否属于您的意图过滤器中使用的URL域。

  • 通过在以下位置托管数字资产链接JSON文件来声明您的网站与您的意图过滤器之间的关系:
    https://domain.name/.well-known/assetlinks.json

您可以在以下资源中找到相关信息:

  • 在Android Studio中支持URL和应用程序索引

  • 创建语句列表

一、深层链接和应用链接之间的区别

深层链接是一种意图过滤器,允许用户直接在Android应用中输入特定活动。 单击其中一个链接可能会打开一个消歧对话框,允许用户选择可以处理给定URL的多个应用程序(包括您的应用程序)中的一个。 例如,图1显示用户点击地图链接后的消歧对话框,询问是否在地图或Chrome中打开链接。

图1.消歧对话框

Android App Link是基于您的网站网址的深层链接,该网址已经过验证,属于您的网站。 因此,如果已安装,则单击其中一个会立即打开您的应用程序 - 不显示消歧对话框。 虽然用户稍后可能会改变他们处理这些链接的偏好。

下表描述了更具体的差异。

图片1.png

二、请求应用链接验证

要为您的应用启用链接处理验证,请在应用清单中的任何一个Web URL intent过滤器中设置android:autoVerify =“true”,其中包括android.intent.action.VIEW intent actionandroid.intent.category.BROWSABLE 意图类别,如以下清单代码段所示:

<activity ...>

    <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>

当您的任何一个意图过滤器上都存在android:autoVerify =“true”时,在Android 6.0及更高版本的设备上安装您的应用会导致系统尝试验证与您应用的任何意图过滤器中的网址相关联的所有主机。 验证涉及以下内容:

1、系统检查所有意图过滤器,包括:

  • 动作:android.intent.action.VIEW

  • 分类:android.intent.category.BROWSABLEandroid.intent.category.DEFAULT

  • 数据方案:httphttps

2、对于上述意图过滤器中找到的每个唯一主机名,Android会在https://hostname/.well-known/assetlinks.json上查询相应的数字资产链接文件网站。

仅当系统为清单中的所有主机找到匹配的数字资产链接文件时,它才会将您的应用程序建立为指定URL模式的默认处理程序。

支持多个主机的应用程序链接

系统必须能够针对托管在所有相应Web域上的数字资产链接文件验证应用程序的URL intent过滤器数据元素中指定的每个主机。 如果任何验证失败,则应用程序不会被验证为应用程序的intent过滤器中定义的任何URL模式的默认处理程序。 然后,系统默认使用其标准行为来解析意图,如创建应用程序内容的深层链接中所述。

例如,如果在https://www.example.com/.well-known/assetlinks.jsonhttps://www.example都找不到assetlinks.json文件,则具有以下意图过滤器的应用将无法验证达网络。

<application>

  <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=”SecondActivity”>
    <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:scheme="https" android:host="www.example.net" />
    </intent-filter>
  </activity>

</application>

请记住,同一意图过滤器中的所有<data>元素将合并在一起,以考虑其组合属性的所有变体。 例如,上面的第一个intent过滤器包含一个只声明HTTPS方案的<data>元素。 但它与其他<data>元素结合使用,因此intent过滤器同时支持http://www.example.comhttps://www.example.com。 因此,如果要定义URI方案和域的特定组合,则必须创建单独的intent过滤器。

支持多个子域的应用程序链接

数字资产链接协议将意图过滤器中的子域视为唯一的独立主机。 因此,如果您的intent过滤器列出了具有不同子域的多个主机,则必须在每个域上发布有效的assetlinks.json。 例如,以下intent过滤器包括www.example.commobile.example.com作为已接受的intent URL主机。 因此,必须在https://www.example.com/.well-known/assetlinks.jsonhttps://mobile.example.com/.well-known/assetlinks.json上发布有效的assetlinks.json

<application>
  <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>
</application>

或者,如果使用通配符(例如* .example.com)声明主机名,则必须在根主机名(example.com)上发布assetlinks.json文件。 例如,具有以下intent过滤器的应用程序将通过example.com的任何子名称验证(例如foo.example.com),只要assetlink.json文件发布在https://example.com/ .well- known / assetlinks.json

<application>
  <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>
</application>

三、声明网站关联

必须在您的网站上发布数字资产链接JSON文件,以指示与该网站关联的Android应用程序并验证该应用程序的URL意图。 JSON文件使用以下字段来标识关联的应用程序:

  • package_name:在应用程序的build.gradle文件中声明的应用程序ID。

  • sha256_cert_fingerprints:应用程序签名证书的SHA256指纹。 您可以使用以下命令通过Java keytool生成指纹:

$ keytool -list -v -keystore my-release-key.keystore

此字段支持多个指纹,可用于支持应用程序的不同版本,例如调试和生产版本。

以下示例assetlinks.json文件向com.example Android应用授予链接开放权限:

[{
  "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"]
  }
}]

将网站与多个应用相关联

网站可以在同一assetlinks.json文件中声明与多个应用的关联。 以下文件列表显示了一个声明文件的示例,该文件分别声明与两个应用程序的关联,并位于https://www.example.com/.well-known/assetlinks.json

[{
  "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"]
  }
}]

不同的应用程序可以处理同一Web主机下的不同资源的链接。 例如,app1可能会为https://example.com/articles声明一个意图过滤器,而app2可能会为https://example.com/videos声明一个意图过滤器。

注意:与域关联的多个应用程序可能使用相同或不同的证书进行签名。

将多个网站与单个应用相关联

多个网站可以在各自的assetlinks.json文件中声明与同一应用程序的关联。 以下文件列表显示了如何使用app1声明example.comexample.net的关联的示例。 第一个列表显示了example.comapp1的关联:
https://www.example.com/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "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"]
  }
}]

下一个清单显示了example.netapp1的关联。 只托管这些文件的位置不同(.com.net):
https://www.example.net/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "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"]
  }
}]

发布JSON验证文件

您必须在以下位置发布JSON验证文件: https://domain.name/.well-known/assetlinks.json

确保以下内容:

  • assetlinks.json文件与content-type application / json一起提供。

  • 无论您的应用程序的意图过滤器是否将HTTPS声明为数据方案,都必须可以通过HTTPS连接访问assetlinks.json文件。

  • 必须可以访问assetlinks.json文件,不需要任何重定向(没有301或302重定向),并且可以通过机器人访问(您的robots.txt必须允许抓取/.well-known/assetlinks.json)。

  • 如果您的应用程序链接支持多个主机域,则必须在每个域上发布assetlinks.json文件。 请参阅支持多个主机的应用链接。

  • 不要在清单文件中使用dev / test URL发布可能无法访问的应用程序(例如任何只能通过VPN访问的应用程序)。 在这种情况下,解决方法是配置构建变体以为开发构建生成不同的清单文件。

四、测试应用链接

在实现应用链接功能时,您应该测试链接功能,以确保系统可以将您的应用与您的网站相关联,并按照您的预期处理URL请求。

要测试现有语句文件,可以使用语句列表生成器和测试器工具。

确认要验证的主机列表

测试时,您应确认系统应为您的应用验证的关联主机列表。 列出其对应的intent过滤器包含以下属性和元素的所有URL

  • android:scheme属性,其值为http或https

  • android:具有域URL模式的host属性

  • android.intent.action.VIEW类别元素

  • android.intent.category.BROWSABLE类别元素

使用此列表检查每个命名主机和子域上是否提供了数字资产链接JSON文件。

确认数字资产链接文件

或者每个网站,使用Digital Asset Links API确认数字资产链接JSON文件已正确托管和定义:

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

测试URL意图

确认要与您的应用关联的网站列表,并确认托管的JSON文件有效后,请在您的设备上安装该应用。 等待至少20秒以完成异步验证过程。 使用以下命令检查系统是否验证了您的应用程序并设置了正确的链接处理策略:

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

检查链接策略

作为测试过程的一部分,您可以检查当前系统设置以进行链接处理。 使用以下命令获取所连接设备上所有应用程序的现有链接处理策略列表:

adb shell dumpsys package domain-preferred-apps

或者以下内容做同样的事情:

adb shell dumpsys package d

注意:确保在安装应用程序后至少等待20秒,以便系统完成验证过程。

该命令返回设备上定义的每个用户或配置文件的列表,前面带有以下格式的标头:

 Applinkages foruser 0:

在此标头之后,输出使用以下格式列出该用户的链接处理设置:

Package: com.android.vending
Domains: play.google.com market.android.com
Status: always : 200000002

此列表指出哪些应用与该用户的哪些域相关联:

  • - 根据其清单中声明的包名标识应用程序。

  • - 显示此应用处理的Web链接的主机的完整列表,使用空格作为分隔符。

  • 状态 - 显示此应用的当前链接处理设置。 已通过验证且其清单包含android:autoVerify =“true”的应用程序显示状态为always。 此状态后的十六进制数与Android系统的用户应用程序链接首选项记录相关。 该值不表示验证是否成功。

注意:如果用户在验证完成之前更改了应用的应用链接设置,即使验证失败,您也可能会看到成功验证的误报。 但是,如果用户明确启用应用程序以打开支持的链接而不询问,则此验证失败无关紧要。 这是因为用户首选项优先于编程验证(或缺少编程验证)。 因此,该链接直接转到您的应用,而不显示对话框,就像验证成功一样。

测试示例

要使应用链接验证成功,系统必须能够使用您在应用的意图过滤器中指定的所有网站验证您的应用,并且该网站符合应用链接的条件。 以下示例显示了定义了多个应用程序链接的清单配置:

<application>

    <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>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https" android:host="www.example2.com" />
        </intent-filter>
    </activity>

    <activity android:name=”SecondActivity”>
        <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:scheme="https" android:host="account.example.com" />
        </intent-filter>
    </activity>

      <activity android:name=”ThirdActivity”>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="https" android:host="map.example.com" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="market" android:host="example.com" />
        </intent-filter>
      </activity>

</application>

平台将尝试从上述清单验证的主机列表是:

www.example.com  
mobile.example.com  
www.example2.com  
account.example.com

平台不会尝试从上面的清单验证的主机列表是:

map.example.com (it does not have android.intent.category.BROWSABLE)
market://example.com (it does not have either an “http” or “https” scheme)

要了解有关语句列表的更多信息,请参阅创建语句列表

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,825评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 1 周五晚上7点半,小雪难得一见地早早下了班,她站在毕马威大楼下有点犹豫。 现在有两个 选择,一个是去三里屯跟朋友...
    职问师姐阅读 327评论 0 0
  • 图/欢欢儿 文/欢欢儿 图片主题: 春运途中的暖心故事 图片解说: 2月10日 兰州 115路公交车 五点...
    欢欢儿9阅读 237评论 0 1