提供直接共享目标

图 1 :Sharesheet 中的“直接共享”行,如 1 所示

借助“直接分享”目标,其他应用的用户能够更轻松快捷地与您的应用分享网址、图片或其他类型的数据。直接分享功能的工作原理是,直接在 Android Sharesheet 上显示即时通讯和社交应用中的联系人,而无需用户先选择应用再搜索联系人。

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

发布直接共享目标

Sharesheet 直接共享行仅显示由 Sharing Shortcuts API 提供的动态快捷方式。如需发布直接共享目标,请完成以下步骤。

  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 报告快捷方式的使用情况。如需了解详情,请参阅本页中的报告通信应用的快捷方式使用情况。例如,如需报告用户发送的消息的使用情况,请通过包含 actions.intent.SEND_MESSAGE 功能的 ShortcutInfoCompat.Builder#addCapabilityBinding 在快捷方式中指定功能绑定。

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

提高您的直接共享目标的排名

Android Sharesheet 显示固定数量的直接共享目标,这些建议按排名进行排序。通过执行以下操作,您或许可以提高快捷方式的排名:

  • 请确保所有 shortcutIds 都是唯一的,并且绝不会针对不同的目标重复使用。
  • 通过调用 setLongLived(true) 确保快捷方式长期存在。
  • 对于与对话相关的快捷方式,请通过 ShortcutManagerCompat.pushDynamicShortcut 重新发布相应的快捷方式,以报告外发和传入消息的快捷方式使用情况。如需了解详情,请参阅本页面中的报告通信应用的快捷方式使用情况
  • 避免提供不相关或过时的直接共享目标,例如,用户在过去 30 天内未向其发送消息的联系人。
  • 对于短信应用,请避免为被识别为垃圾内容的短号码或对话提供快捷方式。用户不太可能与这些对话分享内容。
  • 调用 setCategories() 以将快捷方式与适当的 mimeType 属性相关联。例如,对于短信应用,如果联系人未启用 RCS 或 MMS,您就不会将相应的快捷方式与非文本 MIME 类型(例如 image/*video/*)相关联。
  • 对于给定的对话,在推送动态快捷方式并报告使用情况后,不要更改快捷方式 ID。这样可确保保留使用情况数据以进行排名。

如果用户点按任何直接共享目标,您的应用必须将用户转到一个界面,在界面中,用户可以直接对目标对象执行操作。不要向用户显示消除歧义界面,也不要将其放置在与点按的目标无关的界面中。例如,在即时通讯应用中,点按直接共享目标会将用户转到与所选人员的对话视图。键盘可见,且消息已预填充共享数据。

Sharing Shortcuts API

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

setCategories()
从 Android 10 开始,还可使用类别来过滤可处理共享 intent 或操作的快捷方式。如需了解详情,请参阅声明共享目标。要用作共享目标的快捷方式必须填写此字段。
setLongLived()

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

使快捷方式长期存在有助于提高其排名。如需了解详情,请参阅获得最佳排名

setShortLabel()setLongLabel()

发布个人快捷方式时,请在 setLongLabel() 中添加其全名,在 setShortLabel() 中添加昵称或名字等简称。

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

提供快捷方式图像

要制作共享快捷方式,你需要通过 setIcon() 添加图片。

共享快捷方式可以跨系统 surface 显示,并且可能会被改变形状。此外,某些搭载 Android 版本 7、8 或 9(API 级别 25、26、27 和 28)的设备可能会显示没有背景的纯位图图标,这会大幅降低对比度。为确保快捷方式的显示效果符合预期,请使用 IconCompat.createWithAdaptiveBitmap() 提供自适应位图。

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

不要提供框在特定形状中的图像。例如,在 Android 10(API 级别 29)之前,经常会为直接共享 ChooserTarget 提供遮盖于圆形的用户头像。现在,Android 10 中的 Android Sharesheet 和其他系统 surface 可为快捷方式图像设置形状和主题。通过 ShortcutManagerCompat 提供共享快捷方式的首选方法会自动为您将反向兼容直接共享 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>

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

如果用户在 Android Sharesheet 中选择与上述目标共享示例匹配的共享快捷方式,应用将获得以下共享 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 Sharesheet 中的排名。为此,请通过 ShortcutManagerCompat.pushDynamicShortcut 重新发布表示联系人的对话快捷方式。

快捷方式的使用和功能绑定可向后兼容 Android 5.0 (API 21)。

报告外发邮件的快捷键使用情况

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

如需触发用量报告,请通过具有 actions.intent.SEND_MESSAGE 功能的 ShortcutInfoCompat.Builder#addCapabilityBinding 在快捷方式中指定功能绑定。

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 类型与 capability 相关联。

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

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

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

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 类型与 capability 相关联。

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 提供共享快捷方式和 ChooserTarget

为了能够使用 AndroidX 兼容性库,应用的清单必须包含元数据 chooser-target-service 和 intent-filter 集。请参阅当前的 ChooserTargetService Direct Share API。

此服务已在兼容性库中声明,因此用户无需在应用清单中声明此服务。不过,必须将从共享 activity 到服务的链接视为选择器目标提供程序。

在以下示例中,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 以及人名和资源的名称)只能由系统服务和发布快捷方式的同一应用访问。

直接共享功能的历史是怎样的?

我们在 Android 6.0(API 级别 23)中引入了直接共享功能,以允许应用通过 ChooserTargetService 提供 ChooserTarget 对象。结果是被动地按需检索,导致目标加载时间较长。

在 Android 10(API 级别 29)中,我们已将 ChooserTargetService Direct Share API 替换为新的 sharing Shortcuts API。Share Shortcuts API 可让应用提前发布直接共享目标,而不是被动地检索结果。这加快了在准备 ShareSheet 时检索直接共享目标的过程。ChooserTargetService 直接共享机制将继续有效,但以这种方式提供的目标的排名要低于任何使用 Share Shortcuts API 的目标。

Android 11(API 级别 30)废弃了 ChooserTargetService 服务,Sharing Shortcuts API 是提供直接共享目标的唯一方式。

共享目标的已发布快捷方式与启动器快捷方式(长按启动器中的应用图标时通常使用这些快捷方式)有何不同?

出于“共享目标”目的发布的任何快捷方式也是一种启动器快捷方式,当您长按应用的图标时,它会显示在菜单中。每个 activity 的快捷方式计数上限也适用于应用要发布的快捷方式的总数(共享目标和旧版启动器快捷方式数之和)。

关于应发布多少共享快捷方式的指南?

共享快捷方式的数量受通过 getMaxShortcutCountPerActivity(android.content.Context) 提供的动态快捷方式数量的限制。您可以根据该限制发布任意数量的数字,但必须注意,共享快捷方式可通过应用启动器长按和共享表单显示。大多数长按的应用启动器在竖屏模式下最多显示 4 个或 5 个快捷方式,在横屏模式下最多显示 8 个。如需了解更多详情和有关共享快捷方式的指导,请参阅此常见问题解答