使用直接分享目标,让其他应用的用户能够更轻松、更快速地与您的应用分享网址、图片或其他类型的数据。直接分享功能的运作方式是,直接在 Android Sharesheet 中显示即时通讯应用和社交应用中的联系人,无需用户选择应用,然后搜索联系人。
ShortcutManagerCompat
是一个 AndroidX API,提供向后兼容已废弃的 ChooserTargetService
API 的共享快捷方式。这是发布共享快捷方式和 ChooserTargets
的首选方式。如需了解相关说明,请参阅本页上的使用 AndroidX 提供共享快捷方式和 ChooserTarget。
发布直接共享目标
Sharesheet 直接共享行仅显示 Sharing Shortcuts API 提供的动态快捷方式。如需发布直接分享目标,请完成以下步骤。
在应用的 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>
在应用初始化时,使用
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);
如果您正在开发通信应用,请在用户每次接收或向联系人发送消息时,立即通过
pushDynamicShortcut
报告快捷方式使用情况。如需了解详情,请参阅本页上的报告通信应用的快捷方式使用情况。例如,通过ShortcutInfoCompat.Builder#addCapabilityBinding
使用actions.intent.SEND_MESSAGE
capability 在快捷方式中指定 capability 绑定,以报告用户发送的消息的使用情况。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);
如果用户删除了联系人,请使用
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 或彩信功能,您将不会将相应的快捷方式与非文本 MIME 类型(例如image/*
和video/*
)相关联。 - 对于给定对话,在推送动态快捷方式并报告使用情况后,请勿更改快捷方式 ID。这样可确保保留使用情况数据以进行排名。
如果用户点按任何直接共享目标,您的应用必须将用户转到一个界面,让用户能够直接对目标主题执行操作。请勿向用户显示信息确认界面,也不要将用户转到与所点按的目标无关的界面。例如在即时通讯应用中,点按直接共享目标应将用户转到与所选人员进行对话的视图。键盘处于可见状态,并且消息中预填了共享的数据。
Sharing Shortcuts API
从 Android 10(API 级别 29)开始,ShortcutInfo.Builder
添加了一些方法和增强功能,可提供有关共享目标的更多信息:
setCategories()
- 从 Android 10 开始,类别也用于过滤可以处理共享 intent 或操作的快捷方式。如需了解详情,请参阅声明共享目标。对于要用作共享目标的快捷方式,必须填写此字段。
setLongLived()
指定快捷方式在由应用取消发布或设为不可见后(作为动态或固定快捷方式)是否有效。如果某个快捷方式长期存在,则可能被各种系统服务缓存,即使已取消发布为动态快捷方式也是如此。
使快捷方式长期存在有助于提高其排名。如需了解详情,请参阅获得最佳排名。
setShortLabel()
、setLongLabel()
发布单个 Person 的快捷方式时,请在
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 中选择与上述 share-target 示例相匹配的共享快捷方式,应用将获得以下共享 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
重新发布代表联系人的对话快捷方式。
快捷方式使用和 capability 绑定向后兼容 Android 5.0(API 21)。
报告外发邮件的快捷方式使用情况
报告用户发送的消息的使用情况在功能上类似于在创建消息后点击“发送”按钮。
如需触发使用情况报告,请使用 actions.intent.SEND_MESSAGE
capability 通过 ShortcutInfoCompat.Builder#addCapabilityBinding
在快捷方式中指定 capability 绑定。
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);
报告收到的消息的快捷方式使用情况
如需在用户收到短信、聊天消息、电子邮件或通知等消息时触发使用情况报告,您还必须通过 ShortcutInfoCompat.Builder#addCapabilityBinding
使用 actions.intent.RECEIVE_MESSAGE
capability 在快捷方式中指定 capability 绑定。
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。Sharing Shortcuts API 允许应用提前发布直接共享目标,而不是被动地按需检索结果。这在准备 ShareSheet 时大幅加快了检索直接共享目标的速度。ChooserTargetService
直接共享机制将继续有效,但系统会将以这种方式提供的目标的排名排在使用 Sharing Shortcuts API 提供的目标之下。
Android 11(API 级别 30)已废弃 ChooserTargetService
服务,并且 Sharing Shortcuts API 是提供直接共享目标的唯一方式。
共享目标的已发布快捷方式与启动器快捷方式(长按启动器中的应用图标时通常使用这些快捷方式)有何不同?
为“共享目标”发布的快捷方式也是一种启动器快捷方式,当长按您的应用图标时,它会显示在菜单中。每个 activity 的快捷方式数量上限也适用于应用发布的快捷方式总数(共享目标和旧版启动器快捷方式数量之和)。
关于应发布的共享快捷方式数量,有哪些指导性建议?
共享快捷方式的数量受通过 getMaxShortcutCountPerActivity(android.content.Context)
提供的动态快捷方式数量的限制。您可以发布不超过此限制的任何数量,但必须注意,分享快捷方式可能会显示在应用启动器的长按菜单和分享表格中。大多数应用启动器在长按时,竖屏模式下最多可显示 4 个或 5 个快捷方式,横屏模式下最多可显示 8 个快捷方式。如需详细了解如何分享快捷方式,请参阅此常见问题解答。