ウェブサイトの関連付けと動的ルールを構成する

アプリリンクをサポートするには、デジタル アセット リンクの JSON ファイル(assetlinks.json)を作成し、ウェブサイトの既知の場所に公開する必要があります。このファイルは、ドメインのリンクを処理する権限を持つアプリを公開で宣言するもので、Android デバイスはこのファイルをサーバーから取得してディープリンクを検証します。

Android 15 以降の動的 App Links の場合、assetlinks.json ファイルは、パス、フラグメント、クエリ パラメータのパターン マッチャーなど、動的ルールの構成を定義する場所でもあります。Google サービスがインストールされている Android 15(API レベル 35)以降を搭載した Android デバイスは、定期的にファイルを取得し、アプリのマニフェスト内の静的構成と動的構成を統合します。

このガイドでは、assetlinks.json ファイルを準備してウェブサイトに公開する方法について説明します。必要に応じて、Play ディープリンク ツールまたは Android Studio アプリリンク アシスタントから assetlinks.json ファイルを生成することもできます。詳しくは、アプリリンク デベロッパー ツールをご覧ください。

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

ウェブサイトに関連付けられている 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 スニペットも表示されます。

com.example Android アプリにリンクを開く権限を付与する assetlinks.json ファイルの例を以下に示します。

