Realiza un seguimiento de las métricas de tu widget

Android 16 incluye APIs de métricas adicionales que son más detalladas. Estas métricas registran acciones de presión, como un clic en un botón, un desplazamiento, las impresiones y el tamaño y la posición del widget.

La API principal es AppWidgetEvent. Usa WorkManager para crear un trabajador periódico que capture la participación en el widget una vez por hora.

Consulta el siguiente fragmento para ver un ejemplo del seguimiento de clics, desplazamientos y duración de la impresión.

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

Para preservar el estado del sistema, los eventos se registran una vez por hora de forma predeterminada, aunque los fabricantes de dispositivos pueden cambiar la ventana de informes. Por ejemplo, en los dispositivos Pixel, si un usuario se desplaza por la misma lista en tu widget 10 veces en una hora, solo se contabilizará 1 evento de desplazamiento para esa hora.

Para realizar pruebas, puedes establecer el siguiente atributo en un horario específico y reiniciar el dispositivo de prueba. En el siguiente ejemplo, la ventana de informes se establece en 0 ms y los eventos se registran de inmediato.

adb shell device_config override systemui widget_events_report_interval_ms 0

Para establecer una etiqueta personalizada para registrar los clics y los desplazamientos, puedes usar RemoteViews.setAppWidgetEventTag en una vista dentro de tu diseño de RemoteViews. Esta etiqueta de número entero se usa cuando consultas AppWidgetEvents que incluyen clics o desplazamientos en esta vista.