Измеряйте вовлеченность пользователей

В этом руководстве объясняется, как измерить сигналы взаимодействия для пользовательских вкладок Chrome. Если ваше приложение регулярно отображает ссылки на веб-контент своим пользователям, например, в ленте новостей, может быть важно знать, какие ссылки пользователи находят ценными, а какие нет. В пользовательских вкладках вы можете измерить вовлеченность пользователя в конкретном сеансе по количеству переходов, изменениям направления прокрутки и глубине прокрутки. Чтобы увидеть сигналы взаимодействия в действии, ознакомьтесь с демонстрационным приложением Custom Tabs на GitHub .

Демонстрация сигналов взаимодействия с пользовательской вкладкой.

Пользовательские вкладки предоставляют два разных обратных вызова для измерения вовлеченности пользователей:

  • CustomTabsCallback для отслеживания основных событий навигации, таких как "NAVIGATION_STARTED" или "NAVIGATION_FINISHED" .
  • EngagementSignalsCallback для отслеживания взаимодействия пользователя с конкретной страницей, например направления прокрутки или процента прокрутки.

Оба требуют активного CustomTabsServiceConnection . Подробную информацию о том, как подключиться к CustomTabsService см. в предыдущем руководстве CustomTabsService .

Чтобы измерить вовлеченность пользователей, сначала создайте экземпляры CustomTabsCallback и EngagementSignalsCallback . CustomTabsCallback получает константу navigationEvent описывающую, какой тип навигации произошел:

private CustomTabsCallback mCustomTabsCallback = new CustomTabsCallback() {     @Override     public void onNavigationEvent(int navigationEvent, @Nullable Bundle extras) {         String event;         switch (navigationEvent) {             case CustomTabsCallback.NAVIGATION_ABORTED:                 event = "NAVIGATION_ABORTED";                 break;             case CustomTabsCallback.NAVIGATION_FAILED:                 event = "NAVIGATION_FAILED";                 break;             case CustomTabsCallback.NAVIGATION_FINISHED:                 event = "NAVIGATION_FINISHED";                 break;             case CustomTabsCallback.NAVIGATION_STARTED:                 event = "NAVIGATION_STARTED";                 break;             case CustomTabsCallback.TAB_SHOWN:                 event = "TAB_SHOWN";                 break;             case CustomTabsCallback.TAB_HIDDEN:                 event = "TAB_HIDDEN";                 break;             default:                 event = String.valueOf(navigationEvent);         }         Log.d(TAG, "onNavigationEvent (navigationEvent=" + event + ')');         mTextNavigation.setText("onNavigationEvent " + event);     } }; 

EngagementSignalsCallback поддерживает три различных обратных вызова:

onVerticalScrollEvent()
Вызывается каждый раз, когда пользователь меняет направление прокрутки, где isDirectionUp (первый аргумент) указывает направление.
  1. onGreatestScrollPercentageIncreased : пользовательская вкладка сигнализирует о глубине прокрутки с интервалом от 5% до 100%, когда пользователь достиг нижней части страницы. Обратный вызов вызывается только тогда, когда пользователь прекращает прокрутку. Значение сбрасывается на 0% при каждой новой навигации.
  2. onSessionEnded : пользовательская вкладка запускает это событие, когда прекращает отправлять сигналы взаимодействия (например, после того, как пользователь закрыл пользовательскую вкладку). didUserInteract будет иметь значение true, если пользователь каким-либо образом взаимодействовал со страницей (прокрутка, нажатие кнопки и т. д.).
private EngagementSignalsCallback mEngagementSignalsCallback = new EngagementSignalsCallback() {     @Override     public void onVerticalScrollEvent(boolean isDirectionUp, @NonNull Bundle extras) {         Log.d(TAG, "onVerticalScrollEvent (isDirectionUp=" + isDirectionUp + ')');         mTextVerticalScroll.setText("vertical scroll " + (isDirectionUp ? "UP️" : "DOWN"));     }      @Override     public void onGreatestScrollPercentageIncreased(int scrollPercentage, @NonNull Bundle extras) {         Log.d(TAG, "scroll percentage: " + scrollPercentage + "%");         mTextGreatestPercentage.setText("scroll percentage: " + scrollPercentage + "%");     }      @Override     public void onSessionEnded(boolean didUserInteract, @NonNull Bundle extras) {         Log.d(TAG, "onSessionEnded (didUserInteract=" + didUserInteract + ')');         mTextSessionEnd.setText(didUserInteract ? "session ended with user interaction" : "session ended without user interaction");     } }; 

И CustomTabsCallback , и EngagementSignalsCallback требуют активного подключения к службе пользовательских вкладок. После подключения службы вы можете создать новый CustomTabsSession , вызвав CustomTabsClient.newSession() и передав CustomTabsCallback .

После этого вам следует вызвать isEngagementSignalsApiAvailable() чтобы проверить, поддерживаются ли сигналы взаимодействия текущим браузером. Если они поддерживаются, вы можете зарегистрировать свой EngagementSignalsCallback с помощью CustomTabsSession.setEngagementSignalsCallback() .

private CustomTabsClient mCustomTabsClient; private CustomTabsSession mCustomTabsSession;  private final CustomTabsServiceConnection mServiceConnectionCallback = new CustomTabsServiceConnection() {      @Override     public void onCustomTabsServiceConnected(@NonNull ComponentName name, @NonNull CustomTabsClient client) {         mCustomTabsClient = client;         mCustomTabsSession = mCustomTabsClient.newSession(mCustomTabsCallback);         try {             boolean engagementSignalsApiAvailable = mCustomTabsSession.isEngagementSignalsApiAvailable(Bundle.EMPTY);             if (!engagementSignalsApiAvailable) {                 Log.d(TAG, "CustomTab Engagement signals not available, make sure to use the " +                         "latest Chrome version and enable via chrome://flags/#cct-real-time-engagement-signals");                 return;             }             mCustomTabsSession.setEngagementSignalsCallback(mEngagementSignalsCallback, Bundle.EMPTY);         } catch (RemoteException e) {             Log.w(TAG, "The Service died while responding to the request.", e);         } catch (UnsupportedOperationException e) {             Log.w(TAG, "Engagement Signals API isn't supported by the browser.", e);         }     }      @Override     public void onServiceDisconnected(ComponentName name) {         mCustomTabsClient = null;         mConnection = null;         mCustomTabsSession = null;     } }; 

Единственное, что осталось сделать, — это привязать CustomTabsService :

@Override protected void onStart() {     super.onStart();     bindCustomTabsService(); }  private void bindCustomTabsService() {     String packageName = CustomTabsHelper.getPackageNameToUse(this);     if (packageName == null) return;     CustomTabsClient.bindCustomTabsService(this, packageName, mConnection); }