提供 Direct Share 目标

图 1:分享表单中的 Direct Share 行,如 1 所示

通过 Direct Share 目标,其他应用的用户可以更轻松、更快速地与您的应用共享网址、图片或其他类型的数据。Direct Share 的工作原理是将消息和社交应用中的联系人直接显示在 Android 分享表单中,用户无需先选择应用再搜索联系人。

ShortcutManagerCompat 是一个 AndroidX API,它提供分享快捷方式,并且向后兼容已弃用的 ChooserTargetService API。这是发布分享快捷方式和 ChooserTargets 的首选方法。如需了解相关说明,请参阅本页面上的使用 AndroidX 提供分享快捷方式和 ChooserTargets

发布 Direct Share 目标

分享表单 Direct Share 行仅显示由分享快捷方式 API 提供的动态快捷方式。完成以下步骤即可发布 Direct Share 目标。

  1. 在应用的 XML 资源文件中,声明 share-target 元素。

    <shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
    <share-target android:targetClass="com.example.android.sharingshortcuts.SendMessageActivity">
        <data android:mimeType="text/plain" />
        <category android:name="com.example.android.sharingshortcuts.category.TEXT_SHARE_TARGET" />
    </share-target>
    </shortcuts>
    
  2. 应用初始化时,使用 setDynamicShortcuts 按重要程度排列动态快捷方式。

    索引越低表示越重要。如果您正在开发通信应用,可以将最重要的对话按您应用中的显示顺序排列。不要发布过期的快捷方式;近 30 天内没有用户活动的对话被视为过期。

    Kotlin

    ShortcutManagerCompat.setDynamicShortcuts(myContext, listOf(shortcut1, shortcut2, ..))

    Java

    List<ShortcutInfoCompat> shortcuts = new ArrayList<>();
    shortcuts.add(shortcut1);
    shortcuts.add(shortcut2);
    ...
    ShortcutManagerCompat.setDynamicShortcuts(myContext, shortcuts);
  3. 如果您正在开发通信应用,则每当用户接收或向联系人发送消息时,请立即通过 pushDynamicShortcut 报告快捷方式使用情况。如需了解详情,请参阅本页面上的报告通信应用快捷方式使用情况。例如,通过 ShortcutInfoCompat.Builder#addCapabilityBinding 指定快捷方式中的功能绑定并使用 actions.intent.SEND_MESSAGE 功能,即可报告用户发送消息的使用情况。

    Kotlin

    val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
      ...
      .setShortLabel(firstName)
      .setLongLabel(fullName)
      .setCategories(matchedCategories)
      .setLongLived(true)
    .addCapabilityBinding("actions.intent.SEND_MESSAGE").build()
    ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)

    Java

    ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
      ...
      .setShortLabel(firstName)
      .setLongLabel(fullName)
      .setCategories(matchedCategories)
      .setLongLived(true)
      .addCapabilityBinding("actions.intent.SEND_MESSAGE")
      .build();
    
    ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);
  4. 如果用户删除了联系人,请使用 removeLongLivedShortcut。这是移除快捷方式的首选方法,无论其是否由系统服务缓存。以下代码片段展示了如何执行此操作的示例。

    Kotlin

    val deleteShortcutId = "..."
    ShortcutManagerCompat.removeLongLivedShortcuts(myContext, listOf(deleteShortcutId))

    Java

    String deleteShortcutId = "...";
    ShortcutManagerCompat.removeLongLivedShortcuts(
        myContext, Arrays.asList(deleteShortcutId));

提高 Direct Share 目标的排名

