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

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