Handling shortcuts when building an Android Launcher
In Android 7.1 / API 25, Google has introduced a very cool feature called “Android App Shortcuts”.
In this article, I will explain how to query and launch Android shortcuts from your application.
TL;DR? Here is the source code of the article.
1. What is Android App Shortcuts
According to Google documentation,
Shortcuts let your users quickly start common or recommended tasks within your app.
There are three different types of app shortcuts:
- Static Shortcuts is a type of shortcut which provides you generic links to your application. Take Gmail for an example, static shortcuts may include: “Go to compose screen” or “Show all important emails.”
- Dynamic Shortcuts provides links to a specific, context-sensitive actions within your app. For example, If I have three different email accounts that has been already logged in into Gmail than I can have three different dynamic shortcuts to go directly to these accounts.
- Pinned Shortcuts (only available on Android 8 / API 26 and higher). This type of shortcut allows you to have separated home screen icons for individual shortcuts.
2. Building a simple launcher application
In order to take advantage of this new API, your application must also be a launcher.
Let’s build an example launcher that demonstrates these new shortcut types. Now that Google has officially announced support, I will be using Kotlin to demonstrate these features.
- Firstly we create AppManager class to query and manage runnable applications
Here we use queryIntentActivities to query all the activity that matches can handle a given Intent. In our case we only care about runnable applications — which should have an entry point activity. The Intent that satisfies these conditions should have:
- Action = Intent.ACTION_MAIN
- Category = Intent.CATEGORY_LAUNCHER
2. Secondly we use RecyclerView to display all the applications
3. Thirdly we have to declare a launcher activity inside AndroidManifest
Now, run your application and click the home button. Android will show the dialog asking you to pick which application you want to choose to be the default launcher. Let’s choose us of course!
4. Okay, we are now a launcher. Let’s test this by opening an app.
3. Adding shortcuts to the application
Now for the most interesting part! Let’s scan all of the other app’s Shortcuts and display them in our launcher.
- To do this, we query the shortcuts with a given packageName using the getShortcuts api. This returns a List<ShortcutInfo>.
Android provides a class named LauncherApps that we can use to query and start a shortcut. We can retrieve an instance of it using
private val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
In order to query the different types of shortcuts, we will use the ShortcutQuery class provided by Android. Each type of shortcut uses a different flag. These flags can be bitwise combine to query multiple types at once, just like we do above.
- Static Shortcuts — FLAG_MATCH_MANIFEST
- Dynamic Shortcuts — FLAG_MATCH_DYNAMIC
- Pinned Shortcuts — FLAG_MATCH_PINNED
Note: the method launcherApps.getShortcuts() is throwing Security Exception. This is because only the default launcher can query shortcuts. If you are not the default, this would be a great place to inform the user to make you the default in order to add shortcuts.
- This returns the List<ShortcutInfo>. Each ShortcutInfo has all of the metadata needed to display, however you will need to resolve the name and icon.
- The name is resolved by using ShortcutInfo.shortLabel or ShortcutInfo.longLabel.
- The shortcut drawable can be resolved using:
launcherApps.getShortcutIconDrawable(shortcutInfo,
context.resources.displayMetrics.densityDpi)
2. Implement the UI
Again I will use RecyclerView to display a list of shortcuts and display the list inside a PopupWindow. Whenever the user long click an application we will try to display the list.
3. Let’s run and test our application
4. Conclusion
Google has created a really cool way to get access to your app quickly. If you are building a launcher do not forget to leverage these apis
Thank you for spending time reading the article and happy coding