Shortcuts deliver specific types of content to your users by helping them quickly access parts of your app.
How you deliver content with shortcuts depends on your use case and whether the shortcut's context is app-driven or user-driven. Although a static shortcut's context doesn't change and a dynamic shortcut's context constantly changes, your app drives the context in both cases. In cases where a user chooses how your app delivers content to them, such as with a pinned shortcut, the context is defined by the user. The following scenarios describe a few use cases for each shortcut type:
- Static shortcuts are best for apps that link to content using a consistent structure throughout the lifetime of a user's interaction with the app. Because most launchers only display four shortcuts at once, static shortcuts are useful for performing a routine task in a consistent way, such as if the user wants to view their calendar or email in a specific way .
- Dynamic shortcuts are used for actions in apps that are context-sensitive. Context-sensitive shortcuts are tailored to the actions users perform in an app. For example, if you build a game that lets the user start from their current level on launch, you need to update the shortcut frequently. Using a dynamic shortcut lets you update the shortcut each time the user clears a level.
- Pinned shortcuts are used for specific user-driven actions. For example, a user might want to pin a specific website to the launcher. This is beneficial because it lets the user perform a custom action—like navigating to the website in one step, more quickly than using a default instance of a browser.
Create static shortcuts
Static shortcuts provide links to generic actions within your app, and these actions must remain consistent over the lifetime of your app's current version. Good options for static shortcuts include viewing sent messages, setting an alarm, and displaying a user's exercise activity for the day.
To create a static shortcut, do the following:
-
In your app's
AndroidManifest.xml
file, find the activity whose intent filters are set to theandroid.intent.action.MAIN
action and theandroid.intent.category.LAUNCHER
category. -
Add a
<meta-data>
element to this activity that references the resource file where the app's shortcuts are defined:<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication"> <application ... > <activity android:name="Main"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" /> </activity> </application> </manifest>
-
Create a new resource file called
res/xml/shortcuts.xml
. -
In the new resource file, add a
<shortcuts>
root element that contains a list of<shortcut>
elements. In each<shortcut>
element, include information about a static shortcut including its icon, description labels, and the intents it launches within the app:<shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <shortcut android:shortcutId="compose" android:enabled="true" android:icon="@drawable/compose_icon" android:shortcutShortLabel="@string/compose_shortcut_short_label1" android:shortcutLongLabel="@string/compose_shortcut_long_label1" android:shortcutDisabledMessage="@string/compose_disabled_message1"> <intent android:action="android.intent.action.VIEW" android:targetPackage="com.example.myapplication" android:targetClass="com.example.myapplication.ComposeActivity" /> <!-- If your shortcut is associated with multiple intents, include them here. The last intent in the list determines what the user sees when they launch this shortcut. --> <categories android:name="android.shortcut.conversation" /> <capability-binding android:key="actions.intent.CREATE_MESSAGE" /> </shortcut> <!-- Specify more shortcuts here. --> </shortcuts>
Customize attribute values
The following list includes descriptions for the different attributes within
a static shortcut. Provide a value for android:shortcutId
and
android:shortcutShortLabel
. All other values are optional.
-
android:shortcutId
-
A string literal that represents the shortcut when a
ShortcutManager
object performs operations on it. -
android:shortcutShortLabel
-
A concise phrase that describes the shortcut's purpose. When possible, limit this short description to 10 characters.
For more information, see
setShortLabel()
. -
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
. When possible, limit this long description to 25 characters.For more information, see
setLongLabel()
. -
android:shortcutDisabledMessage
-
The message that appears in a supported launcher when the user attempts to launch a disabled shortcut. The message must explain to the user why the shortcut is disabled. This attribute's value has no effect if
android:enabled
istrue
. -
android:enabled
-
Determines whether the user can interact with the shortcut from a supported launcher. The default value of
android:enabled
istrue
. If you set it tofalse
, set anandroid:shortcutDisabledMessage
that explains why you're disabling the shortcut. If you don't think you need to provide such a message, remove the shortcut from the XML file entirely. -
android:icon
-
The bitmap or adaptive icon that the launcher uses when displaying the shortcut to the user. This value can be the path to an image or the resource file that contains the image. Use adaptive icons whenever possible to improve performance and consistency.
Configure inner elements
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. See Manage multiple intents and activities, Set an intent, and the
TaskStackBuilder
class reference for details. -
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. -
capability-binding
-
Declares the capability linked with the shortcut.
In the previous example, the shortcut is linked to a capability declared for
CREATE_MESSAGE
, which is an App Actions built-in intent. This capability binding lets users use spoken commands with Google Assistant to invoke a shortcut.
Create dynamic shortcuts
Dynamic shortcuts provide links to specific, context-sensitive actions within your app. These actions can change between uses of your app and while your app is running. Good uses for dynamic shortcuts include calling a specific person, navigating to a specific location, and loading a game from the user's last save point. You can also use dynamic shortcuts to open a conversation.
The
ShortcutManagerCompat
Jetpack library is a helper for the
ShortcutManager
API, which lets you manage dynamic shortcuts in your app. Using the
ShortcutManagerCompat
library reduces boilerplate code and helps
ensure that your shortcuts work consistently across Android versions. This
library is also required for pushing dynamic shortcuts so that they are eligible
to appear on Google surfaces—like Assistant—with the
Google Shortcuts Integration Library.
The ShortcutManagerCompat
API lets your app perform the following
operations with dynamic shortcuts:
-
Push and update: use
pushDynamicShortcut()
to publish and update your dynamic shortcuts. If there are already dynamic or pinned shortcuts with the same ID, each mutable shortcut updates. -
Remove: remove a set of dynamic shortcuts using
removeDynamicShortcuts()
. Remove all dynamic shortcuts usingremoveAllDynamicShortcuts()
.
For more information about performing operations on shortcuts, see
Manage shortcuts
and the
ShortcutManagerCompat
reference.
Here's an example of creating a dynamic shortcut and associating it with your app:
Kotlin
val shortcut = ShortcutInfoCompat.Builder(context, "id1") .setShortLabel("Website") .setLongLabel("Open the website") .setIcon(IconCompat.createWithResource(context, R.drawable.icon_website)) .setIntent(Intent(Intent.ACTION_VIEW, Uri.parse("https://www.mysite.example.com/"))) .build() ShortcutManagerCompat.pushDynamicShortcut(context, shortcut)
Java
ShortcutInfoCompat shortcut = new ShortcutInfoCompat.Builder(context, "id1") .setShortLabel("Website") .setLongLabel("Open the website") .setIcon(IconCompat.createWithResource(context, R.drawable.icon_website)) .setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.mysite.example.com/"))) .build(); ShortcutManagerCompat.pushDynamicShortcut(context, shortcut);
Add the Google Shortcuts Integration Library
The Google Shortcuts Integration Library is an optional Jetpack library. It lets you push dynamic shortcuts that can be displayed on Android surfaces, such as the launcher, and Google surfaces, such as Assistant. Using this library helps users discover your shortcuts to quickly access specific content or replay actions in your app.
For example, a messaging app might push a dynamic shortcut for a contact named "Alex" after a user messages that person. After the dynamic shortcut is pushed, if the user asks Assistant, "Hey Google, message Alex on ExampleApp," Assistant can launch ExampleApp and automatically configure it to send a message to Alex.
Dynamic shortcuts pushed with this library aren't subject to the shortcut limits enforced on a per-device basis. This lets your app push a shortcut every time a user completes an associated action in your app. Pushing frequent shortcuts this way lets Google understand your user's patterns of use and suggest contextually relevant shortcuts to them.
For example, Assistant can learn from shortcuts pushed from your fitness-tracking app that a user typically runs each morning and proactively suggest a "start a run" shortcut when the user picks up their phone in the morning.
The Google Shortcuts Integration Library doesn't offer any addressable
functionality itself. Adding this library to your app lets Google surfaces take
in the shortcuts your app pushes using ShortcutManagerCompat
.
To use this library in your app, follow these steps:
-
Update your
gradle.properties
file to support AndroidX libraries:android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true
-
In
app/build.gradle
, add dependencies for the Google Shortcuts Integration Library andShortcutManagerCompat
:dependencies { implementation "androidx.core:core:1.6.0" implementation 'androidx.core:core-google-shortcuts:1.0.0' ... }
With the library dependencies added to your Android project, your app can use
the pushDynamicShortcut()
method from
ShortcutManagerCompat
to push dynamic shortcuts that are eligible
for display on the launcher and participating Google surfaces.
Create pinned shortcuts
On Android 8.0 (API level 26) and higher, you can create pinned shortcuts. Unlike static and dynamic shortcuts, pinned shortcuts appear in supported launchers as separate icons. Figure 1 shows the distinction between these two types of shortcuts.
To pin a shortcut to a supported launcher using your app, complete the following steps:
-
Use
isRequestPinShortcutSupported()
to verify that the device's default launcher supports in-app pinning of shortcuts. -
Create a
ShortcutInfo
object in one of two ways, depending on whether the shortcut exists:-
If the shortcut exists, create a
ShortcutInfo
object that contains only the existing shortcut's ID. The system finds and pins all other information related to the shortcut automatically. -
If you're pinning a new shortcut, create a
ShortcutInfo
object that contains an ID, an intent, and a short label for the new shortcut.
-
If the shortcut exists, create a
-
Pin the shortcut to the device's launcher by calling
requestPinShortcut()
. During this process, you can pass in aPendingIntent
object, which notifies your app only when the shortcut pins successfully.After a shortcut is pinned, your app can update its contents using the
updateShortcuts()
method. For more information, read Update shortcuts.
The following code snippet demonstrates how to create a pinned shortcut.
Kotlin
val shortcutManager = getSystemService(ShortcutManager::class.java) if (shortcutManager!!.isRequestPinShortcutSupported) { // Enable the existing shortcut with the ID "my-shortcut". val pinShortcutInfo = ShortcutInfo.Builder(context, "my-shortcut").build() // Create the PendingIntent object only if your app needs to be notified // that the user let the shortcut be pinned. If the pinning operation fails, // your app isn't notified. Assume here that the app implements a method // called createShortcutResultIntent() that returns a broadcast intent. val pinnedShortcutCallbackIntent = shortcutManager.createShortcutResultIntent(pinShortcutInfo) // Configure the intent so that your app's broadcast receiver gets the // callback successfully. For details, see PendingIntent.getBroadcast(). val successCallback = PendingIntent.getBroadcast(context, /* request code */ 0, pinnedShortcutCallbackIntent, /* flags */ 0) shortcutManager.requestPinShortcut(pinShortcutInfo, successCallback.intentSender) }
Java
ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class); if (shortcutManager.isRequestPinShortcutSupported()) { // Enable the existing shortcut with the ID "my-shortcut". ShortcutInfo pinShortcutInfo = new ShortcutInfo.Builder(context, "my-shortcut").build(); // Create the PendingIntent object only if your app needs to be notified // that the user let the shortcut be pinned. If the pinning operation fails, // your app isn't notified. Assume here that the app implements a method // called createShortcutResultIntent() that returns a broadcast intent. Intent pinnedShortcutCallbackIntent = shortcutManager.createShortcutResultIntent(pinShortcutInfo); // Configure the intent so that your app's broadcast receiver gets the // callback successfully. For details, see PendingIntent.getBroadcast(). PendingIntent successCallback = PendingIntent.getBroadcast(context, /* request code */ 0, pinnedShortcutCallbackIntent, /* flags */ 0); shortcutManager.requestPinShortcut(pinShortcutInfo, successCallback.getIntentSender()); }
Create a custom shortcut activity
You can also create a specialized activity that helps users create shortcuts, complete with custom options and a confirmation button. Figure 2 shows an example of this type of activity in the Gmail app.
In your app's manifest file, add
ACTION_CREATE_SHORTCUT
to the activity's
<intent-filter>
element. This declaration sets up the following behavior when the user attempts
to create a shortcut:
- The system starts your app's specialized activity.
- The user sets options for the shortcut.
- The user selects the confirmation button.
-
Your app creates the shortcut using the
createShortcutResultIntent()
method. This method returns anIntent
, which your app relays back to the previously executing activity usingsetResult()
. -
Your app calls
finish()
on the activity used to create the customized shortcut.
Similarly, your app can prompt users to add pinned shortcuts to the home screen after installation or the first time the app is launched. This method is effective because it helps your users create a shortcut as part of their ordinary workflow.
Test shortcuts
To test your app's shortcuts, install your app on a device with a launcher that supports shortcuts. Then, perform the following actions:
- Touch & hold your app's launcher icon to view the shortcuts that you define for your app.
- Drag a shortcut to pin it to the device's launcher.