在大多数搭载 Android 系统的设备上都可以使用的 Android 主屏幕,允许用户嵌入应用小部件(或小部件)以快速访问内容。如果您正在构建主屏幕替换或类似的应用,您还可以通过实现AppWidgetHost
来允许用户嵌入小部件。这并不是大多数应用需要执行的操作,但如果您正在创建自己的主机,则务必了解主机隐式同意的合同义务。
此页面重点介绍实施自定义AppWidgetHost
时涉及的责任。有关如何实施AppWidgetHost
的具体示例,请查看 Android 主屏幕的源代码LauncherAppWidgetHost
。
以下是实施自定义AppWidgetHost
涉及的关键类和概念概述
应用小部件主机:
AppWidgetHost
为在其 UI 中嵌入小部件的应用提供与 AppWidget 服务的交互。AppWidgetHost
必须具有在其自身包中唯一的 ID。此 ID 在主机的所有使用中都保持不变。该 ID 通常是您在应用中分配的硬编码值。应用小部件 ID:每个小部件实例在绑定时都会分配一个唯一的 ID。请参阅
bindAppWidgetIdIfAllowed()
,以及更多详细信息,请参阅以下的绑定小部件部分。主机使用allocateAppWidgetId()
获取唯一 ID。此 ID 在小部件的生命周期内一直存在,直到它从主机中删除。任何主机特定的状态(例如小部件的大小和位置)都必须由托管包持久化并与应用小部件 ID 关联。应用小部件主机视图:将
AppWidgetHostView
视为每次需要显示小部件时都包裹在其中的框架。每次主机加载小部件时,都会将小部件与AppWidgetHostView
关联。- 默认情况下,系统会创建一个
AppWidgetHostView
,但主机可以通过扩展它来创建自己的AppWidgetHostView
子类。 - 从 Android 12(API 级别 31)开始,
AppWidgetHostView
引入了用于处理动态重载颜色的setColorResources()
和resetColorResources()
方法。主机负责向这些方法提供颜色。
- 默认情况下,系统会创建一个
选项捆绑包:
AppWidgetHost
使用选项捆绑包将信息传达给AppWidgetProvider
,说明小部件是如何显示的(例如,大小范围列表)以及小部件是在锁屏上还是主屏幕上。此信息允许AppWidgetProvider
根据小部件的显示方式和位置调整小部件的内容和外观。您可以使用updateAppWidgetOptions()
和updateAppWidgetSize()
修改小部件的捆绑包。这两种方法都会触发onAppWidgetOptionsChanged()
回调到AppWidgetProvider
。
绑定小部件
当用户将小部件添加到主机时,会发生一个称为绑定的过程。绑定是指将特定应用小部件 ID 与特定主机和特定AppWidgetProvider
关联。
绑定 API 还使主机能够为绑定提供自定义 UI。要使用此过程,您的应用必须在主机的清单中声明BIND_APPWIDGET
权限
<uses-permission android:name="android.permission.BIND_APPWIDGET" />
但这仅仅是第一步。在运行时,用户必须明确授予您的应用权限,才能让它将小部件添加到主机。要测试您的应用是否具有添加小部件的权限,请使用bindAppWidgetIdIfAllowed()
方法。如果bindAppWidgetIdIfAllowed()
返回false
,则您的应用必须显示一个对话框,提示用户授予权限:“允许”当前的小部件添加,或“始终允许”以涵盖所有未来的小部件添加。
此代码段提供了一个如何显示对话框的示例
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);
主机必须检查用户添加的小部件是否需要配置。有关更多信息,请参阅允许用户配置应用小部件。
主机责任
您可以使用AppWidgetProviderInfo
元数据为小部件指定许多配置设置。您可以从与小部件提供程序关联的AppWidgetProviderInfo
对象中检索这些配置选项,在以下部分中将详细介绍。
无论您面向哪个版本的 Android,所有主机都承担以下责任
添加小部件时,请按照前面所述分配小部件 ID。当小部件从主机中删除时,请调用
deleteAppWidgetId()
以释放小部件 ID。添加小部件时,请检查是否需要启动配置活动。通常,如果配置活动存在且未通过同时指定
configuration_optional
和reconfigurable
标志而标记为可选,则主机需要启动小部件的配置活动。有关详细信息,请参阅从配置活动更新小部件。这是许多小部件在可以显示之前必须执行的必要步骤。小部件在
AppWidgetProviderInfo
元数据中指定默认宽度和高度。这些值在单元格中定义——从 Android 12 开始,如果指定了targetCellWidth
和targetCellHeight
——或者如果仅指定了minWidth
和minHeight
,则以 dp 为单位定义。请参阅小部件大小属性。确保小部件至少以这么多 dp 进行布局。例如,许多主机在网格中对齐图标和小部件。在这种情况下,默认情况下,主机使用满足
minWidth
和minHeight
约束的最小单元格数添加小部件。
除了上一节中列出的要求外,特定平台版本引入了会给主机带来新责任的功能。
根据目标 Android 版本确定您的方法
Android 12
Android 12(API 级别 31)捆绑了一个额外的List<SizeF>
,其中包含小部件实例可以在选项捆绑包中采用的可能大小(以 dp 为单位)的列表。提供的尺寸数量取决于主机实现。主机通常为手机提供两种尺寸(纵向和横向),为折叠屏提供四种尺寸。
对AppWidgetProvider
可以提供给RemoteViews
的不同RemoteViews
的数量有限制(MAX_INIT_VIEW_COUNT
,即 16)。由于AppWidgetProvider
对象将RemoteViews
对象映射到List<SizeF>
中的每个大小,因此不要提供超过MAX_INIT_VIEW_COUNT
个大小。
Android 12 还引入了maxResizeWidth
和maxResizeHeight
属性(以 dp 为单位)。我们建议使用至少一个这些属性的小部件不要超过属性指定的大小。
其他资源
- 请参阅
Glance
参考文档。