# Android App Shortcuts - Static, Dynamic and Pinned

## What are app shortcuts?

App shortcuts (introduced in Android Nougat 7.1) allow users to perform certain app actions without having to open the app. Developers can allow users to pin certain app actions to home screen. Let's see how.

### Where have I seen this?

You might have already seen and used this. Most of the popular apps have implemented this to make few of their actions more reachable to users.

![Screenshot 2022-01-01 at 7.38.36 PM.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1641046174890/FmjbFPcMv.png align="left")

![Screenshot 2022-01-01 at 7.39.03 PM.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1641046195706/rGrqT-aiR.png align="left")

There are three types of app shortcuts-

* **Static shortcuts** - These are static shortcuts that are defined using XML and do not change. These are packed in the APK or app bundle.
    
* **Dynamic shortcuts** - These shortcuts can be created/modified/removed at run-time.
    
* **Pinned shortcuts** - These shortcuts can be pinned to the launcher as separate icons, if the user grants permission.
    

Note: Not all launchers support this feature.

## Creating shortcuts

### Static shortcut

In `AndroidManifest.xml`, under the activity whose intent filters are set to

```kotlin
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
```

add the following meta-data -

```kotlin
<meta-data 
    android:name="android.app.shortcuts"
    android:resource="@xml/shortcuts" />
```

Now, create `res/xml/shortcuts.xml`

Here we'll define the shortcuts

I've created a simple shortcut with only two mandatory attributes `android:shortcutId` and `android:shortcutShortLabel` to the MainActivity for the android app.

```kotlin
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
  <shortcut
    android:shortcutId="compose"
    android:shortcutShortLabel="@string/launch_main_activity">
    <intent
      android:action="android.intent.action.VIEW"
      android:targetPackage="me.abhishekkumar.myapplication"
      android:targetClass="me.abhishekkumar.myapplication.MainActivity" />
  </shortcut>
</shortcuts>
```

We can define multiple shortcuts like this -

```kotlin
<shortcuts>
  <shortcut/>
  <shortcut/>
  <shortcut/>
</shortcuts>
```

`android:shortcutId` - It's used to uniquely identify the shortcut so that `ShortcutManager` object can perform operations on it.

`android:shortcutShortLabel`\- A short label for the shortcut that will be displayed in the launcher *(Recommended &lt;= 10 characters)*.

Few optional attributes -

`android:enabled` - Using this attribute we can enable/disable a shortcut. By default, it's set to `true`.

`android:icon`\- Using this attribute we can set an icon to the shortcut that will be displayed along with the label.

`android:shortcutLongLabel`\- A long description for the shortcut *(Recommended &lt;= 25 characters)*. If launcher allows, it will display this of `android:shortcutShortLabel`

`android:shortcutDisabledMessage`\- The message we want to display when a disabled shortcut is clicked by the user.

### Dynamic shortcuts

We can make use of the `ShortcutManagerCompat`Jetpack library which is a helper for accessing features in ShortcutManager.

Here I've created a simple dynamic shortcut to open `ShortcutActivity` using `ShortcutManagerCompat`\-

```kotlin
 val shortcut = ShortcutInfoCompat.Builder(this, "shortcutId")
            .setShortLabel("Label")
            .setLongLabel("Long Label description")
            .setIntent(Intent(Intent.ACTION_MAIN, Uri.EMPTY, this, ShortcutActivity::class.java))
            .build()

        ShortcutManagerCompat.pushDynamicShortcut(this, shortcut)


ShortcutManagerCompat.pushDynamicShortcut(context, shortcut)
```

Note: We need to pass the *Intent action* to the intent

### Pinned shortcuts

On Android 8.0 (API level 26) and higher, we can create pinned shortcuts by following these steps -

1. Check if the launcher supports *pinned shortcuts* by using `isRequestPinShortcutSupported()`
    
2. Create a `ShortcutInfo` object in one of the two ways -
    

* If shortcut exists - pass only the existing shortcut's ID
    
* If shortcut doesn't exist, pass an ID, an intent, and a short label for the new shortcut.
    

1. We can now pin the shortcut to the device's launcher by calling `requestPinShortcut()`, we can pass a PendingIntent object, which notifies your app only when the shortcut is pinned successfully.
    

* When shortcut exists
    

```kotlin
val shortcutManager = getSystemService(ShortcutManager::class.java)

if (shortcutManager?.isRequestPinShortcutSupported==true) {
    val pinShortcutInfo = ShortcutInfo.Builder(context, "shortcutId").build()
    val pinnedShortcutCallbackIntent = shortcutManager.createShortcutResultIntent(pinShortcutInfo)

    val successCallback = PendingIntent.getBroadcast(context,REQUEST_CODE,
            pinnedShortcutCallbackIntent, REQUEST_FLAG)

    shortcutManager.requestPinShortcut(pinShortcutInfo,
            successCallback.intentSender)
}
```

* When shortcut doesn't exist
    

```kotlin
val shortcutManager = getSystemService(ShortcutManager::class.java)

if (shortcutManager?.isRequestPinShortcutSupported==true) {
  val pinShortcutInfo = ShortcutInfo.Builder(this, "shortcutId")
                    .setShortLabel("Label")
                    .setIntent(intent)
                    .build()
    val pinnedShortcutCallbackIntent = shortcutManager.createShortcutResultIntent(pinShortcutInfo)

    val successCallback = PendingIntent.getBroadcast(context,REQUEST_CODE,
            pinnedShortcutCallbackIntent, REQUEST_FLAG)

    shortcutManager.requestPinShortcut(pinShortcutInfo,
            successCallback.intentSender)
}
```

---

I hope you found this article useful!

Follow me for more articles like this. Have a great day! 😊

%%[buy-me-a-coffee]
