SysTecevo

Android App Linksとは?Deep Linkとの違い・assetlinks.jsonの設定と開かない時の対処

初回掲載日:
最終更新日:

Web URLから検証を経てAndroidアプリを開くApp Linksのオリジナル図解

Android App Linksは、WebサイトのURLとAndroidアプリを関連付け、検証済みのURLをアプリへ直接渡すための仕組みです。単なるDeep Linkよりも「このドメインをこのアプリが扱う」という確認が加わるため、リンクを押したときの選択ダイアログを減らしやすくなります。

先に結論:App Linksの設定は、アプリ側のManifestだけでは完了しません。android:autoVerify="true"を付けたintent filter、Web側の https://ドメイン/.well-known/assetlinks.json、そして実際に配布する署名証明書のSHA-256 fingerprintを一致させる必要があります。

この記事で分かること

  • 通常のDeep LinkとApp Links、Dynamic App Linksの違い
  • Manifest、android:autoVerify、assetlinks.jsonの設定順
  • package_nameとSHA-256 certificate fingerprintの確認方法
  • debug署名、release署名、Google Play App Signingの注意点
  • 検証コマンドと、リンクを押してもアプリが開かない時の切り分け
  • Android 15(API 35)以降のDynamic App Linksをどう使い分けるか

Android App Linksとは

App Linksは、Android 6(API 23)以降で利用できる、Webサイトとアプリの関連付けを検証するDeep Linkの仕組みです。アプリのManifestにWeb URLのintent filterを宣言し、Webサイト側にDigital Asset Linksの声明ファイルを置きます。Androidが両者を確認できると、対応するURLをアプリへ直接ルーティングできます。

アプリがインストールされていないユーザーはWebサイトへ進めるため、同じURLをWebとアプリの入口として使える点も特徴です。App LinksはURLをアプリで開く機能だけではなく、ドメイン所有と署名証明書を使って、別アプリが同じURLを横取りしにくくする仕組みでもあります。

Deep Linkとの違い

方式検証主な動き向いている場面
通常のDeep LinkWebサイトとの所有関係を必須にしない条件に合うアプリや選択画面へintentを渡すアプリ内画面への入口、独自schemeなど
App Linksassetlinks.jsonと署名証明書で検証検証済みWeb URLをアプリへ直接渡しやすい自社ドメインのURLを安全にアプリへつなぐ
Dynamic App LinksApp Linksの検証に加えサーバー側ルールを利用Android 15以降でpath・query等の扱いを更新できるキャンペーンやURL範囲の細かな運用
通常のDeep Link、App Links、Dynamic App Linksの検証と設定範囲を比較するオリジナル図解
App LinksはDeep LinkにWebサイト側の関連付け検証を加えた仕組みです。

App LinksがURLをアプリへ渡す流れ

  1. ユーザーが https://example.com/products/42 のようなURLを開く。
  2. アプリのManifestに、scheme・host・必要なpathのintent filterがある。
  3. AndroidがWebサイトの /.well-known/assetlinks.json を取得する。
  4. JSON内のpackage nameとSHA-256 fingerprintが、アプリの署名と一致するか検証する。
  5. 検証済みで、URLがintent filterの範囲に合えば、対応Activityへintentを渡す。

この流れのどこか一つだけを設定しても動きません。Manifestのhost、Web側のファイル、署名証明書、実際にタップしたURLのpathを一つの組み合わせとして確認します。

設定手順1:Manifestにintent filterを追加する

次は説明用のサンプルです。example.com、Activity名、pathは自分のアプリとWebサイトに置き換えてください。

<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="https"
            android:host="example.com"
            android:pathPrefix="/products" />
    </intent-filter>
</activity>

android:autoVerify="true"は、インストール時などにAndroidがWebサイトとの関連付けを検証するよう要求する属性です。これは検証を「必ず成功させる」属性ではありません。Web側のJSON、署名、HTTPS、hostが正しくなければ検証は失敗します。

複数のhostを扱う場合は、hostごとの関連付けを考えます。サブドメインも別のhostとして扱われるため、各ドメインで正しい assetlinks.jsonを公開する必要があります。

