added in API level 25

ShortcutManager

public class ShortcutManager
extends Object

java.lang.Object
   ↳ android.content.pm.ShortcutManager


The ShortcutManager performs operations on an app's set of shortcuts. The ShortcutInfo class contains information about each of the shortcuts themselves.

An app's shortcuts represent specific tasks and actions that users can perform within your app. When a user selects a shortcut in the currently-active launcher, your app opens an activity other than the app's starting activity, provided that the currently-active launcher supports app shortcuts.

The types of shortcuts that you create for your app depend on the app's key use cases. For example, an email app may publish the "compose new email" shortcut, which allows the app to directly open the compose activity.

Note: Only main activities—activities that handle the Intent.ACTION_MAIN action and the Intent.CATEGORY_LAUNCHER category—can have shortcuts. If an app has multiple main activities, you need to define the set of shortcuts for each activity.

This page discusses the implementation details of the ShortcutManager class. For definitions of key terms and guidance on performing operations on shortcuts within your app, see the App Shortcuts feature guide.

Shortcut characteristics

This section describes in-depth details about each shortcut type's usage and availability.

Important security note: All shortcut information is stored in credential encrypted storage, so your app cannot access a user's shortcuts until after they've unlocked the device.

Static and dynamic shortcuts

Static shortcuts and dynamic shortcuts are shown in a supported launcher when the user performs a specific gesture. On currently-supported launchers, the gesture is a long-press on the app's launcher icon, but the actual gesture may be different on other launcher apps.

The LauncherApps class provides APIs for launcher apps to access shortcuts.

Pinned shortcuts

Because pinned shortcuts appear in the launcher itself, they're always visible. A pinned shortcut is removed from the launcher only in the following situations:

  • The user removes it.
  • The publisher app associated with the shortcut is uninstalled.
  • The user selects Clear data from the publisher app's Storage screen, within the system's Settings app.

Because the system performs backup and restore on pinned shortcuts automatically, these shortcuts' IDs should contain either stable, constant strings or server-side identifiers, rather than identifiers generated locally that might not make sense on other devices.

Shortcut display order

When the launcher displays an app's shortcuts, they should appear in the following order:

  1. Static shortcuts: Shortcuts whose ShortcutInfo.isDeclaredInManifest() method returns true.
  2. Dynamic shortcuts: Shortcuts whose ShortcutInfo.isDynamic() method returns true.

Within each shortcut type (static and dynamic), shortcuts are sorted in order of increasing rank according to ShortcutInfo.getRank().

Shortcut ranks

Shortcut ranks are non-negative, sequential integers that determine the order in which shortcuts appear, assuming that the shortcuts are all in the same category. You can update ranks of existing shortcuts when you call updateShortcuts(List), addDynamicShortcuts(List), or setDynamicShortcuts(List).

Note: Ranks are auto-adjusted so that they're unique for each type of shortcut (static or dynamic). For example, if there are 3 dynamic shortcuts with ranks 0, 1 and 2, adding another dynamic shortcut with a rank of 1 represents a request to place this shortcut at the second position. In response, the third and fourth shortcuts move closer to the bottom of the shortcut list, with their ranks changing to 2 and 3, respectively.

Options for static shortcuts

The following list includes descriptions for the different attributes within a static shortcut. You must provide a value for android:shortcutId and android:shortcutShortLabel; all other values are optional.
android:shortcutId

A string literal, which represents the shortcut when a ShortcutManager object performs operations on it.

Note: You cannot set this attribute's value to a resource string, such as @string/foo.

android:enabled

Whether the user can interact with the shortcut from a supported launcher.

The default value is true. If you set it to false, you should also set android:shortcutDisabledMessage to a message that explains why you've disabled the shortcut. If you don't think you need to provide such a message, it's easiest to just remove the shortcut from the XML file entirely, rather than changing the values of the shortcut's android:enabled and android:shortcutDisabledMessage attributes.

android:icon

The bitmap or adaptive icon that the launcher uses when displaying the shortcut to the user. This value can be either the path to an image or the resource file that contains the image. Use adaptive icons whenever possible to improve performance and consistency.

Note: Shortcut icons cannot include tints.

