Cómo medir la participación de los usuarios

En esta guía, se explica cómo medir los indicadores de participación de las pestañas personalizadas de Chrome. Si tu app les muestra a los usuarios vínculos a contenido web con regularidad (por ejemplo, en un feed de noticias), puede ser importante saber qué vínculos consideran valiosos y cuáles no. En las pestañas personalizadas, puedes medir la participación del usuario específica de la sesión a través de la cantidad de navegaciones, los cambios de dirección y la profundidad de desplazamiento. Para ver los indicadores de participación en acción, consulta la app de demostración de pestañas personalizadas en GitHub.

. Demostración de los indicadores de participación de la pestaña personalizada.

Las pestañas personalizadas proporcionan dos devoluciones de llamada diferentes para medir la participación del usuario:

  • CustomTabsCallback para realizar un seguimiento de los eventos de navegación básicos, como "NAVIGATION_STARTED" o "NAVIGATION_FINISHED"
  • EngagementSignalsCallback para hacer un seguimiento de la participación de los usuarios en una página específica, como la dirección o el porcentaje de desplazamiento

Ambos requieren un CustomTabsServiceConnection activo. Consulta la guía anterior de CustomTabsService para obtener detalles sobre cómo conectarte a un CustomTabsService.

Para medir la participación de los usuarios, primero crea una instancia CustomTabsCallback y una EngagementSignalsCallback. CustomTabsCallback recibe una constante navigationEvent que describe qué tipo de navegación ocurrió:

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 admite tres devoluciones de llamada diferentes:

onVerticalScrollEvent()
Se llama cada vez que el usuario cambia la dirección de desplazamiento, donde isDirectionUp (el primer argumento) indica la dirección.
  1. onGreatestScrollPercentageIncreased: La pestaña personalizada indica la profundidad de desplazamiento en intervalos del 5% hasta el 100% cuando el usuario llega a la parte inferior de la página. La devolución de llamada solo se invoca una vez que el usuario deja de desplazarse. El valor se restablece al 0% con cada navegación nueva.
  2. onSessionEnded: La pestaña personalizada activa este evento cuando deja de enviar indicadores de participación (por ejemplo, después de que el usuario cierra la pestaña personalizada). didUserInteract será verdadero si el usuario interactuó con la página de cualquier manera (desplazándose, haciendo clic en un botón, 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");
    }
};

CustomTabsCallback y EngagementSignalsCallback requieren una conexión activa de servicio de pestaña personalizada. Una vez que se conecte el servicio, podrás crear un CustomTabsSession nuevo si llamas a CustomTabsClient.newSession() y pasas el CustomTabsCallback.

Luego, debes llamar a isEngagementSignalsApiAvailable() para verificar si el navegador actual admite los indicadores de participación. Si son compatibles, puedes registrar tu EngagementSignalsCallback a través de 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;
    }
};

Lo único que queda por hacer es vincular el 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);
}