验证 Android 应用链接

本文详细介绍了Android应用链接和深层链接的区别,以及如何为应用添加和验证Android应用链接。通过设置intent过滤器和DigitalAssetLinksJSON文件,开发者可以确保网址直接在应用中打开,提供无缝用户体验。验证过程涉及系统检查intent过滤器和主机上的DigitalAssetLinks文件,以确保所有权和关联性。

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

如需向应用添加 Android 应用链接,请定义使用 HTTP 网址打开应用内容的 intent 过滤器(如创建指向应用内容的深层链接中所述),并验证您是否为相关应用和网站网址的所有者(如本指南中所述)。如果系统成功验证您是网址所有者,则会自动将这些网址 intent 路由到您的应用。

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

  • 在清单中请求自动验证应用链接。这样即可向 Android 系统说明其应该验证您的应用是否属于 intent 过滤器中使用的网址网域。
  • 通过在以下位置托管 Digital Asset Links JSON 文件,声明您的网站和 intent 过滤器之间的关系:

    https://domain.name/.well-known/assetlinks.json
    .

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

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

深层链接是一种 intent 过滤器,可让用户直接进入 Android 应用中的特定 Activity。点击此类链接可能会打开一个消除歧义对话框,该对话框可以让用户从多个能够处理给定网址的应用(包括您的应用)中选择一个。例如,图 1 显示的是在用户点击地图链接后打开的消除歧义对话框,该对话框会询问用户是在 Google 地图中还是 Chrome 中打开此链接。

图 1. 消除歧义对话框

Android 应用链接是一种深层链接,它们基于已验证属于您网站的网站网址。因此,点击某个此类链接会立即打开您的应用(如已安装),并且不会显示消除歧义对话框。不过,用户以后可以更改处理这些链接的偏好设置。

下表介绍了更多具体区别。

深层链接应用链接
intent 网址架构httphttps 或自定义架构需要 http 或 https
intent 操作任何操作需要 android.intent.action.VIEW
intent 类别任何类别需要 android.intent.category.BROWSABLE 和 android.intent.category.DEFAULT
链接验证需要通过 HTTPS 协议在您的网站上发布 Digital Asset Links 文件
用户体验可能会显示一个消除歧义对话框,以供用户选择用于打开链接的应用无对话框;您的应用会打开以处理您的网站链接
兼容性所有 Android 版本Android 6.0 及更高版本

请求应用链接验证

如需为您的应用启用链接处理验证,请在应用清单中的任一网址 intent 过滤中设置 android:autoVerify="true",其中包含 android.intent.action.VIEW intent 操作和 android.intent.category.BROWSABLE intent 类别,如以下清单代码段所示:

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

当任一 intent 过滤器上存在 android:autoVerify="true" 时,在搭载 Android 6.0 及更高版本的设备上安装应用会使系统尝试验证与应用的所有 intent 过滤器中的网址关联的所有主机。验证涉及以下方面:

  1. 系统会检查所有包含以下各项的 intent 过滤器:
    • 操作:android.intent.action.VIEW
    • 类别:android.intent.category.BROWSABLE 和 android.intent.category.DEFAULT
    • 数据架构:http 或 https
  2. 对于在上述 intent 过滤器中找到的每个唯一主机名,Android 会在 https://hostname/.well-known/assetlinks.json 查询 Digital Asset Links 文件的相应网站。

仅当系统为清单中的所有主机找到匹配的 Digital Asset Links 文件后,才会将您的应用确立为处理指定网址格式的默认处理程序。

支持多个主机的应用链接

系统必须能够对照每个相应网域上托管的 Digital Asset Links 文件验证应用网址 intent 过滤器的数据元素中指定的每个主机。如果任何验证失败,就表示应用未通过验证,不能成为应用 intent 过滤器中定义的任何网址格式的默认处理程序。然后,系统会默认采用标准行为解析相应 intent,具体如创建指向应用内容的深层链接中所述。

例如,如果在 https://www.example.com/.well-known/assetlinks.json 和 https://www.example.net/.well-known/assetlinks.json 中都未找到 assetlinks.json 文件,具有以下 intent 过滤器的应用将无法通过验证:

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

请注意,同一 intent 过滤器中的所有 <data> 元素会合并在一起,以涵盖合并后属性的所有变体。例如,上面的第一个 intent 过滤器包含一个仅声明 HTTPS 架构的 <data> 元素。但是,它与其他 <data> 元素组合在一起,以便 Intent 过滤器同时支持 http://www.example.com 和 https://www.example.com。因此,如需定义 URI 架构和网域的特定组合,您必须创建单独的 intent 过滤器。

支持多个子网域的应用链接

