Android 主屏幕(在大多数 Android 设备上可用)允许用户嵌入应用小部件(或小部件)以快速访问内容。如果您正在构建主屏幕替换或类似的应用,您还可以通过实现AppWidgetHost
来允许用户嵌入小部件。这并非大多数应用需要执行的操作,但如果您正在创建自己的主机,则务必了解主机隐式同意的合同义务。
此页面重点介绍实现自定义AppWidgetHost
时涉及的职责。有关如何实现AppWidgetHost
的具体示例,请查看 Android 主屏幕的源代码LauncherAppWidgetHost
。
以下是实现自定义AppWidgetHost
涉及的关键类和概念概述
应用小部件主机:
AppWidgetHost
为在 UI 中嵌入小部件的应用提供与应用小部件服务的交互。一个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 还引入了以 dp 为单位的maxResizeWidth
和 maxResizeHeight
属性。我们建议使用至少一个这些属性的小部件不要超过属性指定的大小。
其他资源
- 请参阅
Glance
参考文档。