Monitorare le metriche per il widget

Android 16 include API per le metriche aggiuntive più granulari. Queste metriche monitorano le azioni di tocco, come un clic su un pulsante, lo scorrimento, le impressioni e le dimensioni e la posizione del widget.

L'API principale è AppWidgetEvent. Utilizza WorkManager per creare un worker periodico che acquisisce il coinvolgimento dei widget una volta all'ora.

Vedi lo snippet seguente per un esempio di monitoraggio di clic, scorrimenti e durata dell'impressione.

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

Per preservare l'integrità del sistema, gli eventi vengono segnalati una volta all'ora per impostazione predefinita, anche se i produttori di dispositivi possono modificare la finestra di reporting. Ad esempio, sui dispositivi Pixel se un utente scorre lo stesso elenco nel widget 10 volte in un'ora, verrà conteggiato solo un evento di scorrimento per quell'ora.

Per i test, puoi impostare il seguente attributo su un orario specifico e riavviare il dispositivo di test. Nell'esempio seguente, la finestra del report è impostata su 0 ms e gli eventi vengono segnalati immediatamente.

adb shell device_config override systemui widget_events_report_interval_ms 0

Per impostare un tag personalizzato per la generazione di report su clic e scorrimenti, puoi utilizzare RemoteViews.setAppWidgetEventTag in una visualizzazione all'interno del layout RemoteViews. Questo tag integer viene utilizzato quando esegui query per AppWidgetEvents che includono clic o scorrimenti in questa visualizzazione.