Android App Linksを開発環境で動作検証する方法

### 本記事の概要

Android App Linksとは、HTTP(S)をスキーマとするURLをクリックした際に、対応するAndroidアプリをシームレスに (どのアプリで開くかをダイアログで選択する必要なく) 立ち上げることを可能にする手法である。 

https://developer.android.com/training/app-links#android-app-links

App Linksの導入方法に関しては、公式ドキュメントに詳しく書かれている。一方で、開発環境でApp Linksの動作確認を行う方法は明記されていない、かつやや煩雑である。

そこで本記事では、App Linksを開発環境で動作検証する際に、私が使用した方法を紹介する。大まかには以下の5ステップの作業が必要となる。

1. ローカルでのビルド時に使用される証明書のSHA256 fingerprintを入手する。
2. 上記のfingerprintを使用し、ローカル用のassetlinks.jsonを作成する。
3. Node.js (Express) 製のサーバーとngrokを使用し、ローカルからassetlinks.jsonをHTTPSで配布する。
4. ngrokが生成するホスト名をmanifestに記載する。
5. ngrokのURLをクリックし、App Linksが機能することを確認する。

ただし、App Links自体の設定方法に関しては知っているものとする。必要に応じて、公式ドキュメントないし別の記事をご参照いただきたい。

### 1. ローカルでのビルド時に使用される証明書のSHA256 fingerprintを入手する

まず前提として、AndroidアプリのAPKは、デジタル証明書により署名される ([Ref](https://developer.android.com/studio/publish/app-signing))。
Android App Linksを利用する際には、ドメインの/.wellknownディレクトリ下に`assetlinks.json`と称されるJSONファイルを配置する必要があるが、このファイル中に、リリース時に使用される証明書のfingerprintを記載する必要がある。

開発環境でのビルド時とリリースビルド時とで使用される証明書が異なるため、リリースビルド用に配置された`assetlinks.json`は、開発環境でビルドされたアプリとはfingerprintが合致しない。ゆえに、開発環境で動作確認する際には、開発環境用の`assetlinks.json`を作成する必要がある。

開発環境でのビルド時に使用される証明書のfingerprintは、以下のコマンドで確認することができる。`SHA256:`に続けて表示されるfingerprintを使用する。

```bash
keytool -list -v -keystore ~/.android/debug.keystore
```

### 2. 上記のfingerprintを使用し、ローカル用のassetlinks.jsonを作成する

開発環境用の`assetlinks.json`を作成する。以下の`hash_of_app_certificate`に、1.で確認したfingerprintを記載する。

https://developers.google.com/digital-asset-links/v1/getting-started

```json
[
    {
        "relation": [
            "delegate_permission/common.handle_all_urls"
        ],
        "target": {
            "namespace": "android_app",
            "package_name": "com.example.app",
            "sha256_cert_fingerprints": [
                "hash_of_app_certificate"
            ]
        }
    }
]
```

### 3. Node.js (Express) 製のサーバーとngrokを使用し、ローカルからassetlinks.jsonをHTTPSで配布する

App Linksを正しく機能させるためには、`assetlinks.json`をHTTPSで配布する必要がある。そこで、私はNode.js (Express) 製のサーバーとngrokを使用した。

まず、Expressを使用して、`assetlinks.json`をHTTPで配布する。
```index.js
const express = require('express');
const server = express();

server.get('/.well-known/assetlinks.json', function(request, response) {
  response.sendFile(__dirname +  '/well-known/assetlinks.json');
});

server.listen(9999);
```

上の例の場合、`node index.js`でサーバーを起動したのち、`http://localhost:9999/.well-known/assetlinks.json`にアクセスすると、`assetlinks.json`が返ってくるはずである。

続いて、ngrokを利用して、これをHTTPSで公開する。ngrokのダウンロードおよび詳しい使用方法に関しては、他の記事ないし公式ドキュメントをご参照いただきたい。

https://ngrok.com

以下のコマンドを実行すると、`localhost:9999`をHTTPSのURLとして公開することができる。
```bash
ngrok http 9999
```

コマンド実行後、以下のように表示される。
```bash
Forwarding                    https://8312-2001-268-c201-1020-5534-12d5-3272-319e.jp.ngrok.io -> http://localhost:9999
```

この例の場合、`https://8312-2001-268-c201-1020-5534-12d5-3272-319e.jp.ngrok.io/.well-known/assetlinks.json`にアクセスすると、`assetlinks.json`が返ってくるはずである。これで、`assetlinks.json`をHTTPSで公開することができた。

### 4. ngrokが生成するホスト名をmanifestに記載

続いて、ngrokによって生成されたホスト名とAndroidアプリとを連携させるため、Androidアプリにも少々手を加える。

以下に、`AndroidManifest.xml`の一部を例示する。`android:host`の値を、実際にApp Linksに使用するホスト名から、ngrokによって生成されたホスト名に書き換える。

```xml
<activity
    android:name="com.example.android.ExampleActivity"
    android:label="@string/title_example" >
    <intent-filter android:label="@string/filter_view_example">
        <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="8312-2001-268-c201-1020-5534-12d5-3272-319e.jp.ngrok.io" />
    </intent-filter>
</activity>
```

### 5. ngrokのURLで、App Linksが機能することを確認

Android Emulatorでアプリを起動する。その後、アプリを閉じたのち、コンソールから以下のようなコマンドを実行すると、確認のダイアログを挟むことなく、アプリが起動されるはずである。このコマンドで、URLがクリックされた際の挙動を確認することができる。

```bash
adb shell am start -a android.intent.action.VIEW -d https://8312-2001-268-c201-1020-5534-12d5-3272-319e.jp.ngrok.io
```

また、ngrokでの配布を停止したのち、アプリの再インストールを行ってみると、確認ダイアログが挟まってしまう (App Linksが機能しない) ことも確認できるはずである。

### 最後に

以上、App Linksを開発環境で動作検証する際に、私が使用した方法を紹介した。もしより良い方法をご存知の方がいれば、ぜひご教示いただきたい。