PWA (渐进式 Web 应用) 已经存在一段时间了。 然而,每次我尝试向客户解释它时,都会出现同样的问题:“我的用户能否使用应用商店安装该应用?” 答案传统上是否定的,但这种情况随着 Chrome 72 的发布而改变,Chrome 72 发布了一个名为 TWA (可信 Web 活动) 的新功能。
可信 Web 活动 是一种新的方式,可使用基于自定义选项卡的协议,将您的 Web 应用内容(如您的 PWA)与您的 Android 应用集成在一起。
在本文中,我将使用 Netguru 的现有 PWA (Wordguru),并逐步说明需要做什么才能使该应用可用,并使其可以直接从 Google Play 应用商店安装。
我们在此处介绍的一些内容对于任何 Android 开发人员来说可能听起来很愚蠢,但这篇文章是从前端开发人员的角度撰写的,尤其是那些从未使用过 Android Studio 或创建过 Android 应用的人。 此外,请注意,我们在此处介绍的许多内容仍然处于实验阶段,因为它仅限于 Chrome 72。
步骤 1:设置可信 Web 活动
设置 TWA 不需要您编写任何 Java 代码,但您需要安装 Android Studio。 如果您以前开发过 iOS 或 Mac 软件,那么这与 Xcode 非常相似,因为它提供了一个友好的开发环境,旨在简化 Android 开发。 因此,请获取它,然后回到这里与我见面。
在 Android Studio 中创建一个新的 TWA 项目
您是否获得了 Android Studio? 好吧,我实际上听不见也看不见你,所以我假设你已经有了。 请继续打开它,然后点击“开始一个新的 Android Studio 项目”。 从那里,让我们选择“添加无活动”选项,该选项允许我们配置项目。
配置相当简单,但了解什么是什么是很重要的
- 名称 应用的名称(但我敢肯定你已经知道了)。
- 包名称: 标识符 用于 Play 商店 上的 Android 应用。 它必须是唯一的,因此我建议使用 PWA 的 URL 倒序(例如
com.netguru.wordguru
)。 - 保存位置: 项目将在本地存在的位置。
- 语言: 这允许我们选择一种特定的代码语言,但由于我们的应用已经编写好了,所以没有必要这样做。 我们可以将其保留为 Java,它是默认选择。
- 最低 API 级别: 这是我们正在使用的 Android API 版本,支持库需要它(我们将在下面介绍)。 让我们使用 API 19。
这些选项下面有一些复选框。 这些与我们这里无关,因此请将它们全部取消选中,然后继续进行“完成”。

添加 TWA 支持库
支持库是 TWA 所必需的。 好消息是我们只需要修改两个文件来满足该要求,这两个文件都在同一个项目目录中:Gradle Scripts
。 两者都名为 build.gradle
,但我们可以通过查看括号中的描述来区分它们。

