The Android home screen, available on most Android-powered devices, lets the
user embed app widgets (or widgets) for
quick access to content. If you're building a home screen replacement or a
similar app, you can also let the user embed widgets by implementing
AppWidgetHost. This isn't
something that most apps need to do, but if you are creating your own host, it's
important to understand the contractual obligations a host implicitly agrees to.
This page focuses on the responsibilities involved in implementing a custom
AppWidgetHost. For a specific example of how to implement an AppWidgetHost,
look at the source code for the Android home screen
LauncherAppWidgetHost.
Here is an overview of key classes and concepts involved in implementing a
custom AppWidgetHost:
App widget host: the
AppWidgetHostprovides the interaction with the AppWidget service for apps that embed widgets in their UI. AnAppWidgetHostmust have an ID that is unique within the host's own package. This ID persists across all uses of the host. The ID is typically a hardcoded value that you assign in your app.App widget ID: each widget instance is assigned a unique ID at the time of binding. See
bindAppWidgetIdIfAllowed()and, for more detail, the Binding widgets section that follows. The host obtains the unique ID usingallocateAppWidgetId(). This ID persists across the lifetime of the widget until it is deleted from the host. Any host-specific state—such as the size and location of the widget—must be persisted by the hosting package and associated with the app widget ID.App widget host view: think of
AppWidgetHostViewas a frame that the widget is wrapped in whenever it needs to be displayed. A widget is associated with anAppWidgetHostViewevery time the widget is inflated by the host.- By default, the system creates an
AppWidgetHostView, but the host can create its own subclass ofAppWidgetHostViewby extending it. - Starting in Android 12 (API level 31),
AppWidgetHostViewintroduces the thesetColorResources()andresetColorResources()methods for handling dynamically overloaded colors. The host is responsible for providing the colors to these methods.
- By default, the system creates an
Options bundle: the
AppWidgetHostuses the options bundle to communicate information to theAppWidgetProviderabout how the widget is displayed—for example, the list of size ranges—and whether the widget is on a lockscreen or the home screen. This information lets theAppWidgetProvidertailor the widget's contents and appearance based on how and where it is displayed. You can useupdateAppWidgetOptions()andupdateAppWidgetSize()to modify a widget's bundle. Both of these methods trigger theonAppWidgetOptionsChanged()callback to theAppWidgetProvider.
Binding widgets
When a user adds a widget to a host, a process called binding occurs. Binding
refers to associating a particular app widget ID with a specific host and a
specific AppWidgetProvider.
Binding APIs also make it possible for a host to provide a custom UI for
binding. To use this process, your app must declare the
BIND_APPWIDGET
permission in the host's manifest:
<uses-permission android:name="android.permission.BIND_APPWIDGET" />
But this is just the first step. At runtime, the user must explicitly grant
permission to your app to let it add a widget to the host. To test whether your
app has permission to add the widget, use the
bindAppWidgetIdIfAllowed()
method. If bindAppWidgetIdIfAllowed() returns false, your app must display a
dialog prompting the user to grant permission: "allow" for the current widget
addition, or "always allow" to cover all future widget additions.
This snippet gives an example of how to display the dialog:
Kotlin
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_BIND).apply { putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName) // This is the options bundle described in the preceding section. putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options) } startActivityForResult(intent, REQUEST_BIND_APPWIDGET)
Java
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName); // This is the options bundle described in the preceding section. intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options); startActivityForResult(intent, REQUEST_BIND_APPWIDGET);
The host must check whether the widget that a user adds needs configuration. For more information, see Enable users to configure app widgets.
Host responsibilities
You can specify a number of configuration settings for widgets using the
AppWidgetProviderInfo metadata.
You can retrieve these configuration options, covered in more detail in the
following sections, from the
AppWidgetProviderInfo
object associated with a widget provider.
Regardless of the version of Android you are targeting, all hosts have the following responsibilities:
When adding a widget, allocate the widget ID as described earlier. When a widget is removed from the host, call
deleteAppWidgetId()to deallocate the widget ID.When adding a widget, check whether the configuration activity needs to be launched. Typically, the host needs to launch the widget's configuration activity if it exists and isn't marked as optional by specifying both the
configuration_optionalandreconfigurableflags. See Update the widget from the configuration activity for details. This is a necessary step for many widgets before they can display.Widgets specify a default width and height in the
AppWidgetProviderInfometadata. These values are defined in cells—starting in Android 12, iftargetCellWidthandtargetCellHeightare specified—or dps if onlyminWidthandminHeightare specified. See Widget sizing attributes.Make sure that the widget is laid out with at least this many dps. For example, many hosts align icons and widgets in a grid. In this scenario, by default the host adds the a widget using the minimum number of cells that satisfy the
minWidthandminHeightconstraints.
In addition to the requirements listed in the preceding section, specific platform versions introduce features that place new responsibilities on the host.
Determine your approach based on the targeted Android version
Android 12
Android 12 (API level 31) bundles an extra List<SizeF> that contains the list
of possible sizes in dps that a widget instance can take in the options bundle.
The number of sizes provided depends on the host implementation. Hosts typically
provide two sizes for phones—portrait and landscape—and four sizes
for foldables.
There is a limit of MAX_INIT_VIEW_COUNT (16) on the number of different
RemoteViews that an AppWidgetProvider can provide to
RemoteViews.
Since AppWidgetProvider objects map a RemoteViews object to each size in the
List<SizeF>, don't provide more than MAX_INIT_VIEW_COUNT sizes.
Android 12 also introduces the
maxResizeWidth
and
maxResizeHeight
attributes in dps. We recommend that a widget that uses at least one of these
attributes doesn't exceed the size specified by the attributes.
Additional resources
- See the
Glancereference documentation.