アプリリンクをテストする

アプリリンク機能を実装する場合は、リンク機能をテストして、想定どおりにシステムでアプリをウェブサイトに関連付けることができ、URL リクエストを処理できることを確認する必要があります。

既存のステートメント ファイルをテストするには、ステートメント リスト生成テストツールを使用できます。

以降のセクションでは、アプリリンクの検証を手動でテストする方法について説明します。必要に応じて、Google Play のディープリンク ツールまたは Android Studio のアプリリンク アシスタントから検証をテストすることもできます。

検証するホストのリストを確定する

テストを行う際は、アプリに関して検証が必要な関連ホストのリストを確定する必要があります。対象インテント フィルタが以下の属性と要素を含むすべての URL のリストを作成します。

  • http または https の値が指定されている android:scheme 属性
  • ドメイン URL パターンが指定されている android:host 属性
  • android.intent.action.VIEW アクション要素
  • android.intent.category.BROWSABLE カテゴリ要素

このリストを使用して、指定された名前の各ホストおよび各サブドメイン上に Digital Asset Links JSON ファイルが用意されているかチェックします。

Digital Asset Links ファイルを確認する

ウェブサイトごとに、Digital Asset Links API を使用して、デジタル アセットリンク JSON ファイルが正しくホストされ定義されていることを確認します。

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

ダイナミック アプリリンクの場合、関連付け拡張機能も確認できます。

https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://www.example.com&relation=delegate_permission/common.handle_all_urls&return_relation_extensions=true

テストプロセスの一部として、リンク処理の現在のシステム設定をチェックできます。次のコマンドを使用して、コネクテッド デバイス上のすべてのアプリを対象に、既存のリンク処理ポリシーのリストを取得します。

adb shell dumpsys package domain-preferred-apps

次のコマンドでも同じ処理を行うことができます。

adb shell dumpsys package d

このコマンドにより、デバイス上で定義されている各ユーザーまたはプロファイルのリストが返されます。リストの先頭には、次の形式のヘッダーが付きます。

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 が示されます。このステータスの後ろにある 16 進数は、ユーザーのアプリリンク設定に関して Android システムが記録する際に使用するものです。この値は検証が成功したかどうかを示すものではありません。

テストの例

アプリリンクの検証が成功するには、アプリリンクの基準を満たす特定のインテント フィルタで指定されている各ウェブサイトを対象にして、アプリを検証できる必要があります。複数のアプリリンクが定義されているマニフェスト構成の例を以下に示します。

<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" />
            <data android:scheme="https" />
            <data android:host="www.example.com" />
            <data 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" />
            <data 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" />
            <data 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" />
            <data 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" />
            <data 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)

ステートメント リストの詳細については、ステートメント リストを作成するをご覧ください。

Android 17 以降では、Activity Manager(am start)コマンドで --debug-link フラグを使用して、システムが特定の URL を解決する方法を診断できます。このツールは、インテントに一致した候補アプリの詳細な内訳と、解決時に評価されたアプリ マニフェストと assetlinks.json ファイル(Dynamic App Links の場合)の特定のルールを提供します。

特定の URL のリンク解決をテストするには、ターミナル ウィンドウで次のコマンドを実行します。

adb shell am start --debug-link -a android.intent.action.VIEW -d "https://xyz.com/foo"

診断出力は App Link Resolution Debug ヘッダーの下に出力され、解決プロセスを理解するのに役立つ次のセクションが含まれています。

  • ターゲットの詳細: 一致する候補アプリを、パッケージ名とターゲット アクティビティで識別します。
  • インテント フィルタの一致(AndroidManifest.xml): マニフェスト インテント フィルタのどの静的属性(schemehostpathpathPrefixpathPattern など)が URI と一致したかを表示します。
  • アプリリンクの検証: 現在のドメイン検証の状態(STATE_SUCCESS など)を示します。
  • ダイナミック アプリリンク: アプリの assetlinks.json ファイルでダイナミック アプリリンクのマッチングルールを使用している場合、このセクションには、URI に対して評価されたすべてのルールが一覧表示されます。各ルールは、一致した URI フィルタ(パス接頭辞やパターンなど)と allow フィールドを示します。
    • allow = 0: 許可/包含ルール(allow: true)。このルールが一致した場合、アプリは URI を開くことができます。
    • allow = 1: ブロック/除外ルール(allow: false / exclude: true)。このルールに一致すると、アプリは URI を開くことができなくなります。
    • : 空のフィルタ文字列(filter =)は、ドメイン内のすべてのパスに一致する空のパス接頭辞を示します(ワイルドカードまたはキャッチオールとして機能します)。

