Android アプリリンクを検証する

Android アプリリンクは特別なタイプのディープリンクであり、ウェブサイト URL から直接 Android アプリ内の対応コンテンツを開けるようになります(ユーザーがアプリを選択する必要はありません)。Android アプリリンクは Digital Asset Links API を使用して、そのドメインのリンクを自動的に開くようにアプリがウェブサイトによって承認されているという信頼を確立します。URL を所有していることが正常に検証されると、システムは自動的に URL インテントをアプリにルーティングします。

アプリとウェブサイトの URL の両方を所有していることを確認する手順は次のとおりです。

  1. autoVerify 属性を含むインテント フィルタを追加します。この属性は、インテント フィルタで使用されている URL ドメインに属するアプリにアプリが所属しているかどうかをシステムに通知します。

  2. 以下の場所に Digital Asset Links JSON ファイルをホストすることにより、ウェブサイトとインテント フィルタの関連付けを宣言します。

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

関連情報については、次のリソースをご覧ください。

アプリリンクの検証用のインテント フィルタを追加する

アプリのリンク処理の検証を有効にするには、次の形式のインテント フィルタを追加します。

<!-- Make sure you explicitly set android:autoVerify to "true". -->
<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" />

    <!-- If a user clicks on a shared link that uses the "http" scheme, your
         app should be able to delegate that traffic to "https". -->
    <!-- Do not include other schemes. -->
    <data android:scheme="http" />
    <data android:scheme="https" />

    <!-- Include one or more domains that should be verified. -->
    <data android:host="..." />
</intent-filter>

autoVerify を各ホストの <intent-filter> 宣言に含めるだけで十分ですが、そのホストが、マークされていない他の宣言にわたって使用されている場合でも、一貫性のために各 <intent-filter> 要素に autoVerify を追加することをおすすめします。また、マニフェスト ファイル内の要素を削除またはリファクタリングした後も、アプリは引き続き定義されているすべてのドメインに関連付けられます。

ドメイン検証プロセスにはインターネット接続が必要であり、完了までに時間がかかることがあります。システムはプロセスの効率を高めるために、Android 12 以降をターゲットとするアプリのドメインが、前のコード スニペットで指定された形式と完全に一致する <intent-filter> 要素内にある場合にのみ、ドメインを検証します。たとえば、「http」や「https」以外のスキーム(<data android:scheme="custom" /> など)では、<intent-filter> がドメインの所有権確認をトリガーしません。

複数のホスト用のアプリリンク機能をサポートする

アプリの URL インテント フィルタのデータ要素で指定されたホストは、そのインテント フィルタ内のそれぞれのウェブドメインでホストされているデジタル アセット リンク ファイルに対して検証可能である必要があります。検証が失敗した場合、システムは、アプリ コンテンツへのディープリンクを作成するで説明されているように、インテントを解決する標準動作をデフォルト設定します。ただし、アプリは、アプリの他のインテント フィルタで定義されている URL パターンのデフォルト ハンドラとして検証できます。

注: Android 11(API レベル 30)以前では、マニフェストで定義したすべてのホストに一致する Digital Asset Links ファイルが見つからない場合、システムはアプリをデフォルト ハンドラとして検証しません。

たとえば、次のインテント フィルタを持つアプリは、https://www.example.com/.well-known/assetlinks.jsonassetlinks.json ファイルが見つかったものの https://www.example.net/.well-known/assetlinks.json で見つからない場合、https://www.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="http" />
      <data android:scheme="https" />
      <data android:host="www.example.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="www.example.net" />
    </intent-filter>
  </activity>

</application>

注: 同じインテント フィルタ内のすべての <data> 要素は、組み合わされた属性のバリエーションをすべて考慮してマージされます。たとえば、上記の最初のインテント フィルタには、HTTPS スキームだけを宣言している <data> 要素が含まれています。ただし、他の <data> 要素と組み合わせることで、インテント フィルタが http://www.example.comhttps://www.example.com の両方をサポートするようになります。そのため、URI スキームとドメインの特定の組み合わせを定義する場合は、個別のインテント フィルタを作成する必要があります。

複数のサブドメイン用のアプリリンク機能をサポートする

