Use Direct Share targets to make it easier and faster for users of other apps to share URLs, images, or other kinds of data with your app. Direct Share works by presenting contacts from messaging and social apps directly on the Android Sharesheet, without users having to select the app then search for the contact.
ShortcutManagerCompat
is an AndroidX API that provides Sharing Shortcuts, and that is backward
compatible with the deprecated ChooserTargetService
API. This is the preferred
way to publish both Sharing Shortcuts and ChooserTargets
. For instructions,
see Use AndroidX to provide both Sharing Shortcuts andChooserTargets
on this page.
Publish Direct Share targets
The Sharesheet Direct Share row only surfaces dynamic shortcuts provided by the Sharing Shortcuts API. Complete the following steps to publish Direct Share targets.
In your app's XML resource file, declare
share-target
elements.<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>
When your app initializes, use
setDynamicShortcuts
to order dynamic shortcuts by importance.A lower index indicates more importance. If you're making a communication app, they can be top conversations ordered by recency as they appear in your app. Don't publish shortcuts that are stale; a conversation with no user activity in the last 30 days is considered stale.
Kotlin
ShortcutManagerCompat.setDynamicShortcuts(myContext, listOf(shortcut1, shortcut2, ..))
Java
List<ShortcutInfoCompat> shortcuts = new ArrayList<>(); shortcuts.add(shortcut1); shortcuts.add(shortcut2); ... ShortcutManagerCompat.setDynamicShortcuts(myContext, shortcuts);
If you're developing a communication app, report shortcut usage through
pushDynamicShortcut
immediately every time the user receives or sends a message to a contact. See Report shortcut usage for communications apps on this page for more information. For example, report usage for messages sent by the user by specifying capability bindings in the shortcut throughShortcutInfoCompat.Builder#addCapabilityBinding
with theactions.intent.SEND_MESSAGE
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);
If the user deletes a contact, use
removeLongLivedShortcut
. This is the preferred way to remove the shortcut regardless of whether it's cached by system services. The following code snippet shows an example of how to do this.Kotlin
val deleteShortcutId = "..." ShortcutManagerCompat.removeLongLivedShortcuts(myContext, listOf(deleteShortcutId))
Java
String deleteShortcutId = "..."; ShortcutManagerCompat.removeLongLivedShortcuts( myContext, Arrays.asList(deleteShortcutId));
Improve rankings of your Direct Share targets
The Android Sharesheet shows a fixed number of Direct Share targets. These suggestions are sorted by rank. You can potentially improve the ranking of your shortcuts by doing the following:
- Ensure all
shortcutIds
are unique and never reused for different targets. - Ensure the shortcut is long-lived by calling
setLongLived(true)
. - For conversation-related shortcuts, report shortcut usage
for outgoing and incoming messages by republishing corresponding shortcuts
through
ShortcutManagerCompat.pushDynamicShortcut
. See Report shortcut usage for communications apps on this page for details. - Avoid providing irrelevant or stale Direct Share targets—for example, contacts the user hasn't messaged within the last 30 days.
- For SMS apps, avoid providing shortcuts for short codes or conversations identified as potential spam. Users are highly unlikely to share to those conversations.
- Call
setCategories()
to associate the shortcut with the appropriatemimeType
attributes. For example, for an SMS app, if the contact is not RCS- or MMS-enabled, you wouldn't associate the corresponding shortcut with non-text MIME types such asimage/*
andvideo/*
. - For a given conversation, once a dynamic shortcut is pushed and usage is reported, don't change the shortcut ID. This ensures retention of usage data for ranking.
If the user taps any Direct Share target, your app must take them to a UI where they can perform an action directly on the subject of the target. Don't present the user a disambiguation UI, and don't place them in a UI unrelated to the tapped target. For example, in a messaging app, tapping a Direct Share target takes the user to a conversation view with the person they selected. The keyboard is visible and the message is prefilled with the shared data.
Sharing Shortcuts API
Starting in Android 10 (API level 29),
ShortcutInfo.Builder
added methods and enhancements
that provide additional info about the share target:
setCategories()
- Starting with Android 10, categories are also used to filter shortcuts that can handle share intents or actions. See Declare a share target for details. This field is required for shortcuts meant to be used as share targets.
setLongLived()
Specifies whether or not a shortcut is valid when it has been unpublished or made invisible by the app (as a dynamic or pinned shortcut). If a shortcut is long lived, it can be cached by various system services even after if has been unpublished as a dynamic shortcut.
Making a shortcut long lived can improve its ranking. See Get the best ranking for details.
setShortLabel()
,setLongLabel()
When publishing a shortcut to an individual person please include their full name in
setLongLabel()
and any short name, such as a nickname or a first name, insetShortLabel()
.
Look at an example of publishing Sharing Shortcuts on GitHub.
Provide shortcut imagery
To make a Sharing Shortcut, you'll need to add an image via setIcon()
.
Sharing Shortcuts can appear across system surfaces and might be reshaped.
Additionally, some devices running Android versions 7, 8, or 9 (API levels 25,
26, 27, and 28) might display bitmap‑only icons without a background, which
dramatically decreases contrast. To ensure your shortcut looks as intended,
provide an adaptive bitmap by using IconCompat.createWithAdaptiveBitmap()
.
Make sure adaptive bitmaps follow the same guidelines and dimensions set for adaptive icons. The most common way to accomplish this is to scale the intended square bitmap to 72x72 dp and center that within a 108x108 dp transparent canvas. If your icon includes transparent regions, you need to include a background color; otherwise, transparent regions appear black.
Do not provide imagery masked to a specific shape. For example, prior to
Android 10 (API level 29), it was common to provide user avatars for Direct Share
ChooserTarget
s that were masked to a circle. The Android Sharesheet and other
system surfaces in Android 10 now shape and theme shortcut imagery.
The preferred method to provide Sharing Shortcuts, through
ShortcutManagerCompat
,
automatically shape backcompat Direct Share ChooserTarget
objects to
circles for you.
Declare a share target
Share targets must be declared in the app's resource file, similar to static shortcuts definitions. Add share
target definitions inside the <shortcuts>
root element in the resource file,
along with other static shortcut definitions. Each <share-targets>
element
contains information about the shared data type, matching categories, and the
target class that will handle the share intent. The XML code looks something
like this:
<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>
The data element in a share target is similar to the data specification in an intent filter. Each share target can have multiple categories, which are only used to match an app's published shortcuts with its share target definitions. Categories can have any arbitrary app-defined values.
In case the user selects the Sharing Shortcut in the Android Sharesheet that matches with the example target-share above, the app will get the following share 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>
If the user opens the share target from the launcher shortcuts, the app will get
the intent that was created when adding the sharing shortcut to the
ShortcutManagerCompat.
Since it's a different intent, Intent.EXTRA_SHORTCUT_ID
won't be available,
and you will have to pass the ID manually if you need it.
Report shortcut usage for communication apps
If you're developing a communication app, you can improve your ranking in the
Android Sharesheet by reporting usage for both outgoing and incoming messages.
To do so, republish the conversation shortcut that represents the contact through
ShortcutManagerCompat.pushDynamicShortcut
.
Shortcut usage and capability bindings are backward compatible to Android 5.0 (API 21).
Report shortcut usage for outgoing messages
Reporting usage for messages sent by the user is functionally similar to clicking the "send" button after creating a message.
To trigger usage reporting, specify capability bindings in the shortcut
through ShortcutInfoCompat.Builder#addCapabilityBinding
with the actions.intent.SEND_MESSAGE
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);
If the outgoing message is for a group chat, you must also add the Audience
parameter value as the recipient
type is associated with the 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);
Report shortcut usage for incoming messages
To trigger usage reporting when the user receives a message such as an SMS,
chat message, email, or notifications, you must additionally specify capability
bindings in the shortcut through
ShortcutInfoCompat.Builder#addCapabilityBinding
with
the actions.intent.RECEIVE_MESSAGE
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);
If the incoming message is from a group chat, you must also add the Audience
parameter value as the sender
type
is associated with the 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);
Use AndroidX to provide both Sharing Shortcuts and ChooserTargets
To be able to work with the AndroidX compatibility library, the app's manifest
must contain the meta-data chooser-target-service and intent-filters set. See
the current ChooserTargetService
Direct Share API.
This service is already declared in the compatibility library, so the user does not need to declare the service in the app's manifest. However, the link from the share activity to the service must be taken into account as a chooser target provider.
In the following example, the implementation of ChooserTargetService
is
androidx.core.content.pm.ChooserTargetServiceCompat
, which is already defined
in 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>
Sharing Shortcuts FAQ
How are the shortcut usage data stored and do they leave the device?
Shortcuts are stored entirely on-device in the system data directory in an encrypted disk partition. Information in shortcuts such as the icon, the intent, and names of people and resources are accessible only by system services and the same app that publishes the shortcuts.
What is the history of Direct Share?
We introduced Direct Share in Android 6.0 (API level 23) to allow apps to
provide ChooserTarget
objects through a ChooserTargetService
. Results were
retrieved reactively on demand, leading to a slow loading time for targets.
In Android 10 (API level 29), we replaced the ChooserTargetService
Direct
Share APIs with the new Sharing Shortcuts API. Instead of retrieving results
reactively on demand, the Sharing Shortcuts API let apps publish Direct Share
targets in advance. This rapidly sped up the process of retrieving Direct Share
targets when preparing the ShareSheet. The ChooserTargetService
Direct Share
mechanism will continue to work, but the system ranks targets that are provided
this way lower than any target that uses the Sharing Shortcuts API.
Android 11 (API level 30) deprecated the ChooserTargetService
service, and
Sharing Shortcuts API is the only way to provide Direct Share targets.
How are published shortcuts for share targets different from launcher shortcuts (the typical usage of shortcuts when long pressing on app icons in launcher)?
Any shortcuts published for a "share target" purpose, is also a launcher shortcut, and will be shown in the menu when long pressing your app's icon. The maximum shortcut count limit per activity also applies to the total number of shortcuts an app is publishing (share targets and legacy launcher shortcuts combined).
What is the guidance on the number of sharing shortcuts one should publish.
The number of sharing shortcuts is constrained to the same limit of dynamic
shortcuts available via
getMaxShortcutCountPerActivity(android.content.Context)
. One can publish any
number to that limit but must keep in mind that sharing shortcuts can be visible
in the app launcher long-press and in the share sheet. Most app launchers on
long-press display a maximum of four or five shortcuts in portrait mode, and
eight in landscape mode. See this
FAQ
for more details and guidance on sharing shortcuts.