android:shortcutShortLabel

A concise phrase that describes the shortcut's purpose. For more information, see ShortcutInfo.Builder.setShortLabel(CharSequence).

Note: This attribute's value must be a resource string, such as @string/shortcut_short_label.

android:shortcutLongLabel

An extended phrase that describes the shortcut's purpose. If there's enough space, the launcher displays this value instead of android:shortcutShortLabel. For more information, see ShortcutInfo.Builder.setLongLabel(CharSequence).

Note: This attribute's value must be a resource string, such as @string/shortcut_long_label.

android:shortcutDisabledMessage

The message that appears in a supported launcher when the user attempts to launch a disabled shortcut. The message should explain to the user why the shortcut is now disabled. This attribute's value has no effect if android:enabled is true.

Note: This attribute's value must be a resource string, such as @string/shortcut_disabled_message.

Inner elements that define static shortcuts

The XML file that lists an app's static shortcuts supports the following elements inside each <shortcut> element. You must include an intent inner element for each static shortcut that you define.

intent

The action that the system launches when the user selects the shortcut. This intent must provide a value for the android:action attribute.

You can provide multiple intents for a single shortcut. If you do so, the last defined activity is launched, and the other activities are placed in the back stack. See Using Static Shortcuts and the TaskStackBuilder class reference for details.

Note: This intent element cannot include string resources.

To learn more about how to configure intents, see Using intents.

categories

Provides a grouping for the types of actions that your app's shortcuts perform, such as creating new chat messages.

For a list of supported shortcut categories, see the ShortcutInfo class reference for a list of supported shortcut categories.

Updating shortcuts

Each app's launcher icon can contain at most getMaxShortcutCountPerActivity() number of static and dynamic shortcuts combined. There is no limit to the number of pinned shortcuts that an app can create, though.

When a dynamic shortcut is pinned, even when the publisher removes it as a dynamic shortcut, the pinned shortcut is still visible and launchable. This allows an app to have more than getMaxShortcutCountPerActivity() number of shortcuts.

As an example, suppose getMaxShortcutCountPerActivity() is 5:

  1. A chat app publishes 5 dynamic shortcuts for the 5 most recent conversations (c1, c2, ..., c5).
  2. The user pins all 5 of the shortcuts.
  3. Later, the user has started 3 additional conversations (c6, c7, and c8), so the publisher app re-publishes its dynamic shortcuts. The new dynamic shortcut list is: c4, c5, ..., c8.

    The publisher app has to remove c1, c2, and c3 because it can't have more than 5 dynamic shortcuts. However, c1, c2, and c3 are still pinned shortcuts that the user can access and launch.

    At this point, the user can access a total of 8 shortcuts that link to activities in the publisher app, including the 3 pinned shortcuts, even though an app can have at most 5 dynamic shortcuts.

  4. The app can use updateShortcuts(List) to update any of the existing 8 shortcuts, when, for example, the chat peers' icons have changed.

    The addDynamicShortcuts(List) and setDynamicShortcuts(List) methods can also be used to update existing shortcuts with the same IDs, but they cannot be used for updating non-dynamic, pinned shortcuts because these 2 methods try to convert the given lists of shortcuts to dynamic shortcuts.

Shortcut intents

Dynamic shortcuts can be published with any set of Intent flags. Typically, Intent.FLAG_ACTIVITY_CLEAR_TASK is specified, possibly along with other flags; otherwise, if the app is already running, the app is simply brought to the foreground, and the target activity might not appear.

Static shortcuts cannot have custom intent flags. The first intent of a static shortcut will always have Intent.FLAG_ACTIVITY_NEW_TASK and Intent.FLAG_ACTIVITY_CLEAR_TASK set. This means, when the app is already running, all the existing activities in your app are destroyed when a static shortcut is launched. If this behavior is not desirable, you can use a trampoline activity, or an invisible activity that starts another activity in Activity.onCreate(Bundle), then calls Activity.finish():

  1. In the AndroidManifest.xml file, the trampoline activity should include the attribute assignment android:taskAffinity="".
  2. In the shortcuts resource file, the intent within the static shortcut should reference the trampoline activity.

Rate limiting

