androidx.glance.appwidget

Interfaces

PreviewSizeMode

This marker interface determines which SizeModes can be used for preview compositions.

SizeMode

Modes describing how the GlanceAppWidget should handle size specification.

Classes

CheckBoxColors

Set of colors to apply to a CheckBox depending on the checked state.

GlanceAppWidget

Object handling the composition and the communication with AppWidgetManager.

GlanceAppWidgetManager

Manager for Glance App Widgets.

GlanceAppWidgetReceiver

AppWidgetProvider using the given GlanceAppWidget to generate the remote views when needed.

GlanceRemoteViews

Object containing the information needed to generate a RemoteViews.

GlanceRemoteViewsService

RemoteViewsService to be connected to for a remote adapter that returns RemoteViews for lazy lists / grids.

MyPackageReplacedReceiver

Broadcast receiver handling updates after a package update.

RadioButtonColors

Set of colors to apply to a RadioButton depending on the checked state.

RemoteViewsCompositionResult

Object containing the result from composition of GlanceRemoteViews.

SizeMode.Responsive

The GlanceAppWidget provides a UI for a fixed set of sizes.

SwitchColors

Set of colors to apply to a Switch depending on the checked state.

UnmanagedSessionReceiver

This receiver responds to lambda action clicks for unmanaged sessions (created by GlanceAppWidget.runComposition).

Objects

CheckboxDefaults

Contains the default values used by CheckBox.

ProgressIndicatorDefaults

Contains the default values used for LinearProgressIndicator.

RadioButtonDefaults

Contains the default values used by RadioButton.

SizeMode.Exact

The GlanceAppWidget provides a UI for each size the App Widget may be displayed at.

SizeMode.Single

The GlanceAppWidget provides a single UI.

SwitchDefaults

Contains the default values used by Switch.

Annotations

Composables

AndroidRemoteViews

Add RemoteViews into a glance composition.

CheckBox

Adds a check box view to the glance view.

CircularProgressIndicator

Adds a circular progress indicator view to the glance view.

LinearProgressIndicator

Adds an indeterminate linear progress indicator view to the glance view.

RadioButton

Adds a radio button to the glance view.

Switch

Adds a switch view to the glance view.

Top-level functions summary

ImageProvider

Image resource from a URI.

Extension functions summary

GlanceModifier

Define the current view as the background of the App Widget.

GlanceModifier

Apply a background color to the element this modifier is attached to.

suspend RemoteViews
GlanceAppWidget.compose(
    context: Context,
    id: GlanceId,
    options: Bundle?,
    size: DpSize?,
    state: Any?
)

Creates a snapshot of the GlanceAppWidget content without running recomposition.

suspend RemoteViews
GlanceAppWidget.composeForPreview(
    context: Context,
    widgetCategory: Int,
    info: AppWidgetProviderInfo?
)

Runs the composition in GlanceAppWidget.providePreview one time and translate it to a RemoteViews.

GlanceModifier

Adds rounded corners for the current view.

GlanceModifier

Adds rounded corners for the current view, using resources.

suspend Nothing

Provides content to the Glance host, suspending until the Glance session is shut down.

Flow<RemoteViews>
@ExperimentalGlanceApi
GlanceAppWidget.runComposition(
    context: Context,
    id: GlanceId,
    options: Bundle,
    sizes: List<DpSize>?,
    state: Any?,
    lambdaReceiver: ComponentName
)

Returns a Flow that, on collection, starts a composition session for this GlanceAppWidget and emits RemoteViews for each result.

GlanceModifier

Use this modifier to group a list of RadioButtons together for accessibility purposes.

suspend inline Int
@RequiresApi(value = 35)
<T : GlanceAppWidgetReceiver> GlanceAppWidgetManager.setWidgetPreviews(
    widgetCategories: IntSet
)

Generate and publish the widget previews for a GlanceAppWidgetReceiver for the given set of widgetCategories.

suspend Unit

Update all App Widgets managed by the GlanceAppWidget class.

suspend inline Unit
<State : Any?> GlanceAppWidget.updateIf(
    context: Context,
    predicate: (State) -> Boolean
)

Update all App Widgets managed by the GlanceAppWidget class, if they fulfill some condition.

Top-level properties summary

ProvidableCompositionLocal<Bundle>

Option Bundle accessible when generating an App Widget.

Top-level functions

ImageProvider

fun ImageProvider(uri: Uri): ImageProvider

Image resource from a URI.

Parameters
uri: Uri

The URI of the image to be displayed.

Extension functions

GlanceModifier.appWidgetBackground

fun GlanceModifier.appWidgetBackground(): GlanceModifier

Define the current view as the background of the App Widget.

By definition, the background of the App Widget is the view with the id @android:id/background.

There can be only one view with this modifier in a given App Widget.

This modifier does not automatically set corner radius. To have these set for you, use the androidx.glance.appwidget.components.Scaffold component.