[{
  "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 つのウェブサイトを複数のアプリに関連付ける

1 つの assetlinks.json ファイル内で、1 つのウェブサイトを複数のアプリに関連付けることを宣言できます。ファイルリストを通じて 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 つのアプリに関連付ける

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

ダイナミック ルールを構成する

Android 15 以降のダイナミック アプリリンクを使用すると、アプリのマニフェストで静的に定義したルールと連携するサーバーサイドのディープリンク マッチング ルールを使用できます。assetlinks.json ファイルでダイナミック ルールを定義します。これは省略可能です。

Google サービスがインストールされている Android 15(API レベル 35)以降を搭載した Android デバイスは、このファイルをサーバーから定期的に取得し、アプリのマニフェスト内の静的構成と動的ルールの構成を統合します。動的ルールを含む assetlinks.json ファイルの例を次に示します。

[
  {
    "relation": [
      "delegate_permission/common.handle_all_urls"
    ],
    "target": {
      "namespace": "android_app",
      "package_name": "com.example.app",
      "sha256_cert_fingerprints": [...]
    },
    "relation_extensions": {
      "delegate_permission/common.handle_all_urls": {
        "dynamic_app_link_components": [
          {"?": {"dl": "*"}},
          {"#": "app"},
          {"/": "/products/*"},
          {"/": "/shoes", "?": {"in_app": "true"}},
          {"/": "*", "exclude": true}
        ]
      }
    }
  }
]

コードに関する主なポイント

  • 動的アプリリンクでは、dynamic_app_link_components という新しいデジタル アセット リンク リレーション拡張機能が追加されます。ここで動的ルールを構成します。
  • 動的ルールには、パス、フラグメント、クエリ パラメータのパターン マッチャーを含めることができます。
  • パターン マッチャーを除外対象としてマークすることもできます。これにより、一致する URL でアプリが開かなくなります。
  • この例は、パス("/")、フラグメント("#")、クエリ パラメータ("?")のマッチャーと、除外されたマッチャー("exclude")の例を示しています。
  • ファイル内のフィールドのいずれかが不正な形式であるか空の場合、Android は動的ルールを破棄し、デバイスはアプリのマニフェストで静的に定義されたルールにフォールバックします。

動的ルールでは、アプリのマニフェスト ファイルで宣言したドメインのスコープ内で適用されるルールのみを指定できます。下記をご覧ください。

ダイナミック ルールを宣言する

ダイナミック アプリリンクは、ルール オブジェクトの配列を保持する新しい dynamic_app_link_components 関係拡張機能をサポートしています。各ルールは、アプリを開くパス、フラグメント、クエリ パラメータのパターン マッチャーを使用して定義されます。マッチャーを個別に除外して、アプリを開かないようにすることもできます。これらはすべて省略可能です。

  • パスマッチング
    • キー: 「/」
    • 値: URL パスの照合式を表す単一の文字列
  • フラグメントのマッチング
    • キー: 「#」
    • 値: URL フラグメントの一致式を表す単一の文字列
  • クエリ パラメータのマッチング
    • キー: 「?」
    • 値: URL クエリ パラメータの Key-Value ペアを照合するディクショナリ。
    • たとえば、辞書 {"?", {"dl": "*", "in_app":"true"} はクエリ文字列 "?in_app=true&dl=abc" と一致します。
    • ディクショナリ内のキーと値のペアの順序は、クエリ文字列内のペアの順序と一致する必要はありません。また、ディクショナリはクエリ文字列内のすべてのキーと値のペアと一致する必要はありませんが、ディクショナリ エントリごとに一致が見つかる必要があります。
    • たとえば、この辞書はクエリ文字列「?lang=en&in_app=true&tz=pst&dl=abc」にも一致しますが、クエリ文字列「?lang=en&tz=pst&dl=abc」には一致しません。
  • 除外
    • キー: "exclude"
    • 値: dynamic_app_link_components で定義された各ルールのオプションの true/false 値(例を参照)。

パターン マッチャーでは次の特殊文字を使用できます。

  • 「*」は、パターン内のワイルドカードの後の文字が一致する文字列で見つかるまで、0 個以上の文字と一致します。
  • ? は任意の 1 文字に一致します
  • 「?*」は 1 文字以上に一致します

値に関する文字の制限は他にありません。

ダイナミック ルールを注文する

ルールの宣言順序は重要です。Android は、一致するルールが見つかるまで各ルールを順番に評価します。

次の例は、順序が処理にどのように影響するかを示しています。最初のルールはすべてのパス(「*」)に一致しますが、一致を除外(exclude: true)します。つまり、すべての URL でアプリを開くことが除外されます。この場合、「/path1」を許可する 2 番目のルールは評価されません。

dynamic_app_link_components: [
  {​"/": "*", exclude: true},
  {​"/": "/path1"}
]

ただし、次の例では「/path1」ルールが最初に宣言されているため、最初に評価され、「/path1」に一致する URL のアプリが開きます。2 番目のルール(すべての URL をアプリを開く対象から除外するルール)は、1 番目のルールが一致しなかった場合にのみ、2 番目に評価されます。

dynamic_app_link_components: [
  {​"/": "/path1"},
  {​"/": "*", exclude: true}
]

ダイナミック ルールのスコープを適切に設定する

Android 15 以降で Dynamic App Links とともに使用するサーバーサイド ルールを定義する際は、アプリのマニフェストで宣言された静的インテント フィルタと連携して補完できるように、適切にスコープを設定することが重要です。

assetlinks.json ファイルで宣言された動的ルールでは、アプリの AndroidManifest.xml ファイルで宣言したホストのルールのみを指定できます。動的ルールでは、アプリ マニフェストで静的に宣言した URL ルールのスコープを拡大することはできません

このため、動的ルールと静的ルール全体でこのアプローチを使用することをおすすめします。

  • アプリ マニフェストで、スキームとドメインのみを宣言するなど、可能な限り広範なスコープでルールを設定します。
  • パスレベルのルーティングなど、サーバーサイドの動的ルールを使用してさらに絞り込みます。

この理想的な構成では、アプリのマニフェストで設定した広範なスコープ内に収まることを前提として、必要に応じて assetlinks.json ファイルに新しいアプリリンクのパスを動的に追加できます。

ルールを正しく処理するには、特定のサイト、関連付け、アプリのステートメント全体で dynamic_app_link_components オブジェクトを 1 つだけ宣言します。

  • 同じサイト、関連付け、アプリに対して、dynamic_app_link_components オブジェクトを宣言する複数のステートメントを探します。
  • 1 つのステートメントで宣言されている複数の dynamic_app_link_components オブジェクトを探す

このような場合、Android はどの動的ルール構成が使用されるかを保証しません。

以前のアプリリンク構成との動的ルールの互換性

アプリリンクをすでにサポートしている場合は、既存の assetlinks.json ファイルにダイナミック リンクのサポートを直接追加できます。アプリリンクの検証に使用する関連フィールドは変更されません。他の変更を加えることなく、動的ルールの新しい関連拡張フィールドを追加できます。

Android 14(API レベル 34 以前)を搭載した Android デバイスは、動的ルールの新しい関係拡張フィールドを無視しますが、Android 15 以降を搭載したデバイスは、これらのルールをマニフェストで定義されたルールと統合します。

JSON 検証ファイルを公開する

次の場所で JSON 検証ファイルを公開する必要があります。

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

注:

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

次の関連ガイドをご覧ください。