Cómo administrar y actualizar GlanceAppWidget

En las siguientes secciones, se describe cómo actualizar GlanceAppWidget y administrar su estado.

Administrar el estado de GlanceAppWidget

La clase GlanceAppWidget proporcionada se instancia cada vez que se crea el widget o requiere una actualización, por lo que debe ser sin estado y pasiva.

El concepto de estado se puede dividir en lo siguiente:

  • Estado de la aplicación: Es el estado o el contenido de la app que requiere el widget. Por ejemplo, una lista de destinos almacenados (es decir, una base de datos) definida por el usuario.
  • Estado del vistazo: Es el estado específico que solo es relevante para el widget de la app y no necesariamente modifica ni afecta el estado de la app. Por ejemplo, se seleccionó una casilla de verificación en el widget o se incrementó un contador.

Usa el estado de la aplicación

Los widgets de la app deben ser pasivos. Cada aplicación es responsable de administrar la capa de datos y controlar los estados, como inactivo, cargando y error, que se reflejan en la IU del widget.

Por ejemplo, el siguiente código recupera los destinos de la caché en memoria de la capa del repositorio, proporciona la lista de destinos almacenada y muestra una IU diferente según su estado:

class DestinationAppWidget : GlanceAppWidget() {

    // ...

    @Composable
    fun MyContent() {
        val repository = remember { DestinationsRepository.getInstance() }
        // Retrieve the cache data everytime the content is refreshed
        val destinations by repository.destinations.collectAsState(State.Loading)

        when (destinations) {
            is State.Loading -> {
                // show loading content
            }

            is State.Error -> {
                // show widget error content
            }

            is State.Completed -> {
                // show the list of destinations
            }
        }
    }
}

Cuando cambia el estado o los datos, es responsabilidad de la app notificar y actualizar el widget. Consulta Update GlanceAppWidget para obtener más información.

Actualizar GlanceAppWidget

Puedes solicitar que se actualice el contenido de tu widget con GlanceAppWidget. Como se explica en la sección Administra el estado de GlanceAppWidget, los widgets de la app se alojan en un proceso diferente. Glance traduce el contenido en RemoteViews reales y los envía al host. Para actualizar el contenido, Glance debe volver a crear los RemoteViews y enviarlos.

Para enviar la actualización, llama al método update de la instancia GlanceAppWidget y proporciona context y glanceId:

MyAppWidget().update(context, glanceId)

Para obtener el glanceId, consulta el GlanceAppWidgetManager:

val manager = GlanceAppWidgetManager(context)
val widget = GlanceSizeModeWidget()
val glanceIds = manager.getGlanceIds(widget.javaClass)
glanceIds.forEach { glanceId ->
    widget.update(context, glanceId)
}

Como alternativa, usa una de las extensiones de GlanceAppWidget update:

// Updates all placed instances of MyAppWidget
MyAppWidget().updateAll(context)

// Iterate over all placed instances of MyAppWidget and update if the state of
// the instance matches the given predicate
MyAppWidget().updateIf<State>(context) { state ->
    state == State.Completed
}

Se puede llamar a estos métodos desde cualquier parte de tu aplicación. Como son funciones suspend, te recomendamos que las ejecutes fuera del alcance del subproceso principal. En el siguiente ejemplo, se inician en un CoroutineWorker:

class DataSyncWorker(
    val context: Context,
    val params: WorkerParameters,
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        // Fetch data or do some work and then update all instance of your widget
        MyAppWidget().updateAll(context)
        return Result.success()
    }
}

Consulta Corrutinas de Kotlin en Android para obtener más detalles sobre las corrutinas.

Cuándo actualizar los widgets

Actualizar los widgets de inmediato o de forma periódica

Tu widget se puede actualizar de inmediato cuando la app está activa. Por ejemplo:

  • Cuando un usuario interactúa con un widget, se activa una acción, una llamada a una lambda o un intent para iniciar una actividad.
  • Cuando el usuario interactúa con tu app en primer plano o mientras la app ya se está actualizando en respuesta a un mensaje de Firebase Cloud Messaging (FCM) o una transmisión.

En estos casos, llama al método update como se describe en esta guía.

Tu widget se puede actualizar periódicamente cuando la app no está activa. Por ejemplo:

  • Usa updatePeriodMillis para actualizar el widget hasta una vez cada 30 minutos.
  • Usa WorkManager para programar actualizaciones más frecuentes, por ejemplo, cada 15 minutos.
  • Actualiza el widget en respuesta a una transmisión.

Recursos