管理快捷方式

创建快捷方式后,您可能需要在应用的生命周期内管理它们。例如,您可能希望通过确定用户使用快捷方式完成特定操作的频率来优化您的应用。在另一种情况下,您可能决定禁用固定快捷方式,以防止您的应用执行过时或缺失的操作。对于对话中引用的快捷方式,您可能希望跟踪使用情况以提供改进快捷方式排名的信号。

此页面描述了这些以及其他几种常见的管理快捷方式的方法。

快捷方式行为

以下部分包含有关快捷方式行为的一般信息,包括可见性、显示顺序和排名。

快捷方式可见性

当用户执行特定手势或语音命令时,静态快捷方式和动态快捷方式会出现在支持的启动器或助手上。在支持的启动器上,手势是按住应用的启动器图标,但在其他启动器应用上,手势可能有所不同。使用 Google 助理,快捷方式可以在助理中显示或从用户语音命令启动。

LauncherApps 类为启动器应用提供了访问快捷方式的 API。

由于固定快捷方式出现在启动器本身中,因此它们始终可见。仅在以下情况下,固定快捷方式才会从启动器中删除

  • 用户将其移除。
  • 与快捷方式关联的应用已卸载。
  • 用户通过转到设置 > 应用和通知,选择应用,然后点击存储 > 清除存储空间来清除应用数据。

共享目标 是出现在 Android 共享表单的直接共享行中的动态快捷方式的子集。

A screenshot of Android Sharesheet
图 1. Android 共享表单。直接共享目标出现在第一行,然后是排名应用,最后是应用列表。

快捷方式显示顺序

当启动器显示应用的快捷方式时,它们必须按以下顺序显示

  1. 静态快捷方式:其 isDeclaredInManifest() 方法返回 true 的快捷方式。
  2. 动态快捷方式:其 ShortcutInfo.isDynamic() 方法返回 true 的快捷方式。

在每种快捷方式类型(静态和动态)中,快捷方式都根据 ShortcutInfo.getRank排名升序排序。Google 助理在确定要向用户显示的上下文快捷方式时也会考虑快捷方式排名。

排名是非负的连续整数。静态快捷方式按其在 shortcuts.xml 文件中出现的顺序从前到后排序。对于动态快捷方式,当您调用 updateShortcuts(Context, List)addDynamicShortcuts(Context, List)pushDynamicShortcut(Context, ShortcutInfoCompat)setDynamicShortcuts(Context, List) 时,您可以更新现有快捷方式的排名。

共享目标的顺序基于各种因素,包括过去的用户历史记录、最近使用情况、频率、排名提示、应用使用情况以及与共享快捷方式关联的对话中设置的优先级。使用 共享快捷方式 API 创建的共享目标优先于 Android 11 中已弃用的 ChooserTargetService 生成的共享目标。在 Android 12 及更高版本中,已弃用的 ChooserTargetService 生成的共享目标将不再出现在共享表单中。

大多数启动器最多显示四个快捷方式。对于定义的任何静态快捷方式和动态快捷方式组合,启动器最多显示两个静态快捷方式和两个动态快捷方式。例如,如果您定义了四个静态快捷方式并以编程方式创建了三个动态快捷方式,则启动器将显示前两个静态快捷方式和两个排名最高的动态快捷方式。

管理多个意图和活动

如果您希望您的应用在用户激活快捷方式时执行多个操作,您可以将其配置为触发连续的活动。您可以通过分配多个意图、从一个活动启动另一个活动或设置意图标志来实现此目的,具体取决于快捷方式的类型。

分配多个意图

使用 ShortcutInfoCompat.Builder 创建快捷方式时,您可以使用 setIntents() 而不是 setIntent()。通过调用 setIntents(),当用户选择快捷方式时,您可以在应用中启动多个活动,并将列表中除最后一个活动之外的所有活动放在后退 上。如果用户随后点击设备的后退按钮,他们会看到应用中的另一个活动,而不是返回到设备的启动器。