有一个名为 JitPack 的 Git 包管理器专门为 Android 应用而设计。 它非常强大,但最重要的是它使发布我们的 Web 应用变得轻而易举。 它是一项付费服务,但如果这是您第一次将内容放入 Google Play 商店,那么我认为它是值得的。
编辑注: 这不是对 JitPack 的赞助宣传。 值得一提的是,因为这篇文章假设对 Android 应用或将应用提交到 Google Play 几乎没有或没有了解,并且它为管理直接连接到商店的 Android 应用仓库提供了更少的摩擦。 也就是说,这完全不是必需的。
进入 JitPack 后,让我们将项目连接到它。 打开我们刚刚查看的 build.gradle (Project: Wordguru)
文件,并告诉它查看 JitPack 以获取应用仓库
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
...
}
}
好的,现在让我们打开另一个 build.gradle
文件。 这里我们可以添加项目所需的任何依赖项,并且我们确实有一个
// build.gradle (Module: app)
dependencies {
...
implementation 'com.github.GoogleChrome:custom-tabs-client:a0f7418972'
...
}
TWA 库使用 Java 8 功能,因此我们需要启用 Java 8。 为此,我们需要将 compileOptions
添加到同一个文件
// build.gradle (Module: app)
android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
...
}
还有一些名为 manifestPlaceholders
的变量,我们将在下一节中介绍。 现在,让我们添加以下内容以定义应用的托管位置、默认 URL 和应用名称
// build.gradle (Module: app)
android {
...
defaultConfig {
...
manifestPlaceholders = [
hostName: "wordguru.netguru.com",
defaultUrl: "https://wordguru.netguru.com",
launcherName: "Wordguru"
]
...
}
...
}
在 Android 应用清单中提供应用详细信息
每个 Android 应用都有一个 Android 应用清单 (AndroidManifest.xml
),它提供了有关应用的基本详细信息,例如它绑定的操作系统、包信息、设备兼容性以及许多其他有助于 Google Play 显示应用要求的内容。
我们真正关心的是 Activity (<activity>
)。 这就是实现用户界面以及“可信 Web 活动”中“活动”所必需的。
有趣的是,我们在 Android Studio 中设置项目时选择了“添加无活动”选项,这是因为我们的清单为空,只包含应用程序标记。
让我们从打开清单文件开始。 我们将用自己的应用程序 ID 替换现有的 package
名称,并将 label
替换为我们在上一节中定义的 manifestPlaceholders
变量中的值。
然后,我们将通过在 <application>
标记内添加 <activity>
标记来实际添加 TWA 活动。
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.netguru.wordguru"> // highlight
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="${launcherName}" // highlight
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name="android.support.customtabs.trusted.LauncherActivity"
android:label="${launcherName}"> // highlight
<meta-data
android:name="android.support.customtabs.trusted.DEFAULT_URL"
android:value="${defaultUrl}" /> // highlight
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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="${hostName}"/> // highlight
</intent-filter>
</activity>
</application>
</manifest>
就这样,朋友们,这就是步骤 1。 让我们继续进行步骤 2。
步骤 2:验证网站和应用之间的关系
TWA 需要 Android 应用和 PWA 之间的连接。 为此,我们使用 数字资产链接。
连接必须在两端设置,其中 TWA 是应用,而 PWA 是网站。
为了建立这种连接,我们需要再次修改我们的 manifestPlaceholders
。 这次,我们需要添加一个名为 assetStatements
的额外元素,它保存有关我们的 PWA 的信息。
// build.gradle (Module: app)
android {
...
defaultConfig {
...
manifestPlaceholders = [
...
assetStatements: '[{ "relation": ["delegate_permission/common.handle_all_urls"], ' +
'"target": {"namespace": "web", "site": "https://wordguru.netguru.com"}}]'
...
]
...
}
...
}
现在,我们需要在 application
标记中添加一个新的 meta-data
标记。 这将通知 Android 应用我们希望与 manifestPlaceholders
中指定的应用建立连接。
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="${packageId}">
<application>
...
<meta-data
android:name="asset_statements"
android:value="${assetStatements}" />
...
</application>
</manifest>
就这样! 我们刚刚建立了应用到网站的关系。 现在让我们进入网站到应用的转换。
为了在反方向建立连接,我们需要创建一个 .json
文件,该文件将在应用的 /.well-known/assetlinks.json
路径中可用。 该文件可以使用内置于 Android Studio 的生成器创建。 看看,我告诉过你 Android Studio 有助于简化 Android 开发!
我们需要三个值来生成该文件
- 托管网站域: 这是我们的PWA URL(例如
https://wordguru.netguru.com/
)。 - 应用包名称: 这是我们的 TWA 包名称(例如
com.netguru.wordguru
)。 - 应用包指纹 (SHA256): 这是基于 Google Play 商店密钥库生成的唯一密码哈希。
我们已经有了第一个和第二个值。 我们可以使用 Android Studio 获取最后一个值。
首先,我们需要生成签名的 APK。 在 Android Studio 中,转到:构建 → 生成签名捆绑包或 APK → APK。

接下来,使用现有的密钥库,如果您已经有一个。 如果您需要一个,请先转到“新建…”。
然后让我们填写表单。 确保记住凭据,因为这些凭据是应用将用其签名的凭据,并且它们确认您对该应用的所有权。