When rate limiting is active, isRateLimitingActive() returns true.

Rate limiting is reset upon certain events, so even background apps can call these APIs until the rate limit is reached again. These events include the following:

  • An app comes to the foreground.
  • The system locale changes.
  • The user performs the inline reply action on a notification.

Handling system locale changes

Apps should update dynamic and pinned shortcuts when they receive the Intent.ACTION_LOCALE_CHANGED broadcast, indicating that the system locale has changed.

When the system locale changes, rate limiting is reset, so even background apps can add and update dynamic shortcuts until the rate limit is reached again.

Retrieving class instances

Instances of this class must be obtained using Context.getSystemService(Class) with the argument ShortcutManager.class or Context.getSystemService(String) with the argument Context.SHORTCUT_SERVICE.

Summary

Public methods

boolean addDynamicShortcuts(List<ShortcutInfo> shortcutInfoList)

Publish the list of dynamic shortcuts.

Intent createShortcutResultIntent(ShortcutInfo shortcut)

Returns an Intent which can be used by the default launcher to pin a shortcut containing the given ShortcutInfo.

void disableShortcuts(List<String> shortcutIds)

Disable pinned shortcuts.

void disableShortcuts(List<String> shortcutIds, CharSequence disabledMessage)

Disable pinned shortcuts, showing the user a custom error message when they try to select the disabled shortcuts.

void enableShortcuts(List<String> shortcutIds)

Re-enable pinned shortcuts that were previously disabled.

List<ShortcutInfo> getDynamicShortcuts()

Return all dynamic shortcuts from the caller app.

int getIconMaxHeight()

Return the max height for icons, in pixels.

int getIconMaxWidth()

Return the max width for icons, in pixels.

List<ShortcutInfo> getManifestShortcuts()

Return all static (manifest) shortcuts from the caller app.

int getMaxShortcutCountPerActivity()

Return the maximum number of static and dynamic shortcuts that each launcher icon can have at a time.

List<ShortcutInfo> getPinnedShortcuts()

Return all pinned shortcuts from the caller app.

boolean isRateLimitingActive()

Return true when rate-limiting is active for the caller app.

boolean isRequestPinShortcutSupported()

Return TRUE if the app is running on a device whose default launcher supports requestPinShortcut(ShortcutInfo, IntentSender).

void removeAllDynamicShortcuts()

Delete all dynamic shortcuts from the caller app.

void removeDynamicShortcuts(List<String> shortcutIds)

Delete dynamic shortcuts by ID.

void reportShortcutUsed(String shortcutId)

Apps that publish shortcuts should call this method whenever the user selects the shortcut containing the given ID or when the user completes an action in the app that is equivalent to selecting the shortcut.

boolean requestPinShortcut(ShortcutInfo shortcut, IntentSender resultIntent)

Request to create a pinned shortcut.

boolean setDynamicShortcuts(List<ShortcutInfo> shortcutInfoList)

Publish the list of shortcuts.

boolean updateShortcuts(List<ShortcutInfo> shortcutInfoList)

Update all existing shortcuts with the same IDs.

Inherited methods

Public methods

addDynamicShortcuts

added in API level 25
public boolean addDynamicShortcuts (List<ShortcutInfo> shortcutInfoList)

Publish the list of dynamic shortcuts. If there are already dynamic or pinned shortcuts with the same IDs, each mutable shortcut is updated.

This API will be rate-limited.

Parameters
shortcutInfoList List

This value must never be null.

Returns
boolean true if the call has succeeded. false if the call is rate-limited.

Throws
IllegalArgumentException if getMaxShortcutCountPerActivity() is exceeded, or when trying to update immutable shortcuts.
IllegalStateException when the user is locked.

createShortcutResultIntent

added in API level 26
public Intent createShortcutResultIntent (ShortcutInfo shortcut)

Returns an Intent which can be used by the default launcher to pin a shortcut containing the given ShortcutInfo. This method should be used by an Activity to set a result in response to Intent.ACTION_CREATE_SHORTCUT.

Parameters
shortcut ShortcutInfo: New shortcut to pin. If an app wants to pin an existing (either dynamic or manifest) shortcut, then it only needs to have an ID, and other fields don't have to be set, in which case, the target shortcut must be enabled. If it's a new shortcut, all the mandatory fields, such as a short label, must be set.

