构建 widget 托管应用

大多数 Android 设备都支持 Android 主屏幕,因此 用户嵌入的应用微件(或 widget) 快速访问内容。如果您要打造主屏幕替换项或 还可以通过实现 AppWidgetHost。这不是 大多数应用都需要执行的任务,但如果您要创建自己的主机, 了解托管方默许的合同义务。

本页重点介绍实现自定义 AppWidgetHost。有关如何实现 AppWidgetHost 的具体示例, 查看 Android 主屏幕的源代码 LauncherAppWidgetHost

以下是实现 自定义 AppWidgetHost

  • 应用 widget 宿主AppWidgetHost 提供与应用 widget 的互动, AppWidget 服务,适用于在界面中嵌入 widget 的应用。AppWidgetHost 具有的 ID 在托管商自己的包中必须是唯一的。此 ID 会永久保留 托管应用的所有资源ID 通常是 分配。

  • 应用微件 ID:每个微件实例都分配有一个唯一 ID 即绑定状态请参阅 bindAppWidgetIdIfAllowed() 以及后面的绑定微件部分,了解更多详情。通过 托管商使用 allocateAppWidgetId()。 此 ID 会在微件的整个生命周期内持续有效,直到它从 主机。任何主机特定的状态,例如 微件必须由托管软件包保留,并与 应用微件 ID。

  • 应用微件托管应用视图:您可以考虑使用 AppWidgetHostView以框架形式显示 该 widget 会在需要显示时被封装。微件是 与 AppWidgetHostView 相关联。 主机。

    • 默认情况下,系统会创建一个 AppWidgetHostView,但主机可以 通过扩展 AppWidgetHostView 来创建自己的 AppWidgetHostView 子类。
    • 从 Android 12(API 级别 31)开始,AppWidgetHostView 引入了 该 setColorResources()resetColorResources() 用于处理动态过载颜色的方法。主机是 负责为这些方法提供颜色。
  • 选项包AppWidgetHost 使用选项包 将信息传达给 AppWidgetProvider 微件的显示方式(例如, 尺寸范围列表,以及 位于锁定屏幕或主屏幕上。通过这些信息, AppWidgetProvider 可根据方式和 以及它的显示位置您可以使用 updateAppWidgetOptions()updateAppWidgetSize() 来修改 widget 的 bundle。这两种方法都会触发 onAppWidgetOptionsChanged()AppWidgetProvider 进行回调。

绑定 widget

当用户向托管应用添加 widget 时,会发生一个称为“绑定”的过程。绑定 是指将特定应用微件 ID 与特定托管应用及 具体的 AppWidgetProvider

通过绑定 API,主机还可以为 绑定。若要使用此流程,您的应用必须声明 BIND_APPWIDGET 权限:

<uses-permission android:name="android.permission.BIND_APPWIDGET" />

但是,这只是第一步。在运行时,用户必须明确授予 权限,以允许其将 widget 添加到托管应用。要测试您的 应用有权添加 widget,请使用 bindAppWidgetIdIfAllowed() 方法。如果 bindAppWidgetIdIfAllowed() 返回 false,您的应用必须显示 提示用户授予权限的对话框:“允许”当前 widget 所对应的 添加,或“始终允许”以涵盖将来增加的所有 widget。

以下代码段举例说明了如何显示该对话框:

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);

托管应用必须检查用户添加的 widget 是否需要配置。对于 请参阅允许用户配置应用 微件

托管方责任

您可以使用 AppWidgetProviderInfo 元数据。 您可以检索这些配置选项, (从 AppWidgetProviderInfo 与 widget 提供程序相关联的对象。

无论您适配的 Android 版本是什么,所有托管应用都有 以下职责:

  • 添加微件时,请按上文所述分配微件 ID。当 从托管应用中移除 widget,调用 deleteAppWidgetId() 来取消分配微件 ID。

  • 添加 widget 时,检查是否需要配置 activity 。通常,托管应用需要启动 widget 的配置 (如果存在)且未通过同时指定 configuration_optionalreconfigurable 标志。请参阅 从配置 activity 更新 widget 了解详情。对于许多微件来说,这是显示前必不可少的一步。

  • widget 会在 AppWidgetProviderInfo 中指定默认宽度和高度 元数据。这些值在单元格中定义,从 Android 12(如果 targetCellWidthtargetCellHeight) 或 dps(如果仅指定了 minWidthminHeight)。请参阅 微件大小调整属性

    请确保 widget 的布局中至少包含这么多 dp。对于 例如,许多托管应用会在网格中对齐图标和微件。在这种情况下 默认情况下,托管应用会以最少数量的单元格 它们满足 minWidthminHeight 约束条件。

除了上一部分中列出的要求之外, 平台版本引入的新功能将新的责任 主机。

根据目标 Android 版本确定方法

Android 12

Android 12(API 级别 31)捆绑了一个包含列表的额外 List<SizeF> 微件实例在选项包中可以采用的可能大小(以 dp 为单位)。 所提供的尺寸数量取决于主机的实现情况。通常由主机托管 针对手机提供两种尺寸:纵向和横向,以及四种尺寸 可折叠设备

每个 Google 账号的MAX_INIT_VIEW_COUNT AppWidgetProvider 可以提供的 RemoteViewsRemoteViews。 由于 AppWidgetProvider 对象会将 RemoteViews 对象映射到 List<SizeF>,则不要提供超过 MAX_INIT_VIEW_COUNT 个尺寸。

Android 12 还引入了 maxResizeWidthmaxResizeHeight 属性(以 dps 为单位)。我们建议微件至少使用其中一个 不能超过属性指定的大小。

其他资源

  • 请参阅 Glance 参考文档。