設定手順2:assetlinks.jsonを配置する

Digital Asset Linksの声明ファイルは、次の固定URLでHTTPS公開します。

https://example.com/.well-known/assetlinks.json

サンプルのJSONは次の形です。fingerprintはダミー値なので、そのまま使わないでください。

[
  {
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target": {
      "namespace": "android_app",
      "package_name": "com.example.app",
      "sha256_cert_fingerprints": [
        "AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99"
      ]
    }
  }
]

確認するポイントは、ファイルがHTTPSで直接取得でき、301・302などのリダイレクトを挟まず、application/jsonとして返ることです。JSONの文法エラー、余分なHTML、認証が必要な公開範囲でも検証に失敗します。

package_nameとSHA-256 fingerprint

package_nameは、アプリのapplication IDです。Manifestの見た目のlabelではなく、Gradleのapplication IDと一致させます。別flavor・別application IDを使う場合は、どのアプリを関連付けるかを分けて考えてください。

sha256_cert_fingerprintsは、アプリを署名した証明書のSHA-256 fingerprintです。debugビルドの証明書とreleaseビルドの証明書は通常異なるため、debugで動いた設定をそのまま本番へ出すことはできません。

Google Play App Signingを利用している場合、ユーザーへ配信されるアプリを署名する証明書は、ローカルのupload keyと異なる場合があります。assetlinks.jsonへ登録するfingerprintは、Play Consoleで確認できるapp signing certificateを基準にします。署名鍵の役割が曖昧な場合は、Google Playの署名鍵・アップロード鍵の記事も確認してください。

設定手順3:アプリ側で受け取るURLを処理する

検証が成功しても、Activity側で受け取ったintentのURIを処理しなければ、アプリのトップ画面しか開かないことがあります。intent.dataからhost・path・queryを読み、許可したURLだけをアプリ内画面へ変換します。

val uri = intent?.data
if (uri?.host == "example.com" && uri.path?.startsWith("/products/") == true) {
    val productId = uri.lastPathSegment
    // productIdを検証してから対象画面へ遷移する
}

URLから受け取った値をそのままSQLや画面遷移へ渡さず、形式・権限・存在確認を行ってください。App Linksの検証は「このアプリがドメインに関連付けられている」ことを示すもので、URLパラメータの安全性を保証するものではありません。

検証方法

1. Web側のファイルを直接確認

ブラウザーまたはHTTPクライアントで、次を確認します。

  • https://example.com/.well-known/assetlinks.jsonがHTTP 200で返る
  • リダイレクト先ではなく、指定URLそのものがHTTPSで応答する
  • Content-TypeがJSONとして扱える
  • package nameとSHA-256 fingerprintがrelease署名と一致する

2. Android端末の検証状態を確認

パッケージ名はサンプルです。自分のapplication IDに置き換えてください。

adb shell pm get-app-links com.example.app
adb shell pm verify-app-links --re-verify com.example.app

設定を変更した後に端末が古い検証結果を保持していると、修正がすぐ見えないことがあります。再検証後に実機で確認し、端末やOSバージョンごとの挙動を切り分けます。Android StudioのApp Links AssistantやPlay Deep Links toolを利用できる場合は、設定の補助として使えます。

3. 実際のURLを起動する

adb shell am start \
  -a android.intent.action.VIEW \
  -d "https://example.com/products/42"

ブラウザーのアドレス欄へ貼り付けるテストだけでなく、メッセージ、メール、別アプリからリンクを開く場合も確認してください。URLのhost・scheme・pathがManifestの範囲と一致しているかが重要です。

Android App Linksが開かない時にHTTPS、Manifest、assetlinks.json、署名fingerprintを順番に確認する診断フロー
開かない場合は、URL・Manifest・Web側JSON・署名を上から分けて確認します。

開かない時の原因別チェックリスト

