LoginSignup
50
49

More than 5 years have passed since last update.

App Linksに対応してみた

Posted at

AndroidのApp Linksとは

公式情報
https://developer.android.com/training/app-links/

雑な理解としては、1つのサービスに対して、WebとAndroidアプリがある場合に、
Android端末上で別のアプリから https://(自分のWebサイト)... というURLに遷移した場合に、アプリがインストールされてればアプリに遷移する。
といったものです。

実装

今回は、
http://my-android-server.appspot.com/html/list.html?page_no=1&open=2
にアクセスすると、
https://play.google.com/store/apps/details?id=hm.orz.chaos114.android.tumekyouen
のアプリのステージ2の画面が表示されるようにします。

まずは、intent-filterの実装

公式情報
https://developer.android.com/training/app-links/deep-linking

今回は、AndroidManifest.xmlにて下記のように設定しました。

        <activity
            android:name=".modules.initial.InitialActivity"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <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:host="my-android-server.appspot.com"
                    android:pathPrefix="/html/list.html"
                    android:scheme="http"/>
            </intent-filter>
        </activity>

2つ目のintent-filterが、
http://my-android-server.appspot.com/html/list.html から始まるURLが実行された場合、
という意味になります。

ここまでで、下記のコマンドを実行することで、アプリの起動ができました。(シェルによっては、"\が無くてもいいかも。。?)

adb shell am start -W -a android.intent.action.VIEW -d "http://my-android-server.appspot.com/html/list.html?page_no=1\&open=2"

ただ、このままでは、

  • アプリが起動するだけで、対象の画面に遷移しない
  • 起動時にブラウザ or 任意のアプリという選択画面が表示される

という状態になっています。順に解決していきます。

起動時のURLから、任意の画面に遷移させる

公式情報
https://developer.android.com/training/app-links/deep-linking#handling-intents

intent-filterを追加したActivityにて、getIntentの戻り値を利用して遷移を行います。

ここはアプリによって大きく変わってくるかと思います。
基本的には、getIntent().getData()をとってみて、nullだったら通常の遷移、値が入っていたらURLを解析して対象の画面に遷移させる形になるかと。

今回は https://github.com/noboru-i/kyouen-android/commit/362ccff367b4bc24ac91b5c2abd9c130b34abee8#diff-ae9d6323f6b1c38043ae5931c6049b56 のように実装しました。

アプリ選択画面をスキップさせる

公式情報
https://developer.android.com/training/app-links/verify-site-associations

ここが今回の本題です。

まずは、Android側のintent-filterに android:autoVerify="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:host="my-android-server.appspot.com"
                    android:pathPrefix="/html/list.html"
                    android:scheme="http"/>
            </intent-filter>

次に、サーバ側。
公式情報
https://developer.android.com/training/app-links/verify-site-associations#web-assoc
https://www.google.co.jp/.well-known/assetlinks.json のように、他の有名ドメインのものは参考にできそうです。)

.well-known/assetlinks.json というファイルを作成し、内部を以下のようにしました。

[
    {
        "relation": ["delegate_permission/common.handle_all_urls"],
        "target": {
            "namespace": "android_app",
            "package_name": "hm.orz.chaos114.android.tumekyouen.debug",
            "sha256_cert_fingerprints":
            ["C0:D7:F9:34:D8:F7:15:06:FA:21:FA:0D:CF:09:E5:C4:E2:66:D4:11:5D:72:E0:D7:B8:38:F9:49:AB:C7:A4:F0"]
        }
    },
    {
        "relation": ["delegate_permission/common.handle_all_urls"],
        "target": {
            "namespace": "android_app",
            "package_name": "hm.orz.chaos114.android.tumekyouen",
            "sha256_cert_fingerprints":
            ["6E:5A:DB:69:B4:C3:28:AC:DA:7F:00:A7:4D:5D:CD:F9:ED:87:0B:5D:D2:71:C5:89:64:DF:13:38:5A:5B:B8:A2"]
        }
    }
]

まず、公式情報にあるサンプルをコピーし、debug用のpackage名と本番用のpackage名を適用しました。
その後、各keystoreに対して、 keytool -list -v -keystore app/cert/debug.keystore などを実行し、 SHA256 の結果を貼り付けました。

これを、 https://my-android-server.appspot.com/.well-known/assetlinks.json としてアクセスできるようにします。

今回はサーバサイドがGAE上で動いているので、 https://github.com/noboru-i/kyouen-python/pull/18/files のように設定しました。
.well-known/assetlinks.json というファイルをそのまま転送しようとしたら Directory matches ignore regex. と言われてアップロードできなかったので、物理的には well-known/assetlinks.json に変更して、app.yamlの設定でアクセス先を変えました。)

https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://my-android-server.appspot.com&relation=delegate_permission/common.handle_all_urls にアクセスし、

"debugString": "********************* ERRORS *********************\nNone!...

と返却されることを確認しました。

これで、再度、

adb shell am start -W -a android.intent.action.VIEW -d "http://my-android-server.appspot.com/html/list.html?page_no=1\&open=2"

を実行すると、今まではダイアログでアプリ選択が出ていたのですが、今回は何も聞かれずに対象のアプリ画面が表示されました。

動作確認

上記の対応を行い、Play Storeにアプリを公開しました。

https://twitter.com/noboru_i/status/1028173855754346496
このツイートをTwitterアプリで開き、URLをタップすると、ダイアログが表示されずにステージ2の画面が表示されました。

capture.gif

50
49
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
49