Avaliar o engajamento do usuário

Este guia explica como medir os indicadores de engajamento das guias personalizadas do Chrome. Se o app mostra links para conteúdo da Web com frequência, por exemplo, em um feed de notícias, é importante saber quais links os usuários consideram valiosos e quais não. Nas guias personalizadas, é possível medir o engajamento do usuário específico da sessão pelo número de navegações, mudanças na direção de rolagem e profundidade de rolagem. Para conferir os indicadores de engajamento em ação, confira o app de demonstração das guias personalizadas no GitHub.

Exemplo de indicadores de engajamento da guia personalizada.

As guias personalizadas oferecem dois callbacks diferentes para medir o engajamento do usuário:

  • CustomTabsCallback para acompanhar eventos de navegação básicos, como "NAVIGATION_STARTED" ou "NAVIGATION_FINISHED".
  • EngagementSignalsCallback para acompanhar o engajamento do usuário específico da página, como direção ou porcentagem de rolagem.

Ambos exigem um CustomTabsServiceConnection ativo. Consulte o guia anterior sobre CustomTabsService para saber como se conectar a um CustomTabsService.

Para medir o engajamento do usuário, primeiro crie uma instância CustomTabsCallback e EngagementSignalsCallback. O CustomTabsCallback recebe uma constante navigationEvent que descreve o tipo de navegação que ocorreu:

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);     } }; 

O EngagementSignalsCallback oferece suporte a três callbacks diferentes:

onVerticalScrollEvent()
É chamado sempre que o usuário muda a direção de rolagem, em que isDirectionUp (o primeiro argumento) indica a direção.
  1. onGreatestScrollPercentageIncreased: a guia personalizada indica a profundidade de rolagem em intervalos de 5% até 100% quando o usuário chega ao final da página. O callback só é invocado quando o usuário para de rolar. O valor é redefinido para 0% a cada nova navegação.
  2. onSessionEnded: a guia personalizada dispara esse evento quando para de enviar indicadores de engajamento (por exemplo, depois que o usuário fecha a guia personalizada). didUserInteract será verdadeiro se o usuário interagir com a página de alguma forma (rolagem, clique no botão etc.).
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");     } }; 

Tanto CustomTabsCallback quanto EngagementSignalsCallback exigem uma conexão ativa de serviço da guia personalizada. Depois que o serviço estiver conectado, será possível criar um novo CustomTabsSession chamando CustomTabsClient.newSession() e transmitindo o CustomTabsCallback.

Em seguida, chame isEngagementSignalsApiAvailable() para verificar se os indicadores de engajamento são compatíveis com o navegador atual. Se houver suporte, você poderá registrar o EngagementSignalsCallback usando o 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;     } }; 

A única coisa que resta fazer é vincular o 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); }