くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

NuxtアプリをPWAでGoogle Storeにリリースする

以前作ったNuxtアプリをPWAでリリースしてみたときの備忘録。

play.google.com

コード量自体は少ないけど、いろいろ迷ったのでメモ。

PWA? TWA?

プッシュ通知などができるようになるPWA(Progressive Web App)でWebサービスを作ることが増えてきた。

Androidアプリだと、TWA(Trusted Web Activity)というのを使うと、PWAをアプリとして配信できるらしい。

公式だとこのあたりに。
はじめてのプログレッシブウェブアプリ  |  Web Fundamentals  |  Google Developers
Trusted Web Activity Integration Guide  |  Web On Android

PWAはWebアプリのことで、TWAはAndroidのActivityのことらしい。
PWA化されているWebアプリにAndroidアプリの署名証明書を紐付けることで、 このWebアプリが 信頼されたもの(Trusted) として、Activityで開いてくれるようになる。

動き的には、customtabsでWebサイトを開いた感じと変わりないけど、
アプリのアイコンやスプラッシュ画像を設定できたり、ナビゲーションバーの色を変えたりできる。

ただ、TWA対応をすることで、customtabsのURLバーがなくなるのでアプリっぽくなる。

Android側の設定

アプリを公開するので、Androidアプリを用意する。
JavaもKotlinも書かず、AndroidManifest.xmlとbuild.gradleの編集だけ。
(なので、Javaで設定)

公式のガイドを読んでいくとだいたいできる感じ。
あとは、サンプルコードが公開されているので、適宜参照した。

1. Android Studioでプロジェクト作成

まずは、プロジェクト作成。

Activityは作らないので「Add No Activity」を選ぶ。

言語を「Java」にしてFinish

f:id:wannabe-jellyfish:20200707115834p:plain

2. app/build.gradleの設定

app/build.gradleの中身はこんな感じ。

やってることとしては、以下の2つ。

  1. サポートライブラリの追加(androidbrowserhelper)
  2. 各種文字列リソースの生成(resValue関連)

他の記事だと、文字列リソースの生成はせず、string.xmlに設定してることが多いけど、
サンプルコードだとこれを使ってたので、こっちにしてみてる。

// app/build.gradle
apply plugin: 'com.android.application'

// 生成する文字列の元情報
def twaManifest = [
        hostName : 'kabu-reco.app',
        launchUrl: '/',
]

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "jp.memorylovers.kabureco"
        minSdkVersion 23
        targetSdkVersion 29
        versionCode 4
        versionName "1.0.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        // ** string.xmlの生成
        // ホスト名
        resValue "string", "host_name", twaManifest.hostName

        // サイトのURL
        def launchUrl = "https://" + twaManifest.hostName + twaManifest.launchUrl
        resValue "string", "launch_url", launchUrl
        resValue "string", "cros_launch_url", launchUrl

        // TWA化に必要なasset_statementsの情報
        resValue "string", "asset_statements", """
            [{
                "relation": ["delegate_permission/common.handle_all_urls"],
                "target": {
                    "namespace": "web",
                    "site": "https://$twaManifest.hostName"
                }
            }]"""
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    // Java8を指定。TWAはJava8のみ。
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // TWAのサポートライブラリを追加
    implementation 'com.google.androidbrowserhelper:androidbrowserhelper:1.1.0'
}

3. AndroidManifest.xmlの設定

AndroidManifest.xmlはこんな感じ。

長いけど、サポートライブラリのActivityを使って、各種設定している感じ。

これも、サンプルコードから抜粋して設定した感じ。

サンプルコードを見ると、色とか画像とかの設定できる項目がわかる。
(というか、ここ以外になさそう。。?)

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="jp.memorylovers.kabureco">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!-- ここから下を追加 -->
        <meta-data
            android:name="asset_statements"
            android:resource="@string/asset_statements" />
        <meta-data
            android:name="cros_web_alternative"
            android:value="@string/cros_launch_url" />

        <activity
            android:name="com.google.androidbrowserhelper.trusted.LauncherActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.LauncherActivity">

            <!-- TWAとして起動するURL -->
            <meta-data
                android:name="android.support.customtabs.trusted.DEFAULT_URL"
                android:value="@string/launch_url" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <!-- ステータスバーの色 -->
            <meta-data
                android:name="android.support.customtabs.trusted.STATUS_BAR_COLOR"
                android:resource="@color/colorPrimary" />

            <!-- ナビゲーションバーの色 -->
            <meta-data
                android:name="android.support.customtabs.trusted.NAVIGATION_BAR_COLOR"
                android:resource="@color/navigationColor" />

            <!-- 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="@string/host_name" android:scheme="https" />
            </intent-filter>
        </activity>

        <activity android:name="com.google.androidbrowserhelper.trusted.FocusActivity" />
    </application>

</manifest>

4. アプリをストアにアップロードする

Webアプリ(PWA)側の設定の前に、まずは一度ストアにアップロードする。

アプリの公開準備ができると、「アプリの署名」が確認できるようになるので、
その情報を使って、Webアプリの設定をする

f:id:wannabe-jellyfish:20200707115948p:plain

Webアプリ(PWA)側の設定

このWebアプリが信頼できることを示すために、
アプリの署名に表示されるフィンガープリントを含めて /.well-known/assetlinks.jsonとして配置する必要がある。

ファイルの内容を自動生成してくれるツールがあるので、それを利用する。

Statement List Generator and Tester  |  Google Digital Asset Links

こんな感じ。フィンガープリントは、先頭のSHA256:を除いて入力するので注意

f:id:wannabe-jellyfish:20200707120016p:plain

あとは、表示された内容を/.well-known/assetlinks.jsonとして配置してWebアプリを更新する。

実機で確認してみる

アルファ版などでクローズドでリリースして確認してみる。

ここでかなりハマる。。デバッグモードがONの端末で確認すると、アドレスバーが消えない。。

ドキュメントを見てみると、設定しないといけないらしい。。 ・Enable debug mode

  1. Chromeを開いて、chrome://flagsにアクセス
  2. Enable command line on non-rooted devicesを検索
  3. ENABLEDにして有効化する
  4. 次に、adbを使って、以下を実行する shell adb shell "echo '_ --disable-digital-asset-link-verification-for-url=\"https://airhorner.com\"' > /data/local/tmp/chrome-command-line"

これで、デバッグモードの端末でもアドレスバーが消えて表示されるように。。(´ω`)
これは罠。。(´ω`)

確認して、問題なさそうであればリリース!意外と早かった(´ω`)

ハマったところまとめ

主にハマったのは、以下の2点

  1. /.well-known/assetlinks.jsonのフィンガープリントは、先頭のSHA256:を除く
  2. デバッグモードがONの端末で確認するときは、設定が必要

とはいえ、一度できると、量産できそう(´ω`) 以上!!

参考にしたサイトさま