This value must never be null.

Returns
Intent The intent that should be set as the result for the calling activity, or null if the current launcher doesn't support shortcuts.

Throws
IllegalArgumentException if a shortcut with the same ID exists and is disabled.

disableShortcuts

added in API level 25
public void disableShortcuts (List<String> shortcutIds)

Disable pinned shortcuts. For more details, see the Javadoc for the ShortcutManager class.

Parameters
shortcutIds List

This value must never be null.

Throws
IllegalArgumentException If trying to disable immutable shortcuts.
IllegalStateException when the user is locked.

disableShortcuts

added in API level 25
public void disableShortcuts (List<String> shortcutIds, 
                CharSequence disabledMessage)

Disable pinned shortcuts, showing the user a custom error message when they try to select the disabled shortcuts. For more details, see the Javadoc for the ShortcutManager class.

Parameters
shortcutIds List

This value must never be null.

disabledMessage CharSequence

Throws
IllegalArgumentException If trying to disable immutable shortcuts.
IllegalStateException when the user is locked.

enableShortcuts

added in API level 25
public void enableShortcuts (List<String> shortcutIds)

Re-enable pinned shortcuts that were previously disabled. If the target shortcuts are already enabled, this method does nothing.

Parameters
shortcutIds List

This value must never be null.

Throws
IllegalArgumentException If trying to enable immutable shortcuts.
IllegalStateException when the user is locked.

getDynamicShortcuts

added in API level 25
public List<ShortcutInfo> getDynamicShortcuts ()

Return all dynamic shortcuts from the caller app.

This API is intended to be used for examining what shortcuts are currently published. Re-publishing returned ShortcutInfos via APIs such as setDynamicShortcuts(List) may cause loss of information such as icons.

Returns
List<ShortcutInfo>

This value will never be null.

Throws
IllegalStateException when the user is locked.

getIconMaxHeight

added in API level 25
public int getIconMaxHeight ()

Return the max height for icons, in pixels.

Returns
int

getIconMaxWidth

added in API level 25
public int getIconMaxWidth ()

Return the max width for icons, in pixels.

Note that this method returns max width of icon's visible part. Hence, it does not take into account the inset introduced by AdaptiveIconDrawable. To calculate bitmap image to function as AdaptiveIconDrawable, multiply 1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction() to the returned size.

Returns
int

getManifestShortcuts

added in API level 25
public List<ShortcutInfo> getManifestShortcuts ()

Return all static (manifest) shortcuts from the caller app.

This API is intended to be used for examining what shortcuts are currently published. Re-publishing returned ShortcutInfos via APIs such as setDynamicShortcuts(List) may cause loss of information such as icons.

Returns
List<ShortcutInfo>

This value will never be null.

Throws
IllegalStateException when the user is locked.

getMaxShortcutCountPerActivity

added in API level 25
public int getMaxShortcutCountPerActivity ()

Return the maximum number of static and dynamic shortcuts that each launcher icon can have at a time.

Returns
int

getPinnedShortcuts

added in API level 25
public List<ShortcutInfo> getPinnedShortcuts ()

Return all pinned shortcuts from the caller app.

This API is intended to be used for examining what shortcuts are currently published. Re-publishing returned ShortcutInfos via APIs such as setDynamicShortcuts(List) may cause loss of information such as icons.

Returns
List<ShortcutInfo>

This value will never be null.

Throws
IllegalStateException when the user is locked.

isRateLimitingActive

added in API level 25
public boolean isRateLimitingActive ()

Return true when rate-limiting is active for the caller app.

See the class level javadoc for details.

Returns
boolean

Throws
IllegalStateException when the user is locked.

isRequestPinShortcutSupported

added in API level 26
public boolean isRequestPinShortcutSupported ()

Return TRUE if the app is running on a device whose default launcher supports requestPinShortcut(ShortcutInfo, IntentSender).

The return value may change in subsequent calls if the user changes the default launcher app.