这将创建一个密钥库文件,该文件是生成应用包指纹 (SHA256) 所必需的。 此文件极其重要,因为它作为您是该应用所有者的证明。 如果此文件丢失,您将无法对商店中的应用进行任何进一步的更新。
接下来,让我们选择捆绑包的类型。在本例中,我们选择“发布”,因为它为我们提供了一个生产捆绑包。我们还需要检查签名版本。

这将生成我们的 APK,该 APK 将在稍后用于在 Google Play 商店中创建发布版。创建密钥库后,我们可以使用它来生成所需的应用程序包指纹(SHA256)。
让我们回到 Android Studio,然后转到 工具 → 应用程序链接助手。这将打开一个侧边栏,其中显示了在应用程序和网站之间创建关联所需的操作步骤。我们希望转到步骤 3,“声明网站关联”,并填写所需数据:网站域
和应用程序 ID
。然后,选择在上一步中生成的密钥库文件。

填写表单后,点击“生成数字资产链接文件”,这将生成我们的assetlinks.json
文件。如果我们打开它,它应该看起来像这样
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.netguru.wordguru",
"sha256_cert_fingerprints": ["8A:F4:....:29:28"]
}
}]
这是我们需要在应用程序的/.well-known/assetlinks.json
路径中提供该文件。我不会介绍如何在该路径上提供它,因为它太具体于项目了,超出了本文的范围。
我们可以通过点击“链接并验证”按钮来测试关系。如果一切顺利,我们将收到带有“成功!”的确认信息。

耶!我们已经建立了 Android 应用程序和我们的PWA之间的双向关系。从这里开始就一路下坡了,所以让我们把它完成。
步骤 3:获取所需资产
Google Play 需要一些资产来确保应用程序在商店中得到很好的展示。具体来说,我们需要以下内容
- 应用程序图标:我们需要各种尺寸,包括 48×48、72×72、96×96、144×144、192×192……或者我们可以使用自适应图标。
- 高分辨率图标:这是一个 512×512 PNG 图像,在整个商店中使用。
- 功能图形:这是一个 1024×500 JPG 或 24 位 PNG(无 Alpha)横幅,Google Play 在应用程序详细信息视图中使用。
- 屏幕截图:Google Play 将使用这些截图来展示应用程序的不同视图,用户可以在下载应用程序之前查看。