症状・原因候補確認する場所対処
HTTPや別hostへリダイレクトされるブラウザー、Webサーバーの応答最初から正しいHTTPS hostへ接続し、リダイレクトを減らす
autoVerifyがない・誤記最終的なAndroidManifest.xmlintent filter、scheme、host、exportedを確認
assetlinks.jsonが404・HTMLを返す/.well-known/assetlinks.json配置場所、公開権限、Content-Type、リダイレクトを確認
package_nameが違うGradleのapplication IDとJSONflavorやapplication ID suffixを含めて一致させる
SHA-256が違うdebug/release証明書、Play Console配布形態に対応する署名証明書を登録する
pathがManifestの範囲外タップしたURLとintent filterhost・pathPrefix・動的ルールの範囲を比較する
端末に古い検証状態が残る端末のApp Links設定と検証結果再検証し、必要ならアプリを再インストールして比較する
アプリは開くが目的画面にならないActivityのintent処理URIのpath・queryを読み、入力値を検証して遷移する

Android 15以降のDynamic App Links

Android 15(API 35)以降では、assetlinks.jsonに動的なURLルールを追加し、path・query・fragmentなどの扱いをサーバー側で細かく調整できます。キャンペーンURLや期間限定ページの除外など、アプリ更新なしでルールを調整したい場合に役立ちます。

ただし、サーバー側のdynamic ruleはManifestが宣言した範囲を広げられません。Manifest側が許可した最大範囲の中で、サーバー側ルールが絞り込む関係です。Android 14(API 34)以下ではDynamic App Linksの高度なpath・query設定が同じようには適用されず、従来のManifest設定へ戻るため、旧OSの挙動も確認してください。

つまり、Dynamic App Linksは通常App Linksの代替ではなく、その関連付けを新しいOS向けに運用しやすくする拡張です。まず通常のApp Linksを動かし、対象OSとURLルールを整理してから導入します。

どの方式を選ぶべきか

  • アプリ内画面への入口だけが必要:通常のDeep Linkから検討します。
  • 自社Web URLを安全にアプリへ渡したい:App Linksを選び、HTTPS・assetlinks.json・署名を運用します。
  • Android 15以降向けにURL範囲をサーバーで調整したい:App Linksを基礎にDynamic App Linksを追加します。
  • debugとreleaseで対象ドメインや署名が違う:ビルドvariant、公開JSON、fingerprintを分けて管理します。

関連するAndroid公開設定との違い

App LinksはURLとアプリを関連付ける設定で、Google PlayのversionCodeやアプリ署名そのものを置き換えるものではありません。Google Play公開時のバージョン管理はversionCode / versionNameの記事、暗号化されていないHTTP通信の切り分けはCleartext HTTPの記事も参照してください。App Linksのfingerprintを確認する際は、配信用の署名鍵とupload keyの役割を混同しないことが重要です。

FAQ

Q. App LinksとDeep Linkは同じですか?

同じではありません。App LinksはDeep Linkの仕組みを使いながら、Webサイトとアプリの関連付けをDigital Asset Linksで検証する方式です。

Q. assetlinks.jsonはどこに置きますか?

対象ドメインの https://ドメイン/.well-known/assetlinks.json です。複数hostを使う場合はhostごとに確認します。

Q. fingerprintはdebug keystoreのものですか?

実際に検証したいビルドの署名証明書を使います。Play App Signingで配布するrelease版なら、Play Consoleのapp signing certificateを確認します。

Q. android:autoVerify="true"だけでアプリは開きますか?

いいえ。Manifest、HTTPS、host、assetlinks.json、package name、署名fingerprint、URLのpathがそろって初めて検証できます。

Q. assetlinks.jsonを直したのにすぐ反映されません。

端末側に検証結果が保持されている可能性があります。再検証コマンドや再インストールを使って確認し、OSバージョンごとの検証タイミングも分けて考えます。

まとめ

Android App Linksは、Web URLをAndroidアプリへ直接つなぐための、検証付きDeep Linkです。実装では、Manifestのintent filterとandroid:autoVerify、Web側の/.well-known/assetlinks.json、正しいpackage nameとSHA-256 certificate fingerprintをそろえます。

開かない時は、まずHTTPSとリダイレクト、次にhost・path、assetlinks.jsonの公開状態、最後にdebug/releaseやPlay App Signingの署名を確認してください。Android 15以降のDynamic App Linksは、Manifestの範囲内でURLルールをサーバー側から細かく調整するための拡張です。

公式情報