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

アプリリンクは、HTTP または HTTPS スキームを使用するディープリンクで、Android によってウェブサイトに関連付けられていることが確認されています。アプリリンクを処理するために登録する手順は次のとおりです。

  1. ウェブサイトのドメインまたは URL を指定するインテント フィルタを 1 つ以上アプリ マニフェストに追加します。
  2. インテント フィルタ要素に autoVerify="true"attribute を追加します。これにより、システムはウェブサイトの assetlinks.json 構成に対してスキームとホストドメインの検証を試みるよう指示されます。
  3. ウェブサイトの関連付けを宣言します。

スキームとホスト、および autoVerify="true を含むアプリリンク宣言の例を次に示します。

<activity
    android:name=".MainActivity"
    android:exported="true"
    ...>
    <!-- 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 link that uses the "http" scheme, your
             app should be able to delegate that traffic to "https". -->
        <!-- Do not include other schemes, as this will prevent verification. -->
        <data android:scheme="http" />
        <data android:scheme="https" />

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

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

  • AutoVerify: アプリリンクには android:autoVerify="true" 属性が必要です。これにより、アプリと <data> タグで指定されたスキームとドメインの関連付けを検証する必要があるというシグナルがシステムに送られます。検証可能にするすべてのインテント フィルタに autoVerify="true を追加することをおすすめします。
  • データ要素: 各アプリリンク インテント フィルタには、検証可能なウェブサイト ドメインと一致するスキームとホスト形式を指定する 1 つ以上の <data> 要素を含める必要があります。
  • スキーム: インテント フィルタには、http スキームと https スキームの両方の <data> 要素が含まれている必要があります。
  • ホスト: 必要に応じて、1 つ以上のホストに一致する <data> 要素を追加できます。ワイルドカード(*)を使用して、複数のサブドメイン(*.example.com など)を一致させます。システムは、ウェブサイトの assetlinks.json ファイルに対して各ホストの検証を試みます。パスレベルのルーティングは、すべて assetlinks.json ファイルで処理する必要があります(以下のベスト プラクティスのセクションを参照)。

  • 複数のホスト: 複数のホストドメインを宣言すると、システム(Android 12 以降)は各ドメインの検証を試みます。ホストが検証されると、アプリはその検証済みホストからのリンクのデフォルト ハンドラになります。Android 11 以前では、1 つでもホストを検証できないと検証に失敗します。

  • 複数のインテント フィルタ: 固有の URL(スキームとホストの特定の組み合わせなど)を宣言する場合は、個別のフィルタを作成することが重要です。同じインテント フィルタ内の複数の <data> 要素は、組み合わされた属性のバリエーションをすべて考慮してマージされるためです。

マニフェスト フィルタ ルールに関する考慮事項

Android 15 以降で動的アプリリンクで使用するフィルタを設定する場合は、サーバーサイドの assetlinks.json ファイルで宣言された動的ルールによって、アプリ マニフェストで静的に宣言された URL ルールのスコープを拡大することはできないことに注意してください。

そのため、次の方法をおすすめします。

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

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

複数のホストのアプリリンクをサポート

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

たとえば、次のインテント フィルタを持つアプリの場合、assetlinks.json ファイルが https://www.example.com/.well-known/assetlinks.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>

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

Digital Asset Links プロトコルは、インテント フィルタ内の各サブドメインを、それぞれ一意の個別ホストとして扱います。そのため、インテント フィルタ内に、サブドメインが異なる複数のホストを登録する場合、それぞれのドメイン上で、有効な 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 を呼び出した結果を含むカスタム チューザ ダイアログを表示します。ユーザーは、ダイアログに表示された一致するアプリのリストから好みのアプリを選択できます。

assetlinks.json の高度な照合ルールや <uri-relative-filter-group> の使用など、Dynamic アプリリンクの機能は、Android 15(API レベル 35)以降でのみ完全にサポートされます。

Android 14(API レベル 34)以前では、システムはアプリリンクの確認のために、マニフェストの <data> 要素で宣言された schemehost のみを考慮します。assetlinks.json のパス固有のルール、除外、動的更新は適用されません。

つまり、マニフェストで schemehost のみが指定されている場合、Android 15 以降の assetlinks.json で定義されているパス固有のルールに関係なく、Android 14 以前で検証済みドメインのすべてのパスがアプリによって予期せずキャプチャされる可能性があります。

Android 15 以降のより具体的なパスに動的アプリリンクを使用する場合に、Android 14 以前のドメインのすべてのリンクをアプリで処理しないようにするには、マニフェストのインテント フィルタに一致しないパスを含めます。リンクの有効なパスになる可能性が低い android:path 属性を持つ <data> 要素を追加します。これにより、下位バージョンでインテント フィルタがすべてのパスに一致しないようになります。

例:

<activity
    android:name=".MainActivity"
    android:exported="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" />

        <data android:scheme="http" />
        <data android:scheme="https" />
        <data android:host="www.example.com" />

        <!-- Add a non-matching path for backward compatibility -->
        <data android:path="/no_match_for_older_android_versions" />

        <uri-relative-filter-group android:allow="true">
          <data android:pathPattern="/.*"/>
        </uri-relative-filter-group>
    </intent-filter>
</activity>

<data android:path="/no_match_for_older_android_versions" /> を追加することで、Android 14 以前ではこのインテント フィルタが受信リンクと一致しないようにしつつ、assetlinks.json ルールの高度な照合ルールに基づいて、Android 15 以降でダイナミック アプリリンクを使用するためにドメインを検証できるようにします。

マニフェストに特定のパスルール(android:pathPrefix など)を含むアプリリンクがすでに存在し、Android 15 以降で動的アプリリンクの使用を開始する場合は、既存のインテント フィルタに <uri-relative-filter-group> 要素を直接追加しても問題ありません。

Android 14 以前では <uri-relative-filter-group> 要素が無視されるため、既存のアプリリンクは、下位バージョンの Android を搭載したデバイスで現在と同じように動作し続けます。

ただし、Android 15 以降で「混合」構成がどのように評価されるかを慎重に検討する必要があります。

  • 2 段階のフィルタリング: Android 15 以降では、システムはインテント フィルタをユニオンとして評価します。URL がマニフェスト チェックに合格するのは、従来の静的 <data> タグまたは <uri-relative-filter-group> の広範なルールのいずれかを満たしている場合です。URL がこの初期マニフェスト チェックに合格すると、システムは assetlinks.json ファイルで定義された動的ルールを 2 番目のレイヤのきめ細かいフィルタリングとして適用します。つまり、サーバーサイドの JSON ルールによって、一致した URL のうち実際にアプリを開くものが最終的に決定されます。

ハイブリッド構成の例:

<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="www.example.com" />

    <!-- Legacy rule: Android 14 and lower use this. Android 15 and higher
         also use this. -->
    <data android:pathPrefix="/store" />

    <!--
      Dynamic rule: Android 14 and lower ignore this. Android 15 and higher
      evaluate this as a union between all paths and the configuration
      specified in the assetlinks.json file. Make sure to apply further
      refinements in the assetlinks.json file to prevent all URL paths from
      opening in the app.
    -->
    <uri-relative-filter-group android:allow="true">
        <data android:pathPrefix="/" />
    </uri-relative-filter-group>
</intent-filter>