Digital Asset Links 协议将 intent 过滤器中的子网域视为唯一的独立主机。因此,如果您的 intent 过滤器列出多个包含不同子网域的主机,您必须在每个网域上分别发布一个有效的 assetlinks.json。例如,以下 Intent 过滤器包含 www.example.com 和 mobile.example.com 作为接受的 intent 网址主机。因此,必须在 https://www.example.com/.well-known/assetlinks.json 和 https://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 文件。例如,只要将 assetlinks.json 文件发布到 https://example.com/.well- known/assetlinks.json,具有以下 intent 过滤器的应用就会通过针对 example.com 的任何子域名(如 foo.example.com)的验证:

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

声明网站关联性

您必须在网站上发布 Digital Asset Links JSON 文件,以指示与网站相关联的 Android 应用并验证应用的网址 intent。JSON 文件使用下列字段标识关联的应用:

  • package_name:在应用的 build.gradle 文件中声明的应用 ID
  • sha256_cert_fingerprints:应用的签名证书的 SHA256 指纹。您可以利用 Java 密钥工具,通过以下命令生成该指纹:

        $ keytool -list -v -keystore my-release-key.keystore
        
    此字段支持多个指纹,这些指纹可用于支持不同版本的应用,例如调试版 build 和正式版 build。

以下 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.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"]
      }
    }]
    

不同的应用可以处理同一网络主机下的不同资源对应的链接。例如,app1 可能声明了一个对应于 https://example.com/articles 的 intent 过滤器,而 app2 可能声明了一个对应于 https://example.com/videos 的 Intent 过滤器。

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

将多个网站与同一应用相关联

多个网站可在各自的 assetlinks.json 文件中声明与同一应用的关联性。以下文件列表示例展示了如何声明 example.com 和 example.net 与 app1 的关联性。第一个列表展示了 example.com 与 app1 的关联性:

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.net 与 app1 的关联性。唯一的区别是托管这些文件的位置不同(.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

请确保以下几点:

  • 使用内容类型 application/json 发布 assetlinks.json 文件。
  • 无论应用的 intent 过滤器是否将数据架构声明为 HTTPS,都必须可通过 HTTPS 连接访问 assetlinks.json 文件。
  • assetlinks.json 文件必须无需重定向即可访问(无 301 或 302 重定向),且可由漫游器访问(您的 robots.txt 必须允许抓取 /.well-known/assetlinks.json)。
  • 如果您的应用链接支持多个主机网域,您必须在每个网域上分别发布 assetlinks.json 文件。请参阅支持多个主机的应用链接
  • 请勿发布清单文件中的开发/测试网址无法供公众访问的应用(例如,任何只可通过 VPN 访问的应用)。作为这种情况下的应急措施,您可以配置编译变体以针对开发编译版本生成不同的清单文件。

测试应用链接

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

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

确认需要验证的主机列表

测试时,您应该对系统需要针对您的应用验证的已关联主机列表进行确认。创建一个列表,在其中列出所有相关网址,此类网址对应的 intent 过滤器包含以下属性和元素:

  • android:scheme 属性,值为 http 或 https
  • 具有网域网址格式的 android:host 属性
  • android.intent.action.VIEW 操作元素
  • android.intent.category.BROWSABLE 类别元素

使用此列表检查每个指定的主机和子网域上是否提供了 Digital Asset Links JSON 文件。

确认 Digital Asset Links 文件

对于每个网站,使用 Digital Asset Links API 确认是否已正确托管和定义 Digital Asset Links JSON 文件:

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

测试网址 intent

确认要与您的应用关联的网站列表,并且确认托管的 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 秒,以让系统完成验证流程。

以上命令会返回设备上定义的每个用户或个人资料的清单,前面带有以下格式的标头:

    App linkages for user 0:
    

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

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

此列表可以指示对于此用户,哪些应用与哪些网域相关联:

  • Package - 以软件包名称标识应用,与应用清单文件中声明的内容一致。
  • Domains - 显示相关主机的完整列表,该应用处理此类主机的网络链接,使用空格作为分隔符。
  • Status - 显示该应用的现有链接处理设置。已通过验证并且清单文件中包含 android:autoVerify="true" 的应用会显示 always 状态。此状态后的十六进制数字与 Android 系统的用户应用链接偏好设置记录有关。此值并不指示验证是否成功。

注意:如果用户在验证完成前更改应用的应用链接设置,那么即使验证失败,验证也可能会误报为已成功。不过,如果用户显式允许该应用在不进行询问的情况下打开支持的链接,则即使出现这种验证失败的情况也没关系。这是因为用户偏好设置优先于程序化验证(或缺少验证)。因此,链接会直接转到您的应用,而不会显示对话框,就好像验证已成功一样。

测试示例

为了让应用链接验证成功,系统必须能够针对您在应用的 intent 过滤器中指定并且符合应用链接标准的所有网站验证您的应用。以下示例展示了定义多个应用链接的清单配置:

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

如需详细了解语句列表,请参阅创建语句列表

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值