Đo lường mức độ tương tác của người dùng

Hướng dẫn này giải thích cách đo lường tín hiệu tương tác cho thẻ Tuỳ chỉnh của Chrome. Nếu ứng dụng của bạn thường xuyên hiển thị đường liên kết đến nội dung trên web cho người dùng, chẳng hạn như trong nguồn cấp tin tức, quan trọng là bạn phải biết được đường liên kết nào có giá trị và đường liên kết nào không. Trong Thẻ tuỳ chỉnh, bạn có thể đo lường mức độ tương tác của người dùng theo phiên cụ thể thông qua số lần di chuyển, thay đổi về hướng cuộn và chiều sâu cuộn. Để xem các tín hiệu tương tác trong thực tế, vui lòng xem ứng dụng minh hoạ Thẻ tuỳ chỉnh trên GitHub.

Bản minh hoạ các tín hiệu tương tác trên thẻ tuỳ chỉnh.

Thẻ tuỳ chỉnh cung cấp hai lệnh gọi lại để đo lường mức độ tương tác của người dùng:

  • CustomTabsCallback để theo dõi các sự kiện điều hướng cơ bản, chẳng hạn như "NAVIGATION_STARTED" hoặc "NAVIGATION_FINISHED".
  • EngagementSignalsCallback để theo dõi mức độ tương tác của người dùng cụ thể trên trang, chẳng hạn như hướng cuộn hoặc tỷ lệ cuộn.

Cả hai đều yêu cầu phải có một CustomTabsServiceConnection đang hoạt động. Xem hướng dẫn trước đó về CustomTabsService để biết thông tin chi tiết về cách kết nối với CustomTabsService.

Để đo lường mức độ tương tác của người dùng, trước tiên, hãy tạo một thực thể CustomTabsCallbackEngagementSignalsCallback. CustomTabsCallback nhận được hằng số navigationEvent mô tả loại điều hướng nào đã xảy ra:

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 hỗ trợ 3 lệnh gọi lại:

onVerticalScrollEvent()
Được gọi mỗi khi người dùng thay đổi hướng cuộn, trong đó isDirectionUp (đối số đầu tiên) cho biết hướng.
  1. onGreatestScrollPercentageIncreased: Chiều sâu cuộn của tín hiệu Thẻ tuỳ chỉnh trong khoảng 5% (tối đa 100%) khi người dùng đến cuối trang. Lệnh gọi lại chỉ được gọi khi người dùng ngừng cuộn. Giá trị này được đặt lại về 0% với mọi lượt điều hướng mới.
  2. onSessionEnded: Thẻ tuỳ chỉnh sẽ kích hoạt sự kiện này khi ngừng gửi tín hiệu tương tác (ví dụ: sau khi người dùng đã đóng Thẻ tuỳ chỉnh). didUserInteract sẽ có giá trị true nếu người dùng tương tác với trang theo bất kỳ cách nào (cuộn, nhấp vào nút, v.v.).
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");
    }
};

Cả CustomTabsCallbackEngagementSignalsCallback đều yêu cầu kết nối dịch vụ Thẻ tuỳ chỉnh đang hoạt động. Sau khi dịch vụ được kết nối, bạn có thể tạo CustomTabsSession mới bằng cách gọi CustomTabsClient.newSession() và truyền CustomTabsCallback.

Sau đó, bạn nên gọi isEngagementSignalsApiAvailable() để kiểm tra xem trình duyệt hiện tại có hỗ trợ các tín hiệu tương tác hay không. Nếu các dịch vụ này được hỗ trợ, bạn có thể đăng ký EngagementSignalsCallback qua 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;
    }
};

Bạn chỉ cần liên kết 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);
}