Note: See also the support library counterpart ShortcutManagerCompat.isRequestPinShortcutSupported(Context), which supports Android versions lower than Build.VERSION_CODES.O using the legacy private intent com.android.launcher.action.INSTALL_SHORTCUT.

Returns
boolean

removeAllDynamicShortcuts

added in API level 25
public void removeAllDynamicShortcuts ()

Delete all dynamic shortcuts from the caller app.

Throws
IllegalStateException when the user is locked.

removeDynamicShortcuts

added in API level 25
public void removeDynamicShortcuts (List<String> shortcutIds)

Delete dynamic shortcuts by ID.

Parameters
shortcutIds List

This value must never be null.

Throws
IllegalStateException when the user is locked.

reportShortcutUsed

added in API level 25
public void reportShortcutUsed (String shortcutId)

Apps that publish shortcuts should call this method whenever the user selects the shortcut containing the given ID or when the user completes an action in the app that is equivalent to selecting the shortcut. For more details, see the Javadoc for the ShortcutManager class

The information is accessible via UsageStatsManager.queryEvents(long, long) Typically, launcher apps use this information to build a prediction model so that they can promote the shortcuts that are likely to be used at the moment.

Parameters
shortcutId String

Throws
IllegalStateException when the user is locked.

requestPinShortcut

added in API level 26
public boolean requestPinShortcut (ShortcutInfo shortcut, 
                IntentSender resultIntent)

Request to create a pinned shortcut. The default launcher will receive this request and ask the user for approval. If the user approves it, the shortcut will be created, and resultIntent will be sent. If a request is denied by the user, however, no response will be sent to the caller.

Only apps with a foreground activity or a foreground service can call this method. Otherwise, it'll throw IllegalStateException.

It's up to the launcher to decide how to handle previous pending requests when the same package calls this API multiple times in a row. One possible strategy is to ignore any previous requests.

Note: See also the support library counterpart ShortcutManagerCompat.requestPinShortcut(Context, ShortcutInfoCompat, IntentSender), which supports Android versions lower than Build.VERSION_CODES.O using the legacy private intent com.android.launcher.action.INSTALL_SHORTCUT.

Parameters
shortcut ShortcutInfo: Shortcut to pin. If an app wants to pin an existing (either static or dynamic) shortcut, then it only needs to have an ID. Although other fields don't have to be set, the target shortcut must be enabled.

If it's a new shortcut, all the mandatory fields, such as a short label, must be set.

This value must never be null.

resultIntent IntentSender: If not null, this intent will be sent when the shortcut is pinned. Use PendingIntent.getIntentSender() to create an IntentSender. To avoid background execution limits, use an unexported, manifest-declared receiver. For more details, see the overview documentation for the ShortcutManager class.

Returns
boolean TRUE if the launcher supports this feature. Note the API will return without waiting for the user to respond, so getting TRUE from this API does *not* mean the shortcut was pinned successfully. FALSE if the launcher doesn't support this feature.

Throws
IllegalArgumentException if a shortcut with the same ID exists and is disabled.
IllegalStateException The caller doesn't have a foreground activity or a foreground service, or the device is locked.

setDynamicShortcuts

added in API level 25
public boolean setDynamicShortcuts (List<ShortcutInfo> shortcutInfoList)

Publish the list of shortcuts. All existing dynamic shortcuts from the caller app will be replaced. If there are already pinned shortcuts with the same IDs, the mutable pinned shortcuts are updated.

This API will be rate-limited.

Parameters
shortcutInfoList List

This value must never be null.

Returns
boolean true if the call has succeeded. false if the call is rate-limited.

Throws
IllegalArgumentException if getMaxShortcutCountPerActivity() is exceeded, or when trying to update immutable shortcuts.
IllegalStateException when the user is locked.

updateShortcuts

added in API level 25
public boolean updateShortcuts (List<ShortcutInfo> shortcutInfoList)

Update all existing shortcuts with the same IDs. Target shortcuts may be pinned and/or dynamic, but they must not be immutable.

This API will be rate-limited.

Parameters
shortcutInfoList List

This value must never be null.

Returns
boolean true if the call has succeeded. false if the call is rate-limited.

Throws
IllegalArgumentException If trying to update immutable shortcuts.
IllegalStateException when the user is locked.