Sachit Wadhawan

How to Implement App Shortcuts in Android 7.1 Nougat?

app shortcuts

Google has released a major update of 7.1 version (API 25) with some pretty cool features. One of the extra features is App Shortcuts.

What is an App Shortcut?

App Shortcuts uncover common tasks or activities of your application to the launcher screen. Users can use the App Shortcuts feature by long-press on the app icon. 

  • App Shortcuts are great for making common actions of your app visible and bring back users into the flow in your application.
  • App Shortcuts can be static or dynamic.
    • Static remain same after you define them, you have to redeploy app if you want to make any changes in it.
    • Dynamic one can be changed any time or on the fly.
  • You can create/manage the stack of activities once you open one through a shortcut. Here you can set the flow of all the activities using intents.
  • You can reorder the shortcuts in their respective. Static shortcuts will come always at the bottom as they’re added first (there’s no rank property to be defined on them)
  • The labels are charSequence. So you can play with the span in order to change anything in the text of the labels.

App shortcuts can be of two types-

Static Shortcuts– They are defined statically in a resource file; you can’t change without redeploying the build.

Dynamic Shortcuts– The one that can be defined at runtime or on the fly; you can change without redeploying the build.

Note: App must have minimum SDK version set to API 25.

Let’s start with creating Static Shortcut first.

Static Shortcuts 

Open your AndroidManifest.xml and add the following meta-data tag to your parent or main activity which you want to open as soon as your app starts playing the role.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.appshortcut.example">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name="com.appshortcut.example.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>

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

</manifest>

 

In the shortcuts.xml file you need to add all your static shortcuts. I will show you how you can add static shortcuts.

<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
    <shortcut
        android:enabled="true"
        android:icon="@drawable/star"
        android:shortcutDisabledMessage="@string/disabled_message"
        android:shortcutLongLabel="@string/long_label"
android:shortcutId="static_shortcut"
        android:shortcutShortLabel="@string/short_label">
        <intent
            android:action="android.intent.action.MAIN"
            android:targetClass="com.appshortcut.example.MainActivity"
            android:targetPackage="com.appshortcut.example"/>
        <intent
            android:action="android.intent.action.VIEW"
            android:targetClass="com.appshortcut.example.MyStaticShortcutActivity"
            android:targetPackage="com.appshortcut.example"/>
    </shortcut>

</shortcuts>

 

You can add multiple shortcuts in the root tag <shortcuts>. Let’s understand the properties one by one.

  • enabled: It indicates that shortcut is enabled or not. If you want to disable this shortcut, just set the parameter value as false.
  • icon: It will set the icon to your shortcut menu on the left side.
  • shortcutDisabledMessage: This will show the message if someone will click on the disabled shortcut. However if you have set the “enabled” feature as false, the option will not be shown when you will do long-press but the user can pin a shortcut to the launcher. So pinned shortcut will be disabled at that time and click on it will show a toast message to the user.
  • shortcutLongLabel: The longer text that will be shown as a label but it will only be shown if there is enough room.
  • shortcutShortLabel: A short description of the shortcut. This field is mandatory.
  • intent: The intent that will be invoked when user will click the shortcut icon.

Multiple intents in shortcuts tags will maintain the stack of the activity as you can see in the above example. When you will press the shortcut icon, then “MainActivity” followed by “MyStaticShortcutActivity” will be opened, and when you press the back button it will take you to the “MainActivity”.

Dynamic Shortcuts

The dynamic shortcuts can be modified on the fly without the need of redeploying your app. They are created in java code.

I will show you how you can add dynamic shortcuts. We will use the ShortcutManager and ShortcutBuilder.Info in order to create dynamic shortcuts.

/**
     * This method will initialize the shortcuts that needs to add in the launcher
     * screen
     *
     * setShortLabel-   This will set the label on the shortcut. This is mandatory. It
     *                  can't be leave blank or ignored
     * setLongLabel-    This is optional and it will only be shown if there is a enough
     *                  space on the launcher screen
     * setIcon-         This will set the icon on the shortcut menu in left side
     * setIntent-       It will decide the flow of the app when you will click on the shortcut
     *                  icon. You can set multiple intents here.
     * setRank-         It will decide the order of the shortcut menu
     *
     */
    private void addDynamicShortcuts() {
        ShortcutInfo shortcutInfoLink = new ShortcutInfo.Builder(this, "shortcut_web")
                .setShortLabel("com")
                .setLongLabel("google.com")
                .setIcon(Icon.createWithResource(this, R.drawable.ic_dynamic_shortcut))
                .setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse("https://google.com")))
                .setRank(0)
                .build();

        ShortcutInfo dynamicShortcutInfo = new ShortcutInfo.Builder(this, "shortcut_dynamic")
                .setShortLabel("Dynamic")
                .setLongLabel("Open dynamic shortcut")
                .setIcon(Icon.createWithResource(this, R.drawable.ic_dynamic_shortcut_2))
                .setIntents(
                        new Intent[]{
                                new Intent(Intent.ACTION_MAIN, Uri.EMPTY, this, MainActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK),
                                new Intent(DynamicShortcutActivity.ACTION)
                        })
                .setRank(1)
                .build();

        mShortcutManager.setDynamicShortcuts(Arrays.asList(shortcutInfoLink, dynamicShortcutInfo));
    }

Here we have built theShortcutInfo using shortcutManager. We can set the properties for the shortcut using it. The properties are same except id and setRank. So I will explain these two only in case of dynamic shortcuts and other properties have same behavior as static shortcuts.

Here in the above example, we have defined the id shortcut_dynamic as the second parameter of ShortcutInfo.Builder and setRank() is used to set the order of the shortcut which is not present in the case of static shortcuts. Here the first static shortcut will appear followed by rank 0 and then rank 1 shortcut. We can see same functionality in the image shown below.

As you can see in above image that static shortcut always takes place at the bottom of the list. You cannot change the rank of static shortcuts. They will always be shown in the order they’re defined in the file shortcuts.xml

If we see the method setShortLabel(CharSequence)of ShortcutInfo.Builder we can see that it takes CharSequence as a parameter. Which means that we can play around with it. We can change it’s color on the fly. We can create a SpannableStringBuilder and set to it a ForegroundColorSpan with the color we want to apply and then pass the spannableStringBuilder as a shortLabel (as the SpannableStringBuilder is a CharSequence):

/**
     * This method will set the listener to the widgets in the activity
     */
    private void setListener() {
        
        ForegroundColorSpan colorSpan = new ForegroundColorSpan(getResources().getColor(android.R.color.holo_red_dark, getTheme()));
        String label = "google.com";
        SpannableStringBuilder colouredLabel = new SpannableStringBuilder(label);
        colouredLabel.setSpan(colorSpan, 0, label.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);

        ShortcutInfo webShortcut = new ShortcutInfo.Builder(MainActivity.this, "shortcut_web")
                .setShortLabel(colouredLabel)
                .setRank(1)
                .build();

        ShortcutInfo dynamicShortcut = new ShortcutInfo.Builder(MainActivity.this, "shortcut_dynamic")
                .setRank(0)
                .build();

        mShortcutManager.updateShortcuts(Arrays.asList(webShortcut, dynamicShortcut));
    }

 

That’s all in order to use App Shortcuts. 🙂 If you have any queries, please feel free to drop your comments.

References- 

  1. How to implement App Shortcuts
  2. App Shortcuts