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

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

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

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

  2. 次の場所でデジタル アセット リンクの 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". -->
    <data android:scheme="http" />
    <data android:scheme="https" />

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

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

ドメイン検証プロセスにはインターネット接続が必要であり、完了までに時間がかかることがあります。プロセスの効率を向上させるため、Android 12 以降をターゲットとするアプリのドメインは、そのドメインが上記のコード スニペットで指定した形式とまったく同じ形式を含む <intent-filter> 要素内にある場合にのみ、検証されます。

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

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

注: Android 11(API レベル 30)以前では、マニフェストで定義したすべてのホストで一致するデジタル アセット リンク ファイルが検出されない限り、アプリはデフォルト ハンドラとして検証されません。

たとえば、次のインテント フィルタを持つアプリは、assetlinks.json ファイルが https://www.example.net/.well-known/assetlinks.json ではなく https://www.example.com/.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 が含まれています。したがって、有効な assetlinks.jsonhttps://www.example.com/.well-known/assetlinks.jsonhttps://mobile.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" />
      <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 ファイル内で複数のアプリとの関連付けを宣言できます。次のファイルリストは、https://www.example.com/.well-known/assetlinks.json にある 2 つのアプリとの関連付けを個別に宣言するステートメント ファイルの例を示しています。

[{
  "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 ファイルは、content-type application/json で提供されます。
  • assetlinks.json ファイルは、アプリのインテント フィルタが HTTPS をデータスキームとして宣言しているかどうかにかかわらず、HTTPS 接続でアクセスできる必要があります。
  • assetlinks.json ファイルは、リダイレクトなしでアクセスできる必要があります(301 リダイレクトや 302 リダイレクトは不可)。
  • アプリリンクが複数のホストドメインをサポートしている場合は、各ドメインで assetlinks.json ファイルを公開する必要があります。複数のホストのアプリリンクをサポートするをご覧ください。
  • 一般にはアクセスできない可能性がある開発/テスト URL をマニフェスト ファイルに含めてアプリを公開しないでください(VPN でのみアクセスできる URL など)。このような場合の回避策は、ビルド バリアントを構成して、開発ビルド用に別のマニフェスト ファイルを生成することです。

Android アプリリンクの検証

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

自動確認

システムによる自動確認には、次の処理が含まれます。

  1. システムは、次のいずれかを含むすべてのインテント フィルタを検査します。
    • アクション: android.intent.action.VIEW
    • カテゴリ: android.intent.category.BROWSABLEandroid.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 に示すように、この画面には [Open supported links] というラジオボタンがあります。

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

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

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

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

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

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

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

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

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

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

  • 値が http または httpsandroid: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 アプリリンクを確認できない場合は、次の一般的なエラーがないか確認してください。このセクションでは、プレースホルダ ドメイン名として example.com を使用します。この確認を行う際には、example.com をサーバーの実際のドメイン名に置き換えてください。

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

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

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

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

次のようなリダイレクトを設定した場合、システムはアプリの Android アプリリンクを検証しません。

  • http://example.com から https://example.com まで
  • example.com から www.example.com まで

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

サーバーの堅牢性

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

確認できないリンク

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

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

署名が正しく、アプリの署名に使用した署名と一致していることを確認します。よくある誤りは次のとおりです。

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