For more information about widget backgrounds, See the documentation on Enable smoother transitions and Implement rounded corners for details on why it is important to label a view as being the background, and why you will want to set the cornerRadius of the same view.

GlanceModifier.background

fun GlanceModifier.background(day: Color, night: Color): GlanceModifier

Apply a background color to the element this modifier is attached to. This will cause the element to paint the specified Color as its background, choosing day or night depending on the device configuration, which will fill the bounds of the element.

GlanceAppWidget.compose

suspend fun GlanceAppWidget.compose(
    context: Context,
    id: GlanceId = createFakeAppWidgetId(),
    options: Bundle? = null,
    size: DpSize? = null,
    state: Any? = null
): RemoteViews

Creates a snapshot of the GlanceAppWidget content without running recomposition.

This runs the composition one time and translates it to RemoteViews.

If a valid id is provided, this function will use the sizing values from the bound widget if using SizeMode.Exact or SizeMode.Single.

Only one instance of compose for a particular id may run at the same time. Calling compose concurrently with the same ID will succeed, but the first call will resume with an exception.

If you need to call compose concurrently, you can omit id so that a random fake ID will be used. Otherwise, call compose sequentially when using the same id.

GlanceAppWidget.composeForPreview

suspend fun GlanceAppWidget.composeForPreview(
    context: Context,
    widgetCategory: Int,
    info: AppWidgetProviderInfo? = null
): RemoteViews

Runs the composition in GlanceAppWidget.providePreview one time and translate it to a RemoteViews. This function can be used to test the preview layout of a GlanceAppWidget.

The value of androidx.glance.LocalSize in the composition depends on the value of GlanceAppWidget.previewSizeMode:

If using SizeMode.Single (default), the composition will use the minimum size of the widget as determined by its AppWidgetProviderInfo.minHeight and AppWidgetProviderInfo.minWidth. If info is null, then DpSize.Zero will be used.

If using SizeMode.Responsive, the composition will use the provided sizes.

The given widgetCategory value should be a combination of AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN, AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD, or AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX.

Parameters
context: Context

context to provide to GlanceAppWidget.providePreview

widgetCategory: Int

widget category to provide to GlanceAppWidget.providePreview

info: AppWidgetProviderInfo? = null

the size of the composition is determined by the minimum width defined in this AppWidgetProviderInfo

Returns
RemoteViews

the preview composition translated to a RemoteViews

GlanceModifier.cornerRadius

fun GlanceModifier.cornerRadius(radius: Dp): GlanceModifier

Adds rounded corners for the current view.

Note: Only works on Android S+.

GlanceModifier.cornerRadius

fun GlanceModifier.cornerRadius(radius: @DimenRes Int): GlanceModifier

Adds rounded corners for the current view, using resources.

Note: Only works on Android S+.

GlanceAppWidget.provideContent

suspend fun GlanceAppWidget.provideContent(
    content: @Composable @GlanceComposable () -> Unit
): Nothing

Provides content to the Glance host, suspending until the Glance session is shut down.

If this function is called concurrently with itself, the previous call will throw CancellationException and the new content will replace it. This function should only be called from GlanceAppWidget.provideGlance.

TODO: make this a protected member once b/206013293 is fixed.

GlanceAppWidget.runComposition

@ExperimentalGlanceApi
fun GlanceAppWidget.runComposition(
    context: Context,
    id: GlanceId = createFakeAppWidgetId(),
    options: Bundle = Bundle(),
    sizes: List<DpSize>? = null,
    state: Any? = null,
    lambdaReceiver: ComponentName = ComponentName(context, UnmanagedSessionReceiver::class.java)
): Flow<RemoteViews>

Returns a Flow that, on collection, starts a composition session for this GlanceAppWidget and emits RemoteViews for each result. The composition is closed when the flow is cancelled.

If a valid id is provided, this function will use the sizing values from the bound widget if using SizeMode.Exact or SizeMode.Single.

Lambda actions and list views in the emitted RemoteViews will continue to work while this is flow is running. This currently does not support resizing (you have to run the flow again with new sizes) or reloading the androidx.glance.state.GlanceStateDefinition state value.

Note: In order to handle lambda actions correctly, only one instance of runComposition for a particular id may run at the same time. Calling runComposition concurrently with the same ID will succeed, but the first call will resume with an exception.

If you need to call runComposition concurrently, you can omit id so that a random fake ID will be used. Otherwise, call runComposition sequentially when using the same id.

By default, this function uses UnmanagedSessionReceiver as the lambdaReceiver target to receive any lambda actions while this function is running. If you need to run this function in a non-default process, you can declare a sub-class of UnmanagedSessionReceiver in that process and pass its ComponentName here.

GlanceModifier.selectableGroup

fun GlanceModifier.selectableGroup(): GlanceModifier

Use this modifier to group a list of RadioButtons together for accessibility purposes.

This modifier can only be used on a Row or Column. This modifier additonally enables the radio group effect, which automatically unselects the currently selected RadioButton when another is selected. When this modifier is used, an error will be thrown if more than one RadioButton has their "checked" value set to true.