デジタル アセット リンク プロトコルでは、インテント フィルタ内のサブドメインは、一意の個別のホストとして扱われます。そのため、インテント フィルタ内に、サブドメインが異なる複数のホストを登録する場合、それぞれのドメイン上で、有効な assetlinks.json を公開する必要があります。たとえば、次のインテント フィルタには、受け入れられるインテントの URL ホストとして www.example.commobile.example.com が含まれています。そのため、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" />
      <data android:scheme="https" />
      <data android:host="www.example.com" />
      <data android:host="mobile.example.com" />
    </intent-filter>
  </activity>
</application>

あるいは、ワイルドカードを使用してホスト名を宣言する場合(*.example.com など)は、ルートホスト名(example.com)で assetlinks.json ファイルを公開する必要があります。たとえば、次のインテント フィルタを持つアプリは、assetlinks.json ファイルが https://example.com/.well-known/assetlinks.json で公開されている限り、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" />
      <data android:host="*.example.com" />
    </intent-filter>
  </activity>
</application>

同じドメインに関連付けられている複数のアプリを確認する

同じドメインに関連付けられている複数のアプリを公開する場合、各アプリを正常に検証できます。ただし、軽量版とフル版のようにアプリがまったく同じドメインホストとパスを解決できる場合は、直近にインストールされたアプリのみがそのドメインのウェブ インテントを解決できます。

このような場合は、必要なパッケージの公開設定があれば、ユーザーのデバイス上で競合する可能性のあるアプリを確認します。次に、アプリで queryIntentActivities() を呼び出した結果を含むカスタム チューザ ダイアログを表示します。ユーザーは、ダイアログに表示された一致するアプリのリストから好みのアプリを選択できます。

ウェブサイトの関連付けを宣言する

ウェブサイトに関連付けられている Android アプリを示し、アプリの URL インテントを検証するために、デジタル アセットリンク JSON ファイルをウェブサイト上で公開する必要があります。JSON ファイルでは、関連付けられたアプリを識別するために次のフィールドが使用されます。

  • package_name: アプリの build.gradle ファイル内で宣言されているアプリ ID
  • sha256_cert_fingerprints: アプリの署名証明書の SHA256 フィンガープリント。Java keytool を使用してフィンガープリントを生成するには、次のコマンドを使用します。
    keytool -list -v -keystore my-release-key.keystore
    
    このフィールドは複数のフィンガープリントをサポートしており、デバッグビルドや実稼働ビルドなど、アプリのさまざまなバージョンをサポートすることができます。

    アプリで Play アプリ署名を使用している場合、keytool をローカルで実行することによって生成される証明書フィンガープリントは通常、ユーザーのデバイス上の証明書フィンガープリントと一致しません。アプリで Play アプリ署名を使用しているかどうかは、Google Play Console のデベロッパー アカウントの Release > Setup > App signing で確認できます。使用している場合は、同じページにアプリの正しいデジタル アセット リンクの JSON スニペットも表示されます。

次の 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"]
  }
}]

1 つのウェブサイトを複数のアプリに関連付ける

ウェブサイトは、同じ assetlinks.json ファイル内で複数のアプリとの関連付けを宣言できます。次のファイルリストは、2 つのアプリとの関連付けを個別に宣言する、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"]
  }
}]

1 つのウェブホストにある複数のリソースに対してそれぞれ個別のリンクを用意し、各リンクを別のアプリで処理することができます。たとえば、app1 は https://example.com/articles 用のインテント フィルタを宣言し、app2 は https://example.com/videos 用のインテント フィルタを宣言する、というように指定できます。

注: 1 つのドメインに関連付けられた複数のアプリは、同じ証明書で署名することも、異なる証明書で署名することもできます。

複数のウェブサイトを 1 つのアプリに関連付ける

複数のウェブサイトが、それぞれの 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

注:

  • assetlinks.json ファイルは、コンテンツ タイプ application/json で提供されます。
  • assetlinks.json ファイルは、アプリのインテント フィルタで HTTPS がデータスキームとして宣言されているかどうかにかかわらず、HTTPS 接続でアクセスできる必要があります。
  • assetlinks.json ファイルは、リダイレクトなしでアクセス可能(301 または 302 リダイレクトなし)である必要があります。
  • アプリリンクが複数のホストドメインをサポートしている場合は、各ドメインで assetlinks.json ファイルを公開する必要があります。複数のホスト用のアプリリンク機能をサポートするをご覧ください。
  • 誰もがアクセスできるわけでない dev / test URL をマニフェスト ファイル内で使用してアプリを公開しないでください(VPN 内に限りアクセス可能な dev / test URL など)。このような場合の回避策は、ビルド バリアントを構成して、開発ビルド用に別のマニフェスト ファイルを生成することです。