拥有所有这些内容后,我们可以继续使用Google Play 商店开发者控制台发布应用程序!
步骤 4:发布到 Google Play!
让我们进入最后一步,并将我们的应用程序最终推送到商店。
使用我们之前生成的 APK(位于AndroidStudioProjects
目录中),我们需要转到Google Play 控制台以发布我们的应用程序。我不会介绍在商店中发布应用程序的过程,因为向导使其非常简单,并且我们在整个过程中会得到逐步指导。
应用程序可能需要几个小时才能完成审核和批准,但批准后,它将最终显示在商店中。
如果找不到 APK,可以通过转到 构建 → 生成签名捆绑包/APK → 构建 APK,传递我们现有的密钥库文件并填写我们在生成密钥库时使用的别名和密码来创建一个新的 APK。生成 APK 后,应该会显示一条通知,并且可以通过点击“定位”链接来获取该文件。
恭喜,您的应用程序已在 Google Play 上架!
就这样!我们刚刚将我们的PWA推送到 Google Play 商店。这个过程不像我们希望的那样直观,但只要付出一点努力,它绝对是可行的,相信我,当你看到你的应用程序在野外展示时,它会给你带来极大的满足感。
值得注意的是,此功能仍然处于早期阶段,我将它视为一段时间的实验性功能。我不建议现在发布应用程序的生产版本,因为这仅适用于 Chrome 72 及更高版本——之前的任何版本都能够安装该应用程序,但应用程序本身会立即崩溃,这不是最好的用户体验。
此外,custom-tabs-client
的官方版本尚不支持TWA。如果您想知道为什么我们使用原始 GitHub 链接而不是官方库版本,那就是原因。
“不像直观”?这简直是荒谬。PWA 的卖点是“轻松安装”,我们不必经历所有这些官僚主义的编码垃圾(是的,垃圾,我尽量保持礼貌)才能发布东西。
所有这些都是不必要的。你只需要将 PWA 的 URL 提供给某个“PWA 商店”,就应该可以了。就是这样。
剩下的都是 Google 明显的懒惰,告诉我们继续使用他们强加给我们的糟糕做法,而不是他们改变自己的做法。
然而,他们拥有所有资金,而不是我们,对吧?当他们拥有全世界所有的资金来改变自己的做法时,为什么我们要花更多时间来适应他们的模式呢?
是时候对这种发布方式说不。PWA 应该关注“这是清单,这是服务工作者,这是我的图标,即时应用程序”,而 Google 的 Play/Android 团队告诉我们任何与之相反的事情,就是他们背叛了他们在过去三年(自从他们从 Chrome 网上应用店中删除“Chrome 应用程序”以来)一直在推动的 PWA 愿景。
是时候说不。是时候有人发明一个更好的 PWA 商店了。
太棒了……那么 Windows 商店和 iOS 商店呢?
我只是来这里说这个。谢谢!
先生,你应该得到一块饼干!你绝对是正确的!这是继 AMP 之后 Google 又一个愚蠢的想法。
伙计,我完全同意你!
真不敢相信我竟然也这么想,但事实就是如此!
我试了一下,但遇到了以下错误。你知道为什么吗?
错误:无法解析:com.github.GoogleChrome:custom-tabs-client:a0f7418972
注意:我没有使用 jitpack,我想尝试手动完成……
关于 jitpack 的事情不用担心——我之前不知道你可以免费使用仓库,而且它需要放在 build.gradle 中的第二个仓库部分。我现在已经将应用程序安装到手机上了,非常棒,超级简单!只是希望有一种方法可以去掉这个地址栏。
我没有使用 jitpack,关于 jitpack 的事情——我之前不知道你可以免费使用仓库,而且它需要放在 build.gradle 中的第二个仓库部分。我想尝试手动完成
您好,我是移动应用新手,这与使用 webview 开发 Android 应用相同吗?
我该如何添加启动画面?是否有办法禁用地址栏?
我认为,所有这些内容都在创建 PWA 的清单中,并且超出了本文的范围。
清单描述了启动画面要使用的图标和主题颜色,以及布局规则(纵向、横向、灵活)以及要显示目标环境的多少内容(在浏览器中运行,带(只读)地址栏,全屏,或者大部分全屏,只留下顶部的通知栏可见(我通常的偏好)。
基本上,你应该首先通过手动方式(使用 Chrome,并且在使用应用程序一段时间后,“添加到主屏幕”选项将被替换为“安装”)将你的 PWA 安装到你的手机上,并查看它的行为,然后再通过本文介绍的方法将其提交到 Play 商店。所有通常的 PWA 规则都适用(清单、服务工作者、具有适当签名的证书的 HTTPS)。
是的,我已经将我的 PWA 设置为真正的 PWA,但是当我使用本教程将其设置为 Android 应用程序时,启动画面内容和主题颜色似乎不起作用。我想可能是 Android 的一些原生功能用于启动画面,就像他们对图标一样。
这个过程并不像我们希望的那样直观,我认为这是显而易见的,大多数与计算机相关的事情都不直观。我们需要集中精力,努力工作,探索事物才能提高效率。
嗯,感谢你!
感谢这篇有帮助的文章。
我有一个问题
如果我的网站使用 AdSense
我的应用程序是否符合 AdSense 政策?
我在 AdSense 政策页面中找到了以下内容:https://support.google.com/admob/answer/48182?hl=en
“内容版 AdSense (AFC) 和 Ad Exchange (AdX) 展示广告不受所有 WebView 技术支持。希望通过 WebView 发布 AFC 和 AdX 展示广告来获利的应用程序开发人员必须使用以下支持的查看框架之一
Android:Chrome 自定义标签
iOS:SFSafariViewController(仅限 iOS9 和 iOS10)”
我在支持论坛中找到了这个答案,TWA 是 Web view,AdSense 不允许,这是对的吗?
https://support.google.com/adsense/thread/20050641/is-adsense-allowed-with-twa-s?hl=en
TWA 使用的是 Chrome 自定义标签还是 WebView?
非常感谢