מעקב אחר מדדים בווידג'ט

‫Android 16 כולל ממשקי API נוספים למדדים שהם מפורטים יותר. המדדים האלה עוקבים אחרי פעולות הקשה כמו קליק על לחצן, גלילה, חשיפות, הגודל והמיקום של הווידג'ט.

ממשק ה-API הראשי הוא AppWidgetEvent. אפשר להשתמש ב-WorkManager כדי ליצור worker תקופתי שמודד את האינטראקציה עם הווידג'ט פעם בשעה.

בדוגמה הבאה אפשר לראות איך עוקבים אחרי קליקים, גלילה ואורך חשיפה.

@RequiresApi(Build.VERSION_CODES_FULL.BAKLAVA_1)
fun getWidgetEngagementMetrics(context: Context) {
    val manager = AppWidgetManager.getInstance(context)

    val endTime = System.currentTimeMillis()
    val startTime = endTime - (24 * 60 * 60 * 1000) // a day ago

    val events = manager.queryAppWidgetEvents(startTime, endTime)

    if (events.isEmpty()) {
        Log.d(TAG, "No events found for the given time range.")
    }

    val metrics = hashMapOf(
        "clicks" to 0L,
        "scrolls" to 0L,
        "totalImpressionLength" to 0L
    )

    for (event in events) {

        Log.d(TAG, "Event Start: ${event.start}")
        Log.d(TAG, "Event End: ${event.end}")

        val widgetId = event.appWidgetId

        // Tap actions
        val clickedIds = event.clickedIds
        if (clickedIds?.isNotEmpty() == true) {
            metrics["clicks"] = metrics.getValue("clicks") + clickedIds.size
            // Log or analyze which components were clicked.
            for (id in clickedIds) {
                Log.d(TAG, "Widget $widgetId: Tap event on component with ID $id")
            }
        }

        // Scroll events
        val scrolledIds = event.scrolledIds
        if (scrolledIds?.isNotEmpty() == true) {
            metrics["scrolls"] = metrics.getValue("scrolls") + scrolledIds.size
            // Log or analyze which lists were scrolled.
            for (id in scrolledIds) {
                Log.d(TAG, "Widget $widgetId: Scroll event in list with ID/tag $id")
            }
        }

        // Impressions
        metrics["totalImpressionLength"] = metrics.getValue("totalImpressionLength") + event.visibleDuration.toMillis()
        Log.d(
            TAG,
            "Widget $widgetId: Impression event with duration " + event.visibleDuration.toMillis() + "ms"
        )

        // Position
        val position = event.position
        if (position != null) {
            Log.d(
                TAG,
                "Widget $widgetId: left=${position.left}, right=${position.right}, top=${position.top}, bottom=${position.bottom}"
            )
        }
    }
    Log.d("WidgetMetrics", "Metrics: $metrics")
}

כדי לשמור על תקינות המערכת, האירועים מדווחים פעם בשעה כברירת מחדל, אבל יצרני המכשירים יכולים לשנות את חלון הדיווח. לדוגמה, במכשירי Pixel, אם משתמש גולל את אותה רשימה בווידג'ט שלכם 10 פעמים בשעה, רק אירוע גלילה אחד ייספר בשעה הזו.

לצורך בדיקה, אפשר להגדיר את המאפיין הבא לזמן מסוים ולהפעיל מחדש את מכשיר הבדיקה. בדוגמה הבאה, חלון הדיווח מוגדר ל-0 אלפיות השנייה והאירועים מדווחים באופן מיידי.

adb shell device_config override systemui widget_events_report_interval_ms 0

כדי להגדיר תג מותאם אישית לדיווח על קליקים וגלילה, אפשר להשתמש ב-RemoteViews.setAppWidgetEventTag בתצוגה בפריסה של RemoteViews. התג הזה מסוג מספר שלם משמש כשמבצעים שאילתה לגבי AppWidgetEvents שכוללים קליקים או גלילה בתצוגה הזו.