Android アプリリンクの検証

アプリのインテント フィルタの 1 つ以上に android:autoVerify="true" が存在する場合、Android 6.0(API レベル 23)以降を搭載したデバイスにアプリをインストールすると、アプリのインテント フィルタ内の URL に関連付けられているホストが自動的に検証されます。Android 12 以降では、検証プロセスを手動で呼び出して、検証ロジックをテストすることもできます。

自動確認

システムの自動確認では、次のことを行います。

  1. 次のいずれかを含むすべてのインテント フィルタが検査されます。
    • アクション: android.intent.action.VIEW
    • カテゴリ: android.intent.category.BROWSABLE および android.intent.category.DEFAULT
    • データスキーム: http または https
  2. 上記のインテント フィルタで見つかった一意のホスト名ごとに、Android は対応するウェブサイトで https://hostname/.well-known/assetlinks.json にあるデジタル アセット リンク ファイルをクエリします。

アプリに関連付けるウェブサイトのリストを確認し、ホストされる JSON ファイルが有効であることを確認したら、アプリをデバイスにインストールします。非同期検証プロセスが完了するまで、少なくとも 20 秒待ちます。次のコマンドを使用して、システムでアプリが検証されたかどうかをチェックし、正しいリンク処理ポリシーを設定します。

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

手動でのオーナー確認

Android 12 以降では、デバイスにインストールされているアプリのドメインの検証を手動で呼び出せます。このプロセスは、アプリが Android 12 をターゲットとしているかどうかに関係なく実施できます。

インターネット接続を確立する

ドメインの検証を行うには、テストデバイスをインターネットに接続する必要があります。

更新されたドメイン検証プロセスをサポートする

アプリが Android 12 以降をターゲットとしている場合、更新されたドメイン検証プロセスが自動的に使用されます。

それ以外の場合は、更新された検証プロセスを手動で有効にできます。そのためには、ターミナル ウィンドウで次のコマンドを実行します。

adb shell am compat enable 175408749 PACKAGE_NAME

デバイスの Android アプリリンクの状態をリセットする

デバイスでドメインの検証を手動で呼び出す前に、テストデバイスの Android アプリリンクの状態をリセットする必要があります。そのためには、ターミナル ウィンドウで次のコマンドを実行します。

adb shell pm set-app-links --package PACKAGE_NAME 0 all

このコマンドは、デバイスを、ユーザーが任意のドメインのデフォルト アプリを選択する前と同じ状態にします。

ドメイン検証プロセスを呼び出す

デバイスの Android アプリリンクの状態をリセットした後、検証自体を実施できます。そのためには、ターミナル ウィンドウで次のコマンドを実行します。

adb shell pm verify-app-links --re-verify PACKAGE_NAME

検証結果を確認する

検証エージェントがリクエストを終えるまで少し待ってから、検証結果を確認します。これを行うには、次のコマンドを実行します。

adb shell pm get-app-links PACKAGE_NAME

このコマンドの出力は、次のようになります。

com.example.pkg:
    ID: 01234567-89ab-cdef-0123-456789abcdef
    Signatures: [***]
    Domain verification state:
      example.com: verified
      sub.example.com: legacy_failure
      example.net: verified
      example.org: 1026

検証が完了したドメインは、ドメイン検証状態が verified になります。その他の状態は、ドメインの検証を実施できなかったことを示します。特に none の状態は、検証エージェントがまだ検証プロセスを完了していない可能性があることを示します。

特定のドメインについてドメインの検証で返される可能性がある戻り値を次に示します。

