TWA postMessage не работает — нет событий навигации или обратных вызовов канала сообщений.JAVA

Программисты JAVA общаются здесь
Anonymous
TWA postMessage не работает — нет событий навигации или обратных вызовов канала сообщений.

Сообщение Anonymous »

Проблема
У меня есть Android-приложение Trusted Web Activity (TWA), созданное с использованием Bubblewrap. TWA запускается успешно, и служба CustomTabs подключается без проблем.
Однако я не получаю никаких навигационных событий или обратных вызовов канала сообщений при попытке реализовать связь postMessage между собственным кодом Android и веб-контентом.
Моя цель — использовать это сообщение для запуска всплывающего окна с разрешением на уведомление в зависимости от того, зарегистрирован пользователь или нет.
Я следую официальной документации postMessage для TWA, но ожидаемые обратные вызовы не срабатывают.
Каковы могут быть потенциальные причины этого и как правильно установить канал связи postMessage для обработки разрешений на уведомления в TWA?
Среда
  • Приложение Android, использующее TWA
  • Версия Chrome: 115+ (требуется для TWA postMessage поддержка)
  • библиотека androidx.browser: v1.6.0-alpha02+
  • Ссылки на цифровые активы (DAL) настроены правильно (проверено запуском TWA без адресной строки)
Текущая реализация
AndroidManifest.xml: LauncherActivity.java:

Код: Выделить всё

    package com.mywebsite.twa;

import android.Manifest;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.browser.customtabs.CustomTabsCallback;
import androidx.browser.customtabs.CustomTabsClient;
import androidx.browser.customtabs.CustomTabsServiceConnection;
import androidx.browser.customtabs.CustomTabsSession;

public class LauncherActivity extends com.google.androidbrowserhelper.trusted.LauncherActivity {
private static final String TAG = "MywebsiteTWA";
private static final String MESSAGE_TO_JS = "Hello from Android";

private CustomTabsClient mClient;
private CustomTabsSession mSession;
private boolean mValidated;
private boolean mChannelRequested;
private final CustomTabsCallback mCustomTabsCallback = new CustomTabsCallback() {
@Override
public void onNavigationEvent(int navigationEvent, @Nullable Bundle extras) {
String eventName;
switch (navigationEvent) {
case NAVIGATION_STARTED:
eventName = "NAVIGATION_STARTED";
break;
case NAVIGATION_FINISHED:
eventName = "NAVIGATION_FINISHED";
break;
case NAVIGATION_FAILED:
eventName = "NAVIGATION_FAILED";
break;
case NAVIGATION_ABORTED:
eventName = "NAVIGATION_ABORTED";
break;
case TAB_SHOWN:
eventName = "TAB_SHOWN";
break;
case TAB_HIDDEN:
eventName = "TAB_HIDDEN";
break;
default:
eventName = "UNKNOWN(" + navigationEvent + ")";
}
Log.i(TAG, "Navigation event: " + eventName);

if (navigationEvent == TAB_SHOWN && !mChannelRequested) {
Uri launchUrl = Uri.parse(getLaunchingUrl().toString());
Log.i(TAG, "Requesting post message channel for " + launchUrl);

// Using the simpler approach that's been reported to work better
boolean channelRequested = mSession.requestPostMessageChannel(launchUrl);
Log.i(TAG, "Post message channel request result: " + channelRequested);
mChannelRequested = channelRequested;
}
}

@Override
public void onMessageChannelReady(@Nullable Bundle extras) {
Log.i(TAG, "Message channel ready, sending initial message");
int result = mSession.postMessage(MESSAGE_TO_JS, null);
Log.i(TAG, "Initial message send result: "  + result);
}

@Override
public void onPostMessage(@NonNull String message, @Nullable Bundle extras) {
Log.i(TAG, "Received message from web: " + message);

// Handle specific messages from web
if ("request_notification_permission".equals(message)) {
requestNotificationPermissionIfNeeded();
}
}

@Override
public void onRelationshipValidationResult(int relation, @NonNull Uri requestedOrigin,
boolean result, @Nullable Bundle extras) {
Log.i(TAG, "Relationship validation result: " + result);
mValidated = result;
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate called");
super.onCreate(savedInstanceState);

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}

initializeCustomTabs();
}

@Override
protected Uri getLaunchingUrl() {
Uri uri = super.getLaunchingUrl();
Log.i(TAG, "Getting launch URL: " + uri.toString());
return uri;
}

protected void requestNotificationPermissionIfNeeded() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.POST_NOTIFICATIONS},
1001
);
}
}

private void initializeCustomTabs() {
Log.i(TAG, "Initializing CustomTabs");
String packageName = CustomTabsClient.getPackageName(this, null);
Log.i(TAG, "Using browser package: " + packageName);

CustomTabsClient.bindCustomTabsService(this, packageName, new CustomTabsServiceConnection() {
@Override
public void onCustomTabsServiceConnected(@NonNull ComponentName name,
@NonNull CustomTabsClient client) {
Log.i(TAG, "CustomTabs service connected");
mClient = client;

// Warm up must be called before session creation
client.warmup(0L);
Log.i(TAG, "Called warmup on CustomTabsClient");

mSession = mClient.newSession(mCustomTabsCallback);
if (mSession == null) {
Log.e(TAG, "Failed to create new session");
} else {
Log.i(TAG, "CustomTabs session created successfully");
// Pre-load the launch URL
Uri launchUrl = Uri.parse(getLaunchingUrl().toString());
Log.i(TAG, "Pre-loading URL: " + launchUrl);
boolean success = mSession.mayLaunchUrl(launchUrl, null, null);
Log.i(TAG, "URL pre-load result: "  + success);
}
}

@Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "CustomTabs service disconnected");
mClient = null;
mSession = null;
mValidated = false;
mChannelRequested = false;
}
});
}

