You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PWABuilder构建的Android TWA中实现渠道区分及通知适配

区分Android TWA与Web访问用户的方案需求(适配通知权限)

我使用PWABuilder开发Trusted Web Activity (TWA)应用,核心需求是区分通过原生TWA访问的用户与直接访问Web应用的用户,以此实现:

  1. 合理请求通知权限:iOS用APN,Android用WebPush;
  2. 准确将订阅信息保存至数据库。

已实现的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:24:57