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
AppWidgetHost
provides the interaction with the AppWidget service for apps that embed widgets in their UI. AnAppWidgetHost
must 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
AppWidgetHostView
as a frame that the widget is wrapped in whenever it needs to be displayed. A widget is associated with anAppWidgetHostView
every time the widget is inflated by the host.- By default, the system creates an
AppWidgetHostView
, but the host can create its own subclass ofAppWidgetHostView
by extending it. - Starting in Android 12 (API level 31),
AppWidgetHostView
introduces 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
AppWidgetHost
uses the options bundle to communicate information to theAppWidgetProvider
about 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 theAppWidgetProvider
tailor 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_optional
andreconfigurable
flags. 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
AppWidgetProviderInfo
metadata. These values are defined in cells—starting in Android 12, iftargetCellWidth
andtargetCellHeight
are specified—or dps if onlyminWidth
andminHeight
are 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
minWidth
andminHeight
constraints.
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
Glance
reference documentation.