Android 使用Trusted Web Activity打包H5页面

1,639 阅读2分钟

在日常工作中,偶尔会遇到将H5页面打包为App的需求,通常会使用WebView来实现。本文介绍官方提供的另一种实现方式Trusted Web Activity

官方文档

Trusted Web Activity 简介

Trusted Web Activity(简称TWA),使用基于Chrome Custom Tab的协议打开H5页面。TWAWebView最大的不同之处在于TWA会通过Digital Asset Links验证打开的网页和App的所有者是否为同一开发者。验证不通过时,页面会显示Custom Tab的导航栏,验证通过时,导航栏可以隐藏。

注意:TWA在Android版Chrome 72及以上版本可用。当设备上的Chrome版本不支持TWA时,会使用普通的Custom Tab打开网页。

添加库

在app module下的build.gradle中添加代码,如下:

android {
    ...
    compileOptions {
       sourceCompatibility JavaVersion.VERSION_1_8
       targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    implementation 'com.google.androidbrowserhelper:androidbrowserhelper:2.4.0'
}

使用TWA

配置Manifest

AndroidManifest中配置LauncherActivity,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <application 
        ...
        >
        <activity
            android:name="com.google.androidbrowserhelper.trusted.LauncherActivity"
            android:exported="true">

            <!--配置打开的网页-->
            <meta-data
                android:name="android.support.customtabs.trusted.DEFAULT_URL"
                android:value="https://go.minigame.vip" />

            <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="go.minigame.vip"
                    android:scheme="https" />
            </intent-filter>
        </activity>
    </application>
</manifest>

效果如图:

device-2023-05-14-09 -middle-original.gif

配置Digital Asset Links

通过Digital Asset Links验证后,打开的页面可以隐藏导航栏。接下来介绍如何配置与测试Digital Asset Links

生成assetlinks.json

通过Android Studio自带的插件App Links Assistant辅助生成。

  • 在插件管理中启用App Links Assistant

企业微信截图_16840273766398.png

  • 在顶部功能栏中,选择Tools->App Links Assistnat打开插件页面。

屏幕截图 2023-05-14 092726.png

  • 在插件页面中选择open generator,生成并保存assetlinks.json文件。

企业微信截图_1684028141656.png

  • 将生成的assetlinks.json文件放到 https://domain/.well-known/路径下。

  • AndroidManifest中配置autoVerify

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <application 
        ...
        >
        <activity
            android:name="com.google.androidbrowserhelper.trusted.LauncherActivity"
            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:host="go.minigame.vip"
                    android:scheme="https" />
            </intent-filter>
        </activity>
    </application>
</manifest>

调试模式

如果无法配置assetlinks.json文件,可以通过调试模式进行测试。

  • res/values/strings中创建asset_statements,在AndroidManifest中配置。

strings

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="asset_statements">
        [{
            "relation": ["delegate_permission/common.handle_all_urls"],
            "target": {
                "namespace": "web",
                "site": "https://go.minigame.vip"}
        }]
    </string>
</resources>

AndroidManifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <application 
        ...
        >
        
        <meta-data
            android:name="asset_statements"
            android:resource="@string/asset_statements" />
        
        <activity
            android:name="com.google.androidbrowserhelper.trusted.LauncherActivity"
            android:exported="true">

           ...

            <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="go.minigame.vip"
                    android:scheme="https" />
            </intent-filter>
        </activity>
    </application>
</manifest>
  • 在Chrome浏览器中打开chrome://flags页面,搜索Enable commandline on not-rooted devices,配置为Enable并重启浏览器。
Screenshot_20230514_100222.png
  • 使用adb命令,关闭验证网站,并重启App。
adb shell "echo '_ --disable-digital-asset-link-verification-for-url="https://go.minigame.vip"' > /data/local/tmp/chrome-command-line"

注意:如果以上步骤执行完后仍然提示验证失败,清除Chrome的缓存后再尝试。

效果如图:

device-2023-05-14-10 -middle-original.gif

个性化配置

androidbrowserhelper库支持一些个性化配置,例如启动页、沉浸式、启动时网页的方向等,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application tools:ignore="MissingApplicationIcon">

        ...

        <activity
            android:name="com.google.androidbrowserhelper.trusted.LauncherActivity"
            android:exported="true">

            ...

            <!--配置状态栏的颜色-->
            <meta-data
                android:name="android.support.customtabs.trusted.STATUS_BAR_COLOR"
                android:resource="@color/purple_200" />

            <meta-data
                android:name="android.support.customtabs.trusted.STATUS_BAR_COLOR_DARK"
                android:resource="@color/purple_500" />
            <!--配置状态栏的颜色-->

            <!--配置导航栏的颜色-->
            <meta-data
                android:name="android.support.customtabs.trusted.NAVIGATION_BAR_COLOR"
                android:resource="@color/purple_200" />

            <meta-data
                android:name="android.support.customtabs.trusted.NAVIGATION_BAR_COLOR_DARK"
                android:resource="@color/purple_500" />
            <!--配置导航栏的颜色-->

            <!--配置沉浸式页面 immersive、sticky-immersive-->
            <meta-data
                android:name="android.support.customtabs.trusted.DISPLAY_MODE"
                android:value="immersive" />

            <!--配置启动时网页方向 portrait、landscape-->
            <meta-data
                android:name="android.support.customtabs.trusted.SCREEN_ORIENTATION"
                android:value="portrait" />

            <!--配置启动页-->
            <!--配置启动页图标-->
            <meta-data
                android:name="android.support.customtabs.trusted.SPLASH_IMAGE_DRAWABLE"
                android:resource="@drawable/google" />

            <!--配置启动页背景颜色-->
            <meta-data
                android:name="android.support.customtabs.trusted.SPLASH_SCREEN_BACKGROUND_COLOR"
                android:resource="@color/color_FFD200" />
            
            <!--配置启动页显示持续时长-->
            <meta-data
                android:name="android.support.customtabs.trusted.SPLASH_SCREEN_FADE_OUT_DURATION"
                android:value="300" />

            <meta-data
                android:name="android.support.customtabs.trusted.FILE_PROVIDER_AUTHORITY"
                android:value="com.chenyihong.exampledemo.twaprovider" />
            <!--配置启动页-->
            
            ...
        </activity>

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.chenyihong.exampledemo.twaprovider"
            android:exported="false"
            android:grantUriPermissions="true">

            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/twa_filepaths" />
        </provider>
    </application>
</manifest>

效果如图:

device-2023-05-14-15 -original-original.gif

示例

演示代码已在示例Demo中添加。

ExampleDemo github

ExampleDemo gitee