如何在PWABuilder构建的Android TWA中实现渠道区分及通知适配
区分Android TWA与Web访问用户的方案需求(适配通知权限)
我使用PWABuilder开发Trusted Web Activity (TWA)应用,核心需求是区分通过原生TWA访问的用户与直接访问Web应用的用户,以此实现:
- 合理请求通知权限:iOS用APN,Android用WebPush;
- 准确将订阅信息保存至数据库。
已实现的React端区分逻辑
React代码中已经写好了平台判断逻辑,但Android TWA环境下无法像iOS那样通过WebView设置自定义User-Agent来标识用户:
{isIOSApp() && ( <APNPermission /> )} {isAndroidApp() && ( <WebPush /> )}
已尝试但失败的方案
- 依赖
document.referrer:从外部链接加载或Google登录后,该值不可靠; - 修改
manifest.json的start_url:外部来源的链接已有查询参数,无法追加自定义参数; - 重写
com.google.androidbrowserhelper.trusted.LauncherActivity类的多个方法,均未找到设置自定义标识的有效途径:onCreate(Bundle savedInstanceState):仅能跟踪Intent额外数据和保存状态,与请求头/User-Agent设置无关;getLaunchingUrl():只能获取启动URL,无法修改;createTwaLauncher():可跟踪TWA启动器创建过程,但无法自定义请求头;launchTwa():无直接控制请求头的能力;getCustomTabsCallback():实现了自定义CustomTabsCallback(MyQualityEnforcer),但无法向Web应用发送消息。
测试代码与日志
重写LauncherActivity的测试代码
@Override protected void onCreate(Bundle savedInstanceState) { Intent i = super.getIntent(); i.putExtra("my app", "company app 2"); Bundle iExtras = i.getExtras(); if (savedInstanceState == null) { Log.d(tag, "2.onCreate Intent.getExtras " + i.getExtras().toString()); super.onCreate(iExtras); } else { Log.d(tag, "2.onCreate savedInstanceState " + savedInstanceState.toString()); super.onCreate(savedInstanceState); } Log.d(tag, "2.onCreate launcher activity last line"); } @Override protected Uri getLaunchingUrl() { Log.d(tag, "4.getLaunchingUrl"); // Get the original launch Url. Uri uri = super.getLaunchingUrl(); Log.d(tag, "4.getLaunchingUrl Launching URL: " + uri); return uri; } @Override protected TwaLauncher createTwaLauncher() { Log.d(tag, "5.createTwaLauncher twa launcher created"); TwaLauncher l = super.createTwaLauncher(); Log.d(tag, "5.createTwaLauncher twa launcher created " + l.getProviderPackage()); return l; } @Override protected void launchTwa() { Log.d(tag, "3.launchTwa main fn starting"); super.launchTwa(); Log.d(tag, "3.launchTwa executed"); } @Override protected CustomTabsCallback getCustomTabsCallback() { Log.d(tag, "6.CustomTabsCallback "); CustomTabsCallback q = new MyQualityEnforcer(); Bundle b = new Bundle(); b.putString("myapp", "company app"); q.onMessageChannelReady(b); Log.d(tag, "6.CustomTabsCallback " + q.toString()); return q; }
自定义QualityEnforcer类
public class MyQualityEnforcer extends QualityEnforcer { private final String tag = "MyLauncherActivity"; @Override public void onMessageChannelReady(Bundle extras) { // Handle the URL update event here Log.i(tag, "URL updated: " + extras.toString()); } }
日志输出
---------------------------- PROCESS STARTED (9972) for package com.company.app.twa ---------------------------- 2024-01-10 16:29:56.370 9972-9972 MyLauncherActivity com.company.app.twa D 1. hello worldWed Jan 10 16:29:56 GMT+11:00 2024 2024-01-10 16:29:56.604 9972-9972 MyLauncherActivity com.company.app.twa D 2.onCreate Intent.getExtras Bundle[{my app=company app 2}] 2024-01-10 16:29:56.617 9972-9972 MyLauncherActivity com.company.app.twa D 3.launchTwa main fn starting 2024-01-10 16:29:56.621 9972-9972 MyLauncherActivity com.company.app.twa D 4.getLaunchingUrl 2024-01-10 16:29:56.622 9972-9972 MyLauncherActivity com.company.app.twa D 4.getLaunchingUrl Launching URL: https://amazing-domain.example.com/ 2024-01-10 16:29:56.623 9972-9972 MyLauncherActivity com.company.app.twa D 5.createTwaLauncher twa launcher created 2024-01-10 16:29:56.639 9972-9972 MyLauncherActivity com.company.app.twa D 5.createTwaLauncher twa launcher created com.android.chrome 2024-01-10 16:29:56.639 9972-9972 MyLauncherActivity com.company.app.twa D 6.CustomTabsCallback 2024-01-10 16:29:56.641 9972-9972 MyLauncherActivity com.company.app.twa I URL updated: Bundle[{myapp=company app}] 2024-01-10 16:29:56.650 9972-9972 MyLauncherActivity com.company.app.twa D 6.CustomTabsCallback com.company.app.twa.MyQualityEnforcer@a6145b7 2024-01-10 16:29:57.339 9972-9972 MyLauncherActivity com.company.app.twa D 3.launchTwa executed 2024-01-10 16:29:57.347 9972-9972 MyLauncherActivity com.company.app.twa D 2.onCreate launcher activity last line
需求
寻求通过JavaScript检测Android设备是否运行在Trusted Web Activity中的有效方法。
内容的提问来源于stack exchange,提问作者Foyzul Karim
相关产品推荐
相关产品推荐

