ユーザー エンゲージメントを測定する

このガイドでは、Chrome カスタムタブのエンゲージメント シグナルを測定する方法について説明します。ニュースフィードなどで、アプリがウェブ コンテンツへのリンクをユーザーに定期的に表示する場合は、ユーザーにとって価値のあるリンクとそうでないリンクを把握することが重要です。カスタムタブでは、ナビゲーション数、スクロール方向の変更、スクロールの深さに基づいて、セッションごとのユーザー エンゲージメントを測定できます。エンゲージメント シグナルの動作を確認するには、GitHub のカスタムタブのデモアプリをご覧ください。

カスタムタブのエンゲージメント シグナルのデモ。

カスタムタブには、ユーザー エンゲージメントを測定するための 2 種類のコールバックがあります。

  • 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 は、次の 3 種類のコールバックをサポートしています。

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

CustomTabsCallbackEngagementSignalsCallback の両方には、アクティブなカスタムタブ サービス接続が必要です。サービスが接続されたら、CustomTabsClient.newSession() を呼び出して CustomTabsCallback を渡すことで、新しい CustomTabsSession を作成できます。

その後、isEngagementSignalsApiAvailable() を呼び出して、エンゲージメント シグナルが現在のブラウザでサポートされているかどうかを確認する必要があります。サポートされている場合は、CustomTabsSession.setEngagementSignalsCallback() を使用して EngagementSignalsCallback を登録できます。

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