大多数 Android 设备上的 Android 主屏幕都允许用户嵌入
应用微件(或widget),以便
快速访问内容。如果您要构建主屏幕替代应用或类似的应用程序,还可以通过实现 AppWidgetHost 允许用户嵌入 widget。大多数应用都不需要这样做,但如果您要创建自己的托管应用,请务必了解托管应用默许的约定义务。
本页重点介绍实现自定义 AppWidgetHost 所涉及的责任。如需查看如何实现 AppWidgetHost 的具体示例,
请参阅 Android 主屏幕
LauncherAppWidgetHost 的源代码。
下面简要介绍了实现自定义 AppWidgetHost 所涉及的关键类和概念:
应用微件托管应用:
AppWidgetHost可以为要在界面中嵌入 widget 的应用提供与 AppWidget 服务的交互。AppWidgetHost必须具有一个在托管应用自己的软件包中独一无二的 ID。此 ID 在托管应用的所有使用场合中保持不变。此 ID 通常是您在应用中分配的硬编码值。应用微件 ID \- 每个 widget 实例在绑定时都分配有一个唯一 ID。请参阅
bindAppWidgetIdIfAllowed(),如需了解详情,请参阅下文的绑定 widget部分。托管应用使用allocateAppWidgetId()获取唯一 ID。 此 ID 在 widget 的整个生命周期内(也就是说,直到从托管应用中将其删除)保持不变。任何特定于托管应用的状态(如 widget 的大小和位置)都必须由托管软件包保留并与应用微件 ID 关联。应用微件托管应用视图 \- 您可以将
AppWidgetHostView看作一个框架 ,每当 widget 需要显示时,都会封装到该框架中。每当 widget 由托管应用扩充时,系统都会将 widget 分配给AppWidgetHostView。- 默认情况下,系统会创建
AppWidgetHostView,但托管应用可以通过扩展AppWidgetHostView来创建自己的子类。 - 从 Android 12(API 级别 31)开始,
AppWidgetHostView引入了 thesetColorResources()和resetColorResources()方法来处理动态重载的颜色。托管应用负责向这些方法提供颜色。
- 默认情况下,系统会创建
选项包:
AppWidgetHost使用选项包将有关如何显示 widget 的信息(例如,大小范围列表)以及 widget 是在锁定屏幕上还是在主屏幕上,传达给AppWidgetProvider。利用此信息,AppWidgetProvider可以根据 widget 的显示方式和显示位置来量身定制 widget 的内容和外观。您可以使用updateAppWidgetOptions()和updateAppWidgetSize()修改 widget 的软件包。这两种方法都会触发对AppWidgetProvider的onAppWidgetOptionsChanged()回调。
绑定 widget
当用户向托管应用添加 widget 时,会发生一个称为“绑定”的流程。 绑定是指将特定应用微件 ID 与特定托管应用以及特定 AppWidgetProvider 关联。
绑定 API 还使托管应用能够提供用于绑定的自定义界面。如需使用此流程,您的应用必须在托管应用的清单中声明
BIND_APPWIDGET
权限:
<uses-permission android:name="android.permission.BIND_APPWIDGET" />
但是,这只是第一步。在运行时,用户必须显式向您的应用授予权限,允许它将 widget 添加到托管应用。如需测试您的
应用是否具有添加 widget 的权限,请使用
bindAppWidgetIdIfAllowed()
方法。如果 bindAppWidgetIdIfAllowed() 返回 false,则您的应用必须显示一个对话框来提示用户授予权限:对于当前 widget 添加,选择“允许”;对于将来添加的所有 widget,选择“始终允许”。
以下代码段举例说明了如何显示该对话框:
val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_BIND).apply { putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.provider) // This is the options bundle described in the preceding section. putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options) } startActivityForResult(intent, REQUEST_BIND_APPWIDGET)
托管应用必须检查用户添加的 widget 是否需要配置。如需了解详情,请参阅允许用户配置应用 微件。
托管应用的责任
您可以使用
AppWidgetProviderInfo 元数据为 widget 指定一些配置设置。
您可以从与 widget 提供程序关联的 AppWidgetProviderInfo对象检索这些配置选项(以下部分对此进行了更详细的说明)。
所有托管应用都承担以下责任:
添加 widget 时,按照前面的说明分配 widget ID。从托管应用中移除 widget 时,调用
deleteAppWidgetId()来取消分配相应的 widget ID。添加 widget 时,检查是否需要启动配置 activity。通常,如果 widget 的配置 activity 存在,并且未通过同时指定
configuration_optional和reconfigurable标志将其标记为可选,则托管应用需要启动该 activity。如需了解详情,请参阅 通过配置 activity 更新 widget 。对于许多 widget 来说,这是一个必要的步骤,执行此步骤后,才能显示这些 widget。widget 在
AppWidgetProviderInfo元数据中指定默认宽度和高度。这些值以单元格为单位定义(从 Android 12 开始,如果指定了targetCellWidth和targetCellHeight),或者以 dp 为单位定义(如果仅指定了minWidth和minHeight)。请参阅 widget 大小调整属性。确保 widget 的布局至少包含这么多 dp。例如,许多托管应用在网格中将图标与 widget 对齐。在这种情况下,托管应用默认使用满足
minWidth和minHeight约束条件的最小数量的单元格来添加 widget。
有关方法的提示
除了上一部分列出的要求之外,请注意以下提示:
选项包可以包含一个 List<SizeF>,其中包含 widget 实例可以采用的
可能大小的列表(以 dp 为单位)。提供的尺寸数量取决于托管应用的实现。托管应用通常为手机提供两种尺寸(竖屏和横屏),为可折叠设备提供四种尺寸。
AppWidgetProvider 可以向
RemoteViews 提供的不同
RemoteViews 的数量上限为 MAX_INIT_VIEW_COUNT (16)。
由于 AppWidgetProvider 对象会将 RemoteViews 对象映射到
List<SizeF> 中的每个大小,因此请勿提供超过 MAX_INIT_VIEW_COUNT 个大小。
当 widget 在 dp 中指定 maxResizeWidth 和 maxResizeHeight
属性时,我们建议使用至少一个此类
属性的 widget 不超过这些属性指定的大小。
其他资源
- 请参阅
Glance参考文档。