从一个活动启动另一个活动

静态快捷方式不能有自定义意图标志。静态快捷方式的第一个意图始终具有 Intent.FLAG_ACTIVITY_NEW_TASKIntent.FLAG_ACTIVITY_CLEAR_TASK 设置。这意味着,当您的应用正在运行时,当启动静态快捷方式时,应用中的所有现有活动都将被销毁。如果您不希望出现此行为,则可以使用跳板活动——一个不可见的活动,它在 Activity.onCreate(Bundle) 调用 Activity.finish() 的活动——启动另一个活动。

  1. AndroidManifest.xml 文件中,在跳板活动中包含属性赋值 android:taskAffinity=""。
  2. 在快捷方式资源文件中,在静态快捷方式中的意图中引用跳板活动。

有关跳板活动的更多信息,请参阅 从一个活动启动另一个活动

设置意图标志

您可以使用任何一组 Intent 标志发布动态快捷方式。最好将 Intent.FLAG_ACTIVITY_CLEAR_TASK 与您的其他标志一起指定。否则,如果您尝试在应用运行时启动另一个任务,则目标活动可能不会出现。

要了解有关任务和意图标志的更多信息,请参阅 任务和后退栈

更新快捷方式

每个应用的启动器图标最多可以包含的静态和动态快捷方式的组合数量等于 getMaxShortcutCountPerActivity 返回的值。应用可以创建的固定快捷方式数量没有限制。

当动态快捷方式被固定时,即使发布者将其作为动态快捷方式移除,固定快捷方式仍然可见且可启动。这允许应用拥有超过 getMaxShortcutCountPerActivity() 个快捷方式。

考虑以下示例,该示例假设 getMaxShortcutCountPerActivity() 返回的值为 4

  1. 一个聊天应用发布了四个动态快捷方式,代表四个最近的对话:c1、c2、c3 和 c4。
  2. 用户固定了所有四个快捷方式。
  3. 稍后,用户启动了另外三个对话:c5、c6 和 c7。发布者应用重新发布其动态快捷方式。新的动态快捷方式列表为:c4、c5、c6 和 c7。

应用必须删除 c1、c2 和 c3,因为它不能显示超过四个动态快捷方式。但是,c1、c2 和 c3 仍然是用户可以访问和启动的固定快捷方式。

然后,用户可以访问总共七个链接到发布者应用中活动的快捷方式。这是因为总数包括快捷方式的最大数量和三个固定快捷方式。

  1. 应用可以使用 updateShortcuts(Context, List) 更新任何七个现有快捷方式中的任何一个。例如,当聊天伙伴的图标发生变化时,您可能会更新此快捷方式集。
  2. 您可以使用addDynamicShortcuts(Context, List)setDynamicShortcuts(Context, List) 方法来更新具有相同 ID 的现有快捷方式。但是,您不能使用它们来更新非动态的、已固定的快捷方式,因为这两种方法都尝试将给定的快捷方式列表转换为动态快捷方式。

在 Google 助理等助手应用上显示的快捷方式数量没有限制。使用 pushDynamicShortcut() 方法(位于 ShortcutManagerCompat Jetpack 库中)来创建和更新助手应用中使用的快捷方式。此外,将 Google 快捷方式集成库 添加到您的应用中,以使动态链接有资格出现在 Google 助理上。

要详细了解应用快捷方式指南,包括更新快捷方式,请参阅 快捷方式最佳实践

处理系统区域设置更改

当应用收到指示系统区域设置更改的 Intent.ACTION_LOCALE_CHANGED 广播时,必须更新动态和已固定的快捷方式。

跟踪快捷方式使用情况

为了确定静态和动态快捷方式出现的具体情况,启动器会检查快捷方式的激活历史记录。对于静态快捷方式,您可以通过调用 reportShortcutUsed() 方法并在以下任一事件发生时传递快捷方式的 ID 来跟踪用户何时在应用中完成特定操作

  • 用户选择具有给定 ID 的快捷方式。
  • 在应用内,用户手动完成与同一快捷方式对应的操作。

