<p>Here is an overview of key classes and concepts involved in implementing a custom
{@link android.appwidget.AppWidgetHost}:</p>
<ul>
<li><strong>App Widget Host</strong>—
The {@link android.appwidget.AppWidgetHost} provides the interaction
with the AppWidget service for apps, like the home screen, that want to embed
app widgets in their UI. An {@link android.appwidget.AppWidgetHost} must have
an ID that is unique within the host's own package. This ID remains persistent
across all uses of the host. The ID is typically a hard-coded value that you assign
in your application.</li>
<li><strong>App Widget ID</strong>—
Each app widget instance is assigned a unique ID at the time of binding
(see {@link android.appwidget.AppWidgetManager#bindAppWidgetIdIfAllowed bindAppWidgetIdIfAllowed()},
discussed in more detail in <a href="#binding">Binding app widgets</a>).
The unique ID is obtained by the host using {@link android.appwidget.AppWidgetHost#allocateAppWidgetId() allocateAppWidgetId()}. This ID is persistent across the lifetime of the widget,
that is, until it is deleted from the host. Any host-specific state (such as the
size and location of the widget) should be persisted by the hosting package and
associated with the app widget ID.
</li>
<li><strong>App Widget Host View</strong>—
{@link android.appwidget.AppWidgetHostView} can be thought of as a frame
that the widget is wrapped in whenever it needs to be displayed. An app widget
is assigned to an {@link android.appwidget.AppWidgetHostView} every time the
widget is inflated by the host. </li>
<li><strong>Options Bundle</strong>—
The {@link android.appwidget.AppWidgetHost} uses the options bundle to communicate
information to the {@link android.appwidget.AppWidgetProvider} about how the
widget is being displayed (for example, size range, and whether the widget is on
a lockscreen or the home screen). This information allows the
{@link android.appwidget.AppWidgetProvider} to tailor the widget's contents
and appearance based on how and where it is displayed.
<p>When a user adds an app widget to a host, a process called
<em>binding</em> occurs. <em>Binding</em> refers to associating
a particular app widget ID to a specific host and to a specific
{@link android.appwidget.AppWidgetProvider}. There are different
ways of achieving this, depending on what version of Android your
app is running on.</p>
<h3 id="binding-pre">Binding app widgets on Android 4.0 and lower</h3>
<p>On devices running Android version 4.0 and lower, users add app widgets
via a system activity that allows users to select a widget. This implicitly
does a permission check—that is, by adding the app widget, the user is
implicitly granting permission to your app to add app widgets to the host.
Here is an example that illustrates
this approach, taken from the original
<a href="https://android.googlesource.com/platform/packages/apps/Launcher/+/master/src/com/android/launcher/Launcher.java">Launcher</a>. In this snippet, an event handler invokes
see <a href="{@docRoot}guide/topics/appwidgets/index.html#Configuring">Creating an
App Widget Configuration Activity</a>.</p>
<p>Once the app widget is ready, the next step is to do the
actual work of adding it to the workspace. The
<a href="https://android.googlesource.com/platform/packages/apps/Launcher/+/master/src/com/android/launcher/Launcher.java">original Launcher</a> uses a method called {@code completeAddAppWidget()}
to do this.</p>
<h3 id="binding-41">Binding app widgets on Android 4.1 and higher</h3>
<p>Android 4.1 adds APIs for a more streamlined binding process.
These APIs also make it possible for a host to provide a custom UI for
binding. To use this improved process, your app must declare the
{@link android.Manifest.permission#BIND_APPWIDGET} permission in its manifest:</p>
method. It also introduces lockscreen widgets.</li>
</ul>
<p>If you are targeting earlier devices, refer to the original
<a href="https://android.googlesource.com/platform/packages/apps/Launcher/+/master/src/com/android/launcher/Launcher.java">Launcher</a> as an example.
</div>
</div>
<p>Widget developers can specify a number of configuration settings
for widgets using the <a href="{@docRoot}guide/topics/appwidgets/index.html#MetaData">
AppWidgetProviderInfo metadata</a>.
These configuration options, discussed in more detail below, can be
retrieved by the host from the {@link android.appwidget.AppWidgetProviderInfo}
object associated with a widget provider.</p>
<p>Regardless of the version of Android you are targeting, all hosts
have the following responsibilities:</p>
<ul>
<li>When adding a widget, you must allocate the widget ID as described above.
You must also make sure that when a widget is removed from the host, you call {@link android.appwidget.AppWidgetHost#deleteAppWidgetId deleteAppWidgetId()}
to deallocate the widget ID.</li>
<li>When adding a widget, be sure to launch its configuration activity
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 should add the app widget using the minimum number of
cells that satisfy the {@code minWidth} and {@code minHeight} constraints.</li>
</ul>
<p>In addition to the requirements listed above, specific platform
versions introduce features that place new responsibilities on the
host. These are described in the following sections.</p>
<h3 id="30">Android 3.0</h3>
<p>Android 3.0 (API Level 11) introduces the ability for a widget to specify {@link android.appwidget.AppWidgetProviderInfo#autoAdvanceViewId autoAdvanceViewId()}.
This view ID should point to an instance of an
{@link android.widget.Advanceable}, such as {@link android.widget.StackView}
or {@link android.widget.AdapterViewFlipper}. This indicates that the host
should call {@link android.widget.Advanceable#advance advance()} on this
view at an interval deemed appropriate by the host (taking into account whether
it makes sense to advance the widget—for example, the host probably
wouldn't want to advance a widget if it were on another page, or
if the screen were turned off).</p>
<h3 id="31">Android 3.1</h3>
<p>Android 3.1 (API Level 12) introduces the ability to resize widgets.
A widget can specify that it is resizable using the
For a sample implementation, see <a href="https://android.googlesource.com/platform/packages/apps/Launcher2/+/master/src/com/android/launcher2/AppWidgetResizeFrame.java">
{@code AppWidgetResizeFrame}</a> in {@code Launcher2}.</p>
<h3 id="40">Android 4.0</h3>
<p>Android 4.0 (API Level 15) introduces a change in padding policy that
puts the responsibility on the host to manage padding. As of 4.0, app
widgets no longer include their own padding. Instead, the system adds
padding for each widget, based the characteristics of the current screen.
This leads to a more uniform, consistent presentation of widgets in a grid.
To assist applications that host app widgets, the platform provides
The size is specified as a minimum and maximum width/height in dps.
The reason that a range is specified (as opposed to a fixed size)
is because the width and height of a widget may change with orientation.
You don’t want the host to have to update all of its widgets on rotation,
as this could cause serious system slowdown. These values should be
updated once upon the widget being placed, any time the widget is resized,
and any time the launcher inflates the widget for the first time in a
given boot (as the values aren’t persisted across boot).</p>
<h3 id="42">Android 4.2</h3>
<p>Android 4.2 (API Level 17) adds the ability for the options bundle
to be specified at bind time. This is the ideal way to specify app
widget options, including size, as it gives the {@link
android.appwidget.AppWidgetProvider} immediate access to the options
data on the first update. This can be achieved by using the method {@link android.appwidget.AppWidgetManager#bindAppWidgetIdIfAllowed(int,android.content.ComponentName,android.os.Bundle) bindAppWidgetIdIfAllowed()}. For more discussion of this topic,
see <a href="#host-binding">Binding app widgets</a>.</p>
<p>Android 4.2 also introduces lockscreen widgets. When hosting widgets
on the lockscreen, the host must specify this information within the app
widget options bundle (the {@link
android.appwidget.AppWidgetProvider} can use this information to style
the widget appropriately). To designate a widget as a lockscreen widget, use {@link android.appwidget.AppWidgetHostView#updateAppWidgetOptions updateAppWidgetOptions()}