none
このドメインは何も記録されていません。検証エージェントがドメインの検証に関連するリクエストを終えるまでさらに数分待ってから、もう一度ドメイン検証プロセスを呼び出します
verified
宣言のアプリについて、ドメインの検証が完了しました。
approved
ドメインが(通常はシェルコマンドの実行によって)強制的に承認されました。
denied
ドメインが(通常はシェルコマンドの実行によって)強制的に拒否されました。
migrated
以前のドメイン検証を使用した以前のプロセスの結果がシステムに保持されていました。
restored
ユーザーがデータの復元を行った後にドメインが承認されました。ドメインは以前に検証されているものと思われます。
legacy_failure
ドメインが以前の検証ツールによって拒否されました。具体的なエラーの理由は不明です。
system_configured
デバイス設定によりドメインが自動的に承認されました。
エラーコード 1024 以上

デバイスの検証ツールに固有のカスタム エラーコード。

ネットワーク接続が確立されていることを再確認し、もう一度ドメイン検証プロセスを呼び出します

アプリをドメインに関連付けるようユーザーに依頼する

アプリをドメインについて承認するもう 1 つの方法は、アプリをそのドメインに関連付けるようユーザーに依頼することです。

アプリがすでにドメインに対して承認されているかどうかを確認する

ユーザーにプロンプトを表示する前に、アプリが、<intent-filter> 要素で定義したドメインのデフォルト ハンドラになっているかどうかを確認します。承認状態をクエリするには、次のいずれかの方法を使用します。

DomainVerificationManager

次のコード スニペットは、DomainVerificationManager API の使用方法を示しています。

Kotlin

val context: Context = TODO("Your activity or fragment's Context")
val manager = context.getSystemService(DomainVerificationManager::class.java)
val userState = manager.getDomainVerificationUserState(context.packageName)

// Domains that have passed Android App Links verification.
val verifiedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_VERIFIED }

// Domains that haven't passed Android App Links verification but that the user
// has associated with an app.
val selectedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_SELECTED }

// All other domains.
val unapprovedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_NONE }

Java

Context context = TODO("Your activity or fragment's Context");
DomainVerificationManager manager =
        context.getSystemService(DomainVerificationManager.class);
DomainVerificationUserState userState =
        manager.getDomainVerificationUserState(context.getPackageName());

Map<String, Integer> hostToStateMap = userState.getHostToStateMap();
List<String> verifiedDomains = new ArrayList<>();
List<String> selectedDomains = new ArrayList<>();
List<String> unapprovedDomains = new ArrayList<>();
for (String key : hostToStateMap.keySet()) {
    Integer stateValue = hostToStateMap.get(key);
    if (stateValue == DomainVerificationUserState.DOMAIN_STATE_VERIFIED) {
        // Domain has passed Android App Links verification.
        verifiedDomains.add(key);
    } else if (stateValue == DomainVerificationUserState.DOMAIN_STATE_SELECTED) {
        // Domain hasn't passed Android App Links verification, but the user has
        // associated it with an app.
        selectedDomains.add(key);
    } else {
        // All other domains.
        unapprovedDomains.add(key);
    }
}

コマンドライン プログラム

開発中にアプリをテストする際、次のコマンドを実行すると、組織が所有するドメインの検証状態をクエリできます。

adb shell pm get-app-links --user cur PACKAGE_NAME

次の出力例では、「example.org」ドメインの検証が失敗したにもかかわらず、ユーザー 0 がシステム設定でアプリを手動で承認しており、そのドメインに対して他のパッケージは検証されていません。

com.example.pkg:
ID: ***
Signatures: [***]
Domain verification state:
  example.com: verified
  example.net: verified
  example.org: 1026
User 0:
  Verification link handling allowed: true
  Selection state:
    Enabled:
      example.org
    Disabled:
      example.com
      example.net

また、シェルコマンドを使用して、ユーザーが特定のドメインに関連付けるアプリを選択するプロセスをシミュレートすることもできます。これらのコマンドの詳細な説明は、adb shell pm の出力で確認できます。

リクエストの説明をする

ドメイン承認のリクエストを行う前に、ユーザーに状況を説明します。たとえばスプラッシュ画面、ダイアログ、または同様の UI 要素を表示して、アプリを特定のドメインのデフォルト ハンドラにする必要がある理由をユーザーに説明します。

リクエストを行う

アプリが何をするよう求めているのかをユーザーが理解したら、リクエストを行います。そのためには、次のコード スニペットに示すように、ACTION_APP_OPEN_BY_DEFAULT_SETTINGS インテントのアクションと、ターゲット アプリの package:com.example.pkg に一致するデータ文字列を含むインテントを呼び出します。

