قياس تفاعل المستخدمين

يوضِّح هذا الدليل كيفية قياس إشارات التفاعل لعلامات التبويب المخصّصة على Chrome. إذا كان تطبيقك يعرض بانتظام روابط تؤدي إلى محتوى الويب للمستخدمين، مثلاً في خلاصة أخبار، قد يكون من المهم معرفة الروابط التي يجدها المستخدمون مفيدة وغير ذلك. في "علامات التبويب المخصَّصة"، يمكنك قياس تفاعل المستخدِمين المحدّدين في الجلسة من خلال عدد عمليات التنقّل وتغييرات اتجاه التمرير وعمق التنقّل في الصفحة. للاطّلاع على إشارات التفاعل أثناء استخدامها، يُرجى الاطّلاع على التطبيق التجريبي لعلامات التبويب المخصّصة على 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 صحيحة إذا تفاعل المستخدم مع الصفحة بأي شكل (التمرير أو النقر على الزر وما إلى ذلك).
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);
}