デバッグ出力の例

ドメイン https://xyz.com に関連付けられたアプリ(com.example.xyzapp)が、assetlinks.json ファイルで動的ルールを定義して /foo* を除外し、他のすべてのパスを許可しているとします。

[
  {
    "relation": [
      "delegate_permission/common.handle_all_urls"
    ],
    "target": {
      "namespace": "android_app",
      "package_name": "com.example.xyzapp",
      "sha256_cert_fingerprints": ["..."]
    },
    "relation_extensions": {
      "delegate_permission/common.handle_all_urls": {
        "dynamic_app_link_components": [
          {"/": "/foo*", "exclude": true},
          {"/": "*"}
        ]
      }
    }
  }
]

--debug-link を使用して URL https://xyz.com/foo を診断する場合:

adb shell am start --debug-link -a android.intent.action.VIEW -d "https://xyz.com/foo"

このコマンドは、次の診断の内訳を出力します。

--- App Link Resolution Debug ---

URI: https://xyz.com/foo
Resolution: Ambiguous (Multiple apps or Browser fallback)
This usually happens when multiple apps can handle the link and no default is set.

All Matching Candidates:

Target:
  Package: com.example.xyzapp
  Activity: com.example.xyzapp.MainActivity

  Intent Filter Match (AndroidManifest.xml)
    Scheme: 'https' matched android:scheme="https"
    Host: 'xyz.com' matched android:host="xyz.com"

App Link Verification:
  Verification status: STATE_SUCCESS
  Dynamic App Links:
    -> Matched Rule 0: UriRelativeFilterGroup { allow = 1, uri_filters = {UriRelativeFilter { uriPart = PATH, patternType = PREFIX, filter = /foo }},  }
    -> Matched Rule 1: UriRelativeFilterGroup { allow = 0, uri_filters = {UriRelativeFilter { uriPart = PATH, patternType = PREFIX, filter =  }},  }

Target:
  Package: org.chromium.webview_shell
  Activity: org.chromium.webview_shell.WebViewBrowserActivity

  Intent Filter Match (AndroidManifest.xml)
    Scheme: 'https' matched android:scheme="https"

---------------------------------

Starting: Intent { act=android.intent.action.VIEW dat=https://xyz.com/foo }

この例では、システムは assetlinks.json の 2 つの動的アプリリンク ルールを評価しました。

  • ルール 0(allow = 1filter = /foo): {"/": "/foo*", "exclude": true} から生成された除外ルール(allow: false)。/foo パス接頭辞で始まる URL をブロックします。
  • ルール 1(allow = 0filter =): {"/": "*"} から生成されます。これは、空のパス接頭辞(filter =)を持つ包含ルール(allow: true)であり、xyz.com のすべてのパスと一致します(キャッチオール)。

このシナリオでの解決の仕組み:

  1. ルール 0 とルール 1 の両方が URL https://xyz.com/foo と一致します。
  2. ダイナミック アプリリンクのルールは上から順に評価されます(最初に一致したルールが適用されます)。
  3. ルール 0 はステートメント リストの先頭にあり、除外ルール(allow = 1)であるため、一般的な許可ルール(ルール 1)よりも優先されます。
  4. そのため、アプリは https://xyz.com/foo の処理から除外され、システムはブラウザにフォールバックするか、曖昧さ回避ダイアログを表示します。