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 hacen un seguimiento de las acciones de presión, como un clic en un botón, el desplazamiento, las impresiones y el tamaño y la posición del widget.

La API principal es AppWidgetEvent. Usa WorkManager para crear un Worker periódico que capture la interacción del widget, ya sea diaria, semanal o cada vez que se abra tu app.

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 informan una vez por hora de forma predeterminada, aunque los fabricantes de dispositivos pueden cambiar el período de informes. Por ejemplo, en los dispositivos Pixel, si un usuario desplaza la misma lista en tu widget 10 veces en una hora, solo se registrará 1 evento de desplazamiento para esa hora.

Para realizar pruebas, puedes configurar el siguiente atributo en un tiempo especificado y reiniciar el dispositivo de prueba. En el siguiente ejemplo, la ventana de informes se establece en 0 ms y los eventos se informan de inmediato.

adb shell device_config override systemui widget_events_report_interval_ms 0

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