protected CustomTabsSession getSession() {
return mSession;
}
}
Текущее поведение
Из журналов:

Код: Выделить всё

---------------------------- PROCESS STARTED (27377) for package com.mywebsite.twa ----------------------------
2025-05-13 16:30:44.715 27377-27399 AdrenoGLES-0            com.mywebsite.twa                   I  QUALCOMM build                   : ee3f1da111, Ie1e5aac4cc
Build Date                       : 01/11/24
OpenGL ES Shader Compiler Version: EV031.35.01.12
Local Branch                     :
Remote Branch                    : refs/tags/AU_LINUX_ANDROID_LA.UM.9.14.11.00.00.571.148
Remote Branch                    : NONE
Reconstruct Branch               : NOTHING
2025-05-13 16:30:44.715 27377-27399 AdrenoGLES-0            com.mywebsite.twa                   I  Build Config                     : S P 10.0.7 AArch64
2025-05-13 16:30:44.715 27377-27399 AdrenoGLES-0            com.mywebsite.twa                   I  Driver Path                      : /vendor/lib64/egl/libGLESv2_adreno.so
2025-05-13 16:30:44.724 27377-27399 AdrenoGLES-0            com.mywebsite.twa                   I  PFP: 0x016dc094, ME: 0x00000000
2025-05-13 16:30:44.741 27377-27399 OpenGLRenderer          com.mywebsite.twa                   I  setGrContext nullptr-->validptr
2025-05-13 16:30:44.744 27377-27399 OpenGLRenderer          com.mywebsite.twa                   E  Unable to match the desired swap behavior.
2025-05-13 16:30:44.758 27377-27377 Compatibil...geReporter com.mywebsite.twa                   D  Compat change id reported: 160794467; UID 10542;  state: ENABLED
2025-05-13 16:30:44.761 27377-27377 MywebsiteTWA           com.mywebsite.twa                   I  CustomTabs service connected
2025-05-13 16:30:44.763 27377-27377 MywebsiteTWA           com.mywebsite.twa                   I  Called warmup on CustomTabsClient
2025-05-13 16:30:44.764 27377-27377 MywebsiteTWA           com.mywebsite.twa                   I  CustomTabs session created successfully
2025-05-13 16:30:44.764 27377-27377 TWALauncherActivity     com.mywebsite.twa                   D  Using url from Manifest: https://mywebsite.com/index.html
2025-05-13 16:30:44.764 27377-27377 MywebsiteTWA           com.mywebsite.twa                   I  Getting launch URL: https://mywebsite.com/index.html
2025-05-13 16:30:44.764 27377-27377 MywebsiteTWA           com.mywebsite.twa                   I  Pre-loading URL: https://mywebsite.com/index.html
2025-05-13 16:30:44.765 27377-27377 MywebsiteTWA           com.mywebsite.twa                   I  URL pre-load result: true
2025-05-13 16:30:45.098 27377-27377 TwaLauncher             com.mywebsite.twa                   D  Launching Trusted Web Activity.
2025-05-13 16:30:46.047 27377-27399 Surface                 com.mywebsite.twa                   D  Surface::disconnect
2025-05-13 16:30:46.047 27377-27399 BufferQueueProducer     com.mywebsite.twa                   D  [VRI[LauncherActivity]#0(BLAST Consumer)0](id:6af100000000,api:1,p:27377,c:27377) disconnect: api 1
2025-05-13 16:30:50.152 27377-27499 ProfileInstaller        com.mywebsite.twa                   D  Skipping profile installation for com.mywebsite.twa
TWA запускается успешно, но:
  • События навигации не регистрируются
  • Обратные вызовы канала сообщений не запускаются
  • Между собственным кодом и веб-контентом не устанавливается связь
Что я пробовал
  • Первоначально использовалось версия с тремя параметрами
    requestPostMessageChannel
    mSession.requestPostMessageChannel(sourceOrigin, targetOrigin, new Bundle())
  • Переключена на более простую версию с одним параметром, как рекомендовано в
    недавних обсуждениях Элемент списка
  • Настройка проверенных ссылок на цифровые активы (TWA запускается без адресной строки)
  • Добавлено правильное ведение журнала для всех методов обратного вызова
  • Гарантировано, что веб-контент имеет правильный прослушиватель событий сообщений
Вопрос
  • Почему события навигации не запускаются в
    CustomTabsCallback?
  • Что может препятствовать установлению канала сообщений
    ?
  • Нужны ли какие-либо дополнительные действия для
    правильной инициализации функции postMessage в TWA?
Дополнительный контекст
Сам TWA работает корректно — запускается и отображает веб-контент как положено. Проблема кажется специфичной для реализации postMessage. Журналы показывают успешное подключение к службе и предварительную загрузку URL-адреса, но не последующие события навигации или канала сообщений.
Мы будем очень признательны за любую информацию о том, чего может не хватать или что может препятствовать запуску событий обратного вызова.
Официальная документация по адресу:

Вернуться в «JAVA»