Kotlin

val context: Context = TODO("Your activity or fragment's Context")
val intent = Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:${context.packageName}"))
context.startActivity(intent)

Java

Context context = TODO("Your activity or fragment's Context");
Intent intent = new Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:" + context.getPackageName()));
context.startActivity(intent);

インテントが呼び出されると、ユーザーには [デフォルトで開く] という設定画面が表示されます。図 1 に示すように、この画面には [対応リンクを開く] というラジオボタンがあります。

ユーザーが [対応リンクを開く] をオンにすると、[このアプリ内で開くリンク] というセクションに、一連のチェックボックスが表示されます。ユーザーはここから、アプリに関連付けるドメインを選択できます。図 2 に示すように、[リンクを追加] を選択してドメインを追加することもできます。ユーザーが追加したドメイン内のリンクを選択すると、そのリンクがアプリで自動的に開きます。

ラジオボタンをオンにすると下部のセクションにチェックボックスと [リンクを追加] ボタンが表示されます
図 1. アプリでデフォルトで開くリンクをユーザーが選択できるシステム設定画面。
各チェックボックスは追加できるドメインを表しています。ダイアログのボタンは [キャンセル] と [追加] です。
図 2. アプリに関連付ける追加のドメインをユーザーが選択できるダイアログ。

アプリが検証できないドメインをアプリで開く

サードパーティとしてリンクを開くことがアプリの主な機能であって、処理対象ドメインを検証する機能を備えていないこともあります。その場合は、ユーザーがウェブリンクを選択する際に、ファーストパーティ アプリとサードパーティ アプリのどちらかを選択できないことを説明します。ユーザーは、ドメインをサードパーティ アプリに手動で関連付ける必要があります。

さらに、ユーザーが希望する場合はファーストパーティ アプリでリンクを開くことができる、プロキシとして機能するダイアログまたはトランポリン アクティビティの導入を検討します。このようなダイアログまたはトランポリン アクティビティを設定する前に、アプリのウェブ インテント フィルタに一致するファーストパーティ アプリに対してパッケージの公開設定を持つようにアプリを設定します。

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

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

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

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

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

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

このリストを使用して、指定された各ホストとサブドメインでデジタル アセット リンクの JSON ファイルが提供されていることを確認します。

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

ウェブサイトごとに、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

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

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 が示されます。このステータスの後ろにある 16 進数は、ユーザーのアプリリンク設定に関して 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" />
            <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 App Links を確認できない場合は、次の一般的なエラーを確認してください。このセクションでは、プレースホルダのドメイン名として example.com を使用します。これらのチェックを行う場合は、example.com をサーバーの実際のドメイン名に置き換えてください。

インテント フィルタの設定が正しくない
アプリが所有していない URL が <intent-filter> 要素に含まれているかどうかを確認します。
サーバーの設定が正しくない

サーバーの JSON 構成で、SHA 値が正しいことを確認します。

また、example.com.(末尾にピリオドあり)が example.com と同じコンテンツを提供していることを確認します。

サーバーサイドのリダイレクト

次のようなリダイレクトを設定した場合、アプリの Android アプリリンクは一切検証されません。

  • http://example.comhttps://example.com
  • example.comwww.example.com

これにより、アプリのセキュリティが保護されます。

サーバーの堅牢性

サーバーがクライアント アプリに接続できるかどうかを確認します。

確認できないリンク

テスト目的で、検証できないリンクを意図的に追加してもかまいません。Android 11 以前では、このようなリンクがあると、アプリの Android アプリリンクがすべて検証されなくなります。

assetlinks.json の署名が正しくない

署名が正しく、アプリの署名に使用した署名と一致していることを確認します。一般的な間違いには次のものがあります。

  • デバッグ証明書でアプリに署名し、assetlinks.json にリリース署名のみが含まれている。
  • assetlinks.json に小文字のサインがある。署名は大文字にする必要があります。
  • Play アプリ署名を使用している場合は、Google が各リリースの署名に使用する署名を使用していることを確認してください。完全な JSON スニペットを含むこれらの詳細を確認するには、ウェブサイトの関連付けを宣言する手順に沿って操作します。