GlanceAppWidgetManager.setWidgetPreviews

@RequiresApi(value = 35)
suspend inline fun <T : GlanceAppWidgetReceiver> GlanceAppWidgetManager.setWidgetPreviews(
    widgetCategories: IntSet = intSetOf( WIDGET_CATEGORY_HOME_SCREEN or WIDGET_CATEGORY_KEYGUARD or WIDGET_CATEGORY_SEARCHBOX )
): Int

Generate and publish the widget previews for a GlanceAppWidgetReceiver for the given set of widgetCategories. Previews are generated from the layout provided by GlanceAppWidget.providePreview on the widget connected to the given GlanceAppWidgetReceiver class. This receiver must be registered as an app widget provider in the application manifest.

Previews should be published during the initial setup phase or launch of your app. To avoid running this unnecessarily, you can see what previews are currently published for your provider by checking AppWidgetProviderInfo.generatedPreviewCategories.

The preview composition is run for each value in the widgetCategories array. If your widget has the same layout across categories, you can combine all of the categories in a single value, e.g. WIDGET_CATEGORY_HOME_SCREEN or WIDGET_CATEGORY_KEYGUARD or WIDGET_CATEGORY_SEARCHBOX, which will call composeForPreview once and set the previews for all of the categories.

Note that this API is only available on Build.VERSION_CODES.VANILLA_ICE_CREAM and above, so you will likely want to set AppWidgetProviderInfo.previewLayout and AppWidgetProviderInfo.previewImage as well to have the most coverage across versions.

See also AppWidgetProviderInfo.generatedPreviewCategories, AppWidgetManager.setWidgetPreview, AppWidgetManager.getWidgetPreview, and AppWidgetManager.removeWidgetPreview.

import androidx.glance.appwidget.GlanceAppWidgetManager
import androidx.glance.appwidget.GlanceAppWidgetManager.Companion.SET_WIDGET_PREVIEWS_RESULT_RATE_LIMITED
import androidx.glance.appwidget.GlanceAppWidgetReceiver

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
    return
}
fun Class<GlanceAppWidgetReceiver>.hasPreviewForCategory(widgetCategory: Int): Boolean {
    val component = ComponentName(context, this)
    val providerInfo =
        (context.getSystemService(Context.APPWIDGET_SERVICE) as AppWidgetManager)
            .installedProviders
            .first { providerInfo -> providerInfo.provider == component }
    return providerInfo.generatedPreviewCategories.and(widgetCategory) != 0
}
val receiverClasses = listOf<Class<GlanceAppWidgetReceiver>>()
val glanceAppWidgetManager = GlanceAppWidgetManager(context)
withContext(Dispatchers.Default) {
    try {
        for (receiver in receiverClasses) {
            if (receiver.hasPreviewForCategory(WIDGET_CATEGORY_HOME_SCREEN)) {
                Log.i("Widget", "Skipped updating previews for $receiver")
                continue
            }
            if (
                glanceAppWidgetManager.setWidgetPreviews(receiver.kotlin) ==
                    SET_WIDGET_PREVIEWS_RESULT_RATE_LIMITED
            ) {
                Log.e("Widget", "Failed to set previews for $receiver, rate limited")
            }
        }
    } catch (e: Exception) {
        Log.e("Widget", "Error thrown when calling setWidgetPreview", e)
    }
}
Parameters
widgetCategories: IntSet = intSetOf( WIDGET_CATEGORY_HOME_SCREEN or WIDGET_CATEGORY_KEYGUARD or WIDGET_CATEGORY_SEARCHBOX )

the widget categories for which to set previews. Each element of this set must be a combination of WIDGET_CATEGORY_HOME_SCREEN, WIDGET_CATEGORY_KEYGUARD, or WIDGET_CATEGORY_SEARCHBOX.

Returns
Int

GlanceAppWidgetManager.SET_WIDGET_PREVIEWS_RESULT_SUCCESS if the preview was successfully updated. Returns GlanceAppWidgetManager.SET_WIDGET_PREVIEWS_RESULT_RATE_LIMITED when the caller has hit a system-defined rate limit on setting previews for a particular provider. In this case, you may opt to schedule a task in the future to try again, if necessary.

GlanceAppWidget.updateAll

suspend fun GlanceAppWidget.updateAll(context: Context): Unit

Update all App Widgets managed by the GlanceAppWidget class.

GlanceAppWidget.updateIf

suspend inline fun <State : Any?> GlanceAppWidget.updateIf(
    context: Context,
    predicate: (State) -> Boolean
): Unit

Update all App Widgets managed by the GlanceAppWidget class, if they fulfill some condition.

Top-level properties

LocalAppWidgetOptions

val LocalAppWidgetOptionsProvidableCompositionLocal<Bundle>

Option Bundle accessible when generating an App Widget.

See AppWidgetManager#getAppWidgetOptions for details