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

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

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

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

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

テストの際は、システムがアプリに対して検証する必要がある関連ホストのリストを確認する必要があります。対応するインテント フィルタに次の属性と要素が含まれているすべての URL のリストを作成します。

  • android:scheme 属性の値が http または https
  • ドメイン URL パターンを含む 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://<var>domain.name</var>:<var>optional_port</var>&amp;
   relation=delegate_permission/common.handle_all_urls

Dynamic App Links の場合は、リレーション拡張機能も確認できます。

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 以降では、アクティビティ マネージャー(am start)コマンドで --debug-link フラグを使用して、システムが特定の URL をどのように解決するかを診断できます。このツールは、インテントに一致した候補アプリの詳細な内訳と、解決時に評価されたアプリ マニフェストおよび assetlinks.json ファイル(動的アプリリンク用)の特定のルールを提供します。

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

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

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

  • ターゲットの詳細: 一致する各候補アプリをパッケージ名とターゲット アクティビティで識別します。
  • インテント フィルタの一致(AndroidManifest.xml): マニフェスト インテント フィルタのどの静的属性(scheme、host、path、pathPrefix、pathPattern など)が URI と一致したかを示します。
  • アプリリンクの検証: 現在のドメイン検証状態(STATE_SUCCESS など)が表示されます。
  • Dynamic App Links: アプリが assetlinks.json ファイルで Dynamic App Links の一致ルールを使用している場合、このセクションには、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 = 1、filter = /foo): {"/": "/foo*", "exclude": true} から生成された、/foo パス接頭辞で始まる URL をブロックする排他ルール(allow: false)です。
  • ルール 1(allow = 0、filter =): {"/": "*"} から生成された、空のパス接頭辞(filter =)を持つ包含ルール(allow: true)です。xyz.com の下のすべてのパスに一致します(キャッチオール)。

このシナリオでの解決方法:

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