Android 分享表单显示固定数量的 Direct Share 目标。这些建议按排名排序。您可以通过以下方法提高快捷方式的排名

  • 确保所有 shortcutIds 都是唯一的,并且不会用于不同的目标。
  • 通过调用 setLongLived(true),确保快捷方式是长期的。
  • 对于与对话相关的快捷方式,通过 ShortcutManagerCompat.pushDynamicShortcut 重新发布相应的快捷方式,从而报告收发消息的快捷方式使用情况。有关详情,请参阅本页面上的报告通信应用快捷方式使用情况
  • 避免提供不相关或过期的 Direct Share 目标,例如用户在过去 30 天内没有发送消息的联系人。
  • 对于短信应用,避免提供针对短号码或被识别为潜在垃圾邮件的对话的快捷方式。用户极不可能分享到这些对话。
  • 调用 setCategories(),将快捷方式与适当的 mimeType 属性相关联。例如,对于短信应用,如果联系人未启用 RCS 或彩信,则不会将相应的快捷方式与 image/*video/* 等非文本 MIME 类型相关联。
  • 对于给定的对话,动态快捷方式被推送并报告使用情况后,不要更改快捷方式 ID。这确保了用于排名的使用数据的保留。

如果用户点按了任何 Direct Share 目标,您的应用必须将其定向到一个 UI,用户可以直接在该 UI 中对目标对象执行操作。不要向用户显示歧义消除 UI,也不要将他们置于与所点按目标无关的 UI 中。例如,在消息应用中,点按 Direct Share 目标会将用户定向到与所选人员的对话视图。键盘可见,并且消息已使用共享数据预填充。

分享快捷方式 API

从 Android 10(API 级别 29)开始,ShortcutInfo.Builder 增加了提供关于分享目标的更多信息的方法和增强功能

setCategories()
从 Android 10 开始,类别也用于过滤可以处理分享 Intent 或操作的快捷方式。有关详情,请参阅声明分享目标。用作分享目标的快捷方式必须包含此字段。
setLongLived()

指定快捷方式在被应用取消发布或设为不可见(作为动态或固定快捷方式)时是否有效。如果快捷方式是长期的,则即使在作为动态快捷方式被取消发布后,它仍可由各种系统服务缓存。

将快捷方式设为长期可以提高其排名。有关详情,请参阅获得最佳排名

setShortLabel(), setLongLabel()

向个人发布快捷方式时,请在 setLongLabel() 中包含他们的全名,并在 setShortLabel() 中包含任何短名称,例如昵称或名字。

查看一个在 GitHub 上发布分享快捷方式的示例。

提供快捷方式图像

要制作分享快捷方式,您需要通过 setIcon() 添加图像。

分享快捷方式可以显示在系统界面的各个位置,并且可能会被重塑。此外,某些运行 Android 7、8 或 9(API 级别 25、26、27 和 28)的设备可能会显示没有背景的仅位图图标,这会显著降低对比度。为确保您的快捷方式按预期显示,请使用 IconCompat.createWithAdaptiveBitmap() 提供自适应位图。

确保自适应位图遵循针对自适应图标设置的相同指南和尺寸。最常见的方法是将预期方形位图缩放至 72x72 dp,并将其居中放置在 108x108 dp 的透明画布中。如果您的图标包含透明区域,则需要包含背景颜色;否则,透明区域会显示为黑色。

请勿提供遮罩为特定形状的图像。例如,在 Android 10(API 级别 29)之前,通常为 Direct Share ChooserTarget 提供遮罩为圆形的头像。Android 10 中的 Android 分享表单和其他系统界面现在会对快捷方式图像进行塑形和主题化。通过 ShortcutManagerCompat 提供分享快捷方式的首选方法会自动将向后兼容的 Direct Share ChooserTarget 对象塑形为圆形。

声明分享目标

分享目标必须在应用的资源文件中声明,类似于静态快捷方式定义。将分享目标定义添加到资源文件中的 <shortcuts> 根元素内,与其他静态快捷方式定义一起。每个 <share-targets> 元素包含有关共享数据类型、匹配类别以及将处理分享 Intent 的目标类的信息。XML 代码示例如下

<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
  <share-target android:targetClass="com.example.android.sharingshortcuts.SendMessageActivity">
    <data android:mimeType="text/plain" />
    <category android:name="com.example.android.sharingshortcuts.category.TEXT_SHARE_TARGET" />
  </share-target>
</shortcuts>

分享目标中的 data 元素类似于 Intent 过滤器的 data 规范。每个分享目标可以有多个类别,这些类别仅用于将应用发布的快捷方式与其分享目标定义进行匹配。类别可以具有任何任意的应用定义值。

如果用户在 Android 分享表单中选择了与上述示例目标分享匹配的分享快捷方式,则应用将收到以下分享 Intent

Action: Intent.ACTION_SEND
ComponentName: {com.example.android.sharingshortcuts /
                com.example.android.sharingshortcuts.SendMessageActivity}
Data: Uri to the shared content
EXTRA_SHORTCUT_ID: <ID of the selected shortcut>

如果用户从启动器快捷方式打开分享目标,则应用将收到将分享快捷方式添加到 ShortcutManagerCompat 时创建的 Intent。由于这是不同的 Intent,因此 Intent.EXTRA_SHORTCUT_ID 将不可用,如果需要,您将必须手动传递 ID。

报告通信应用快捷方式使用情况

如果您正在开发通信应用,则可以通过报告收发消息的使用情况来提高您在 Android 分享表单中的排名。为此,请通过 ShortcutManagerCompat.pushDynamicShortcut 重新发布代表联系人的对话快捷方式。

快捷方式使用情况和功能绑定向后兼容至 Android 5.0(API 级别 21)。

报告发件消息的快捷方式使用情况

报告用户发送消息的使用情况在功能上类似于创建消息后点击“发送”按钮。

要触发使用情况报告,请通过 ShortcutInfoCompat.Builder#addCapabilityBinding 使用 actions.intent.SEND_MESSAGE 功能在快捷方式中指定功能绑定。

Kotlin

val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(firstName)
  .setLongLabel(fullName)
  .setCategories(matchedCategories)
  .setLongLived(true)
.addCapabilityBinding("actions.intent.SEND_MESSAGE").build()
ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)

Java

ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(firstName)
  .setLongLabel(fullName)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.SEND_MESSAGE")
  .build();

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);

如果发件消息是用于群聊,您还必须添加 Audience 参数值,因为 recipient 类型与该功能相关联。

Kotlin

val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(groupShortTitle)
  .setLongLabel(groupLongTitle)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.SEND_MESSAGE", "message.recipient.@type", listOf("Audience")).build()

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)

Java

ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(groupShortTitle)
  .setLongLabel(groupLongTitle)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.SEND_MESSAGE", "message.recipient.@type", Arrays.asList("Audience"))
  .build();

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);

报告收件消息的快捷方式使用情况

要在用户收到短信、聊天消息、电子邮件或通知等消息时触发使用情况报告,您必须通过 ShortcutInfoCompat.Builder#addCapabilityBinding 使用 actions.intent.RECEIVE_MESSAGE 功能在快捷方式中额外指定功能绑定。

Kotlin

val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(firstName)
  .setLongLabel(fullName)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.RECEIVE_MESSAGE").build()

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)

Java

ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(firstName)
  .setLongLabel(fullName)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.RECEIVE_MESSAGE")
  .build();

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);

如果收件消息来自群聊,您还必须添加 Audience 参数值,因为 sender 类型与该功能相关联。

Kotlin

val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(groupShortTitle)
  .setLongLabel(groupLongTitle)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.RECEIVE_MESSAGE", "message.sender.@type", listOf("Audience")).build()

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)

Java

ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(groupShortTitle)
  .setLongLabel(groupLongTitle)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.RECEIVE_MESSAGE", "message.sender.@type", Arrays.asList("Audience"))
  .build();

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);

使用 AndroidX 提供分享快捷方式和 ChooserTargets

为了能够使用 AndroidX 兼容性库,应用的清单必须包含 meta-data chooser-target-service 和 intent-filters 设置。请参阅当前的 ChooserTargetService Direct Share API。

此服务已在兼容性库中声明,因此用户无需在应用的清单中声明该服务。但是,必须将分享活动到该服务的链接作为选择器目标提供程序考虑在内。

在以下示例中,ChooserTargetService 的实现是 androidx.core.content.pm.ChooserTargetServiceCompat,这已在 AndroidX 中定义

<activity
    android:name=".SendMessageActivity"
    android:label="@string/app_name"
    android:theme="@style/SharingShortcutsDialogTheme">
    <!-- This activity can respond to Intents of type SEND -->
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
    <!-- Only needed if you import the sharetarget AndroidX library that
         provides backwards compatibility with the old DirectShare API.
         The activity that receives the Sharing Shortcut intent needs to be
         taken into account with this chooser target provider. -->
    <meta-data
        android:name="android.service.chooser.chooser_target_service"
        android:value="androidx.sharetarget.ChooserTargetServiceCompat" />
</activity>

分享快捷方式常见问题解答

快捷方式使用情况数据如何存储?它们会离开设备吗?

快捷方式完全存储在设备上,位于系统数据目录中的加密磁盘分区中。快捷方式中的信息(如图标、Intent 以及人员和资源的名称)仅可由系统服务和发布快捷方式的应用访问。

Direct Share 的历史是什么?

我们在 Android 6.0(API 级别 23)中引入了 Direct Share,允许应用通过 ChooserTargetService 提供 ChooserTarget 对象。结果按需响应式检索,导致目标加载时间缓慢。

在 Android 10(API 级别 29)中,我们用新的分享快捷方式 API 替换了 ChooserTargetService Direct Share API。分享快捷方式 API 不再按需响应式检索结果,而是让应用提前发布 Direct Share 目标。这大大加快了准备分享表单时检索 Direct Share 目标的过程。ChooserTargetService Direct Share 机制将继续有效,但系统会将以此方式提供的目标的排名低于使用分享快捷方式 API 的任何目标。

Android 11(API 级别 30)弃用了 ChooserTargetService 服务,分享快捷方式 API 是提供 Direct Share 目标的唯一方法。

为分享目标发布的快捷方式与启动器快捷方式(长按启动器中的应用图标时快捷方式的典型用法)有何不同?

任何出于“分享目标”目的发布的快捷方式,也是启动器快捷方式,会在长按应用图标时显示在菜单中。每个活动的最大快捷方式数量限制也适用于应用发布的快捷方式总数(分享目标和旧版启动器快捷方式的总和)。

关于应发布多少分享快捷方式,有什么指导意见?

分享快捷方式的数量受到通过 getMaxShortcutCountPerActivity(android.content.Context) 获取的动态快捷方式数量上限的限制。可以发布任意数量的快捷方式,但必须记住,分享快捷方式可以在应用启动器长按菜单和分享表单中可见。大多数应用启动器在纵向模式下长按时最多显示四个或五个快捷方式,在横向模式下显示八个。有关分享快捷方式的更多详细信息和指导,请参阅此常见问题解答