您的应用通过调用 pushDynamicShortcut() 方法并在相关事件发生时传递快捷方式的 ID 来跟踪动态快捷方式的使用情况。使用此方法推送动态快捷方式的使用情况,可以让 Google 助理等助手应用向用户推荐相关的快捷方式。由于 pushDynamicShortcut() 方法在被调用时会报告使用情况,因此不要对同一快捷方式调用 reportShortcutUsed() 方法。

对于与对话相关的快捷方式,跟踪传出和传入消息的使用情况非常重要。有关详细信息,请参阅 人员和对话最佳实践

禁用快捷方式

由于您的应用及其用户可以将快捷方式固定到设备的启动器,因此这些固定的快捷方式可能会将用户引导至应用中已过时或不再存在的操作。为了管理这种情况,您可以通过调用 disableShortcuts 来禁用您不希望用户选择的快捷方式,该方法会从静态和动态快捷方式列表中删除指定的快捷方式,并禁用这些快捷方式的固定副本。您还可以使用此方法的重载版本,该版本接受 CharSequence 作为自定义错误消息。然后,当用户尝试启动任何禁用的快捷方式时,该错误消息将显示。

速率限制

使用 setDynamicShortcuts()addDynamicShortcuts()updateShortcuts() 方法时,您可能只能在后台应用(即没有活动或服务在前台运行的应用)中调用这些方法特定次数。可以调用这些方法的特定次数的限制称为速率限制。此功能可防止 ShortcutManagerCompat 过度消耗设备资源。

当速率限制处于活动状态时,isRateLimitingActive() 返回 true。但是,速率限制会在某些事件期间重置,因此即使是后台应用也可以调用 ShortcutManager 方法,直到再次达到速率限制。这些事件包括以下内容

  • 应用进入前台。
  • 系统区域设置更改。
  • 用户对通知执行 内联回复 操作。

如果在开发或测试过程中遇到速率限制,您可以从 设备设置 中选择开发者选项 > 重置 ShortcutManager 速率限制,或者您可以在 adb 中输入以下命令

$ adb shell cmd shortcut reset-throttling [ --user your-user-id ]

备份和恢复

当用户更改设备时,您可以通过在应用的清单文件中包含 android:allowBackup="true" 属性赋值来允许用户对应用执行备份和恢复操作。如果您支持备份和恢复,请牢记以下关于应用快捷方式的要点

  • 静态快捷方式会自动重新发布,但仅在用户在新设备上重新安装应用后才会重新发布。
  • 动态快捷方式不会备份,因此请在应用中包含逻辑,以便在用户在新设备上打开应用时重新发布这些快捷方式。
  • 已固定的快捷方式会自动恢复到设备的启动器,但系统不会备份与已固定的快捷方式关联的图标。因此,请将已固定的快捷方式的图像保存在应用中,以便于在新设备上恢复它们。

以下代码片段显示了如何最好地恢复应用的动态快捷方式以及如何检查应用的已固定快捷方式是否已保留

Kotlin

class MyMainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (ShortcutManagerCompat.dynamicShortcuts.size == 0) {
            // Application restored. Re-publish dynamic shortcuts.
            if (ShortcutManagerCompat.pinnedShortcuts.size > 0) {
                // Pinned shortcuts are restored. Use updateShortcuts() to make
                // sure they contain up-to-date information.
            }

        }
    }
    // ...
}

Java

public class MainActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (ShortcutManagerCompat.getDynamicShortcuts().size() == 0) {
            // Application restored. Re-publish dynamic shortcuts.
            if (ShortcutManagerCompat.getPinnedShortcuts().size() > 0) {
                // Pinned shortcuts are restored. Use pdateShortcuts() to make
                // sure they contain up-to-date information.
            }
        }
    }
    // ...
}