Download directly

In this episode, we talk to Android developer Andrew Orobator. He gives us the lowdown on the new feature App Shortcuts that was introduced in Android. We talk about static and dynamic shortcuts, use cases for other shortcuts and how to implement them for your app. We also cover what the feature lacks and things to watch out for, while implementing them. Listen on!

Fragmented also has spanking new music from the super talented Blueprint: you can find out more at [email protected].

Show Notes

Andrew’s Medium posts

Misc

Sponsors

Contact

Transcript

Donn Felker: Kaushik, it’s been a while, but we’re finally back.

Kaushik Gopal: Yes we are. How has your 2017 been so far?

DF: Well, it’s a new year, so I think it’s only right to talk about something new which neither you or I have done. I work with an individual named Andrew, and we’ve invited him on the show to talk with us about application shortcuts, a newly released Android feature. Without further ado, welcome to the show, Andrew.

Andrew Orobator: Thank you.

DF: For folks who aren’t familiar with you and haven’t read any of your really good blog posts, can you tell us a little bit about your background—how you got started in Android development, where you work, and so forth?

AO: Sure thing. In the summer of 2013, I had just finished up a class on Java. I had a new HTC One (M7) that I wanted to put some music on, instead of carrying around my old iPod Classic. I tried out several music players, but none of them really worked the way I wanted them to. So I set out to make my own—which I actually just released to beta in the first week of January. It’s called Auracle Music Player.

I currently work as a Android engineer for American Express (which is how I met Donn), although I’ll be joining the team at 7Park Data in a few weeks.

DF: What does 7Park do?

AO: 7Park Data generates analytics for millions of users of popular apps. Then they take all of that data and apply machine learning algorithms to it, and they essentially provide consumer insights.

KG: Very cool! That sounds exciting. Are you excited about it?

AO: Yeah, I’m super excited. I did a couple of machine learning classes in college (just the basics, but enough to get by), so it’s going to be really exciting to work closely on the Android side with machine learning.

KG: Will you be building the client-facing consumption point for that data?

AO: That’s correct. I’ll be working on the app that’s accumulating data and sending it to their backends.

KG: We’ll stay tuned and have you back on the show sometime so we can learn more. Look at us, already pushing the next episode!

DF: Andrew, when I was visiting New York, you showed me a blog post you had written about implementing app shortcuts, so we thought it would be perfect to have you on the show to talk about that. Have you written just the one blog post, or have you written or talked more about it?

AO: So there was a blog post, a talk I gave about it at AmEx, and an open-source repository on GitHub to go along with all of this.

KG: Fantastic.

To kick this off, what exactly are app shortcuts? I know that Google has recently released a whole bunch of new features in Android 7. I know that app links, instant apps, and app shortcuts exist, but I know nothing about app shortcuts. Could you tell me what app shortcuts are, and why they’re interesting as Android developers?

AO: App shortcuts are primary actions or deep links into your app that can be accessed via a long press on the app icon. You can pin these shortcuts to your home screen by long pressing and dragging them from the menu that appears. For all of you iOS folks, this is pretty similar to a Force Touch, although app shortcuts are implemented in software, not hardware.

KG: Got it. So in iOS, there’s some pressure-sensitive aspect in the hardware that triggers an app shortcut, but in Android, it’s just a long press.

DF: Where exactly are these app shortcuts available? Can I only do them on my home screen, or can I do it the app launcher? What about custom launchers?

AO: It really depends on the launcher’s implementation, since they’re the apps that actually choose how to display these shortcuts. You implement app shortcuts by providing data that says, “Hey, this is what I want to display,” and then the launcher figures out how and when to display it. In both Nova Launcher and the Google Now Launcher, you can access shortcuts on the home screen, but you can also access app shortcuts in the app drawer using the Google Now Launcher.

KG: Interesting. So, even if you did have it technically implemented in your application, it would only be seen in the specific launchers that are capable of launching it, right?

AO: That’s correct.

KG: How else can you use this? Donn and I have been wondering if you actually use these from the home screen. For example, I have a to-do application, and there’s one task that I keep doing, to the point where I’m thinking, “You know what? This should just be the default.” Is there a way to pin that specific action to my home screen, in my list of app shortcuts?

AO: Absolutely. Individual shortcuts can be pinned to the home screen, but (again) this is up to the launcher app that the user uses—although I haven’t seen any that diverge from that.

DF: Let’s reel back for a second. You’re an application developer. When you developed Auracle, why did you decide to implement app shortcuts? How do they benefit the user?

AO: Personally, I’m a big fan of playlists. I love making custom playlists, and I mostly listen to playlists when I’m listening to music. Sometimes I know the exact playlist I want to listen to. Auracle provides shortcuts to my most listened to playlists, and I can just pin my favorites on my home screen. Instead of opening the app and navigating to the playlist, I can just click on the playlist right from the home screen.

DF: I used to work at MyFitnessPal, which had a calorie tracking app. If they wanted to allow folks to go straight to the food diary, they could implement a custom shortcut to do that, correct?

AO: Yeah, that sounds about right.

KG: Since we are talking about example applications, it’s easier to sell app shortcuts as a feature when people can see examples of applications that do this. You said that your music player has a playlist menu. I could have sworn that Pocket Casts (a podcast player that many of us use) also has something along those lines. Are there any other apps that jump out to you as doing this pretty well?

AO: Yeah. Google Maps has really good app shortcuts. When you press on the Maps icon, two shortcuts appear: “Home” and “Work”. When you click on “Home,” it’s opens up directions to your home.

KG: Why have I not done this? Immediately, I’m understanding why you use this.

DF: Okay, end the podcast. Thanks, we’re good to go!

No, I’m literally on my phone right now, playing with this. I’m long pressing random icons. Pocket Casts has a bunch of options. Google Play Music has everything. It’s almost as if, if you have analytics on your application and you’re able to tell what users do the most, it would be a good thing to implement that as an app shortcut.

AO: That’s actually a really solid idea.

DF: Yeah, I’m looking at Play Music now. Every time I open it, I always seem to go to “My Library”, because I create playlists (just like you, Andrew). I have a productivity playlist (music with no lyrics) and another playlist for working out. I always open the app, and I’m buried in some search that I was doing. Then I have to navigate back to the home screen, go to “My Library”, and then to “My Playlists”.

But with this app shortcut that they have, I can go straight to “My Library” or my recent activity. I skipped all of these steps. Just like you said for Maps, it’s just a huge timesaver—I mean, let’s be honest: every time you open Maps you’re either going somewhere from home, or you’re going home. You’re probably going home 50% of the time, so that’s a humongous time savings.

KG: Donn, you know that I have problems with to-do applications. I go a little bonkers about a whole bunch of them: Trello, Asana, Todoist, etcetera (yes, I’ve used all of them—and actually still do!). One thing that I find super helpful about the app shortcuts is the ability to hold and press the icon and quickly add tasks to specific projects. You can also do searches faster, which makes sense. This is pretty slick. I’m really liking this, especially for applications that primarily use one action really quickly. I imagine that an app shortcut is a great thing there.

It’s funny though. I was looking at Uber and Lyft and thinking about the Maps thing. Being developers, we’re kind of lazy that way. I was thinking, “Maybe Uber and Lyft should have a ‘Get me a ride home’ button.” I’m sure that’s coming down the line, though.

AO: That would actually be awesome.

KG: That would be pretty slick. It would be a huge time saver.

Alright, so we’ve been talking about all the advantages this has, but are there any limitations to this? For example, are these only available on an API level? Because if you’re a developer, you’re thinking, “Oh my God, this is amazing,” but then you use API 14 or 15 and no one sees it. Can you tell us a little more about some of those limitations?

AO: Sure. App shortcuts were introduced in Android 7.1, so they can only be used on API level 25 or above. When you’re actually writing code, you have to check against Build.VERSION_CODES.N_MR1.

DF: That’s the hidden beast in Android sometimes. You’ve got a new cool feature that comes out in the new APIs, but you can’t use it until everyone is using it.

Thankfully, I have it, though!

KG: And that’s all that matters!

One quick follow-up question to that: there are actually two limitations here, right? One is the API level, which (you rightly mentioned) is API 25. Then there’s also the fact that only certain launchers allow this. Developers have to keep that in mind, because we can’t just say, “Okay, set the minimum API to 25.” If you can…oh man, you’re living the life. But it’s not just about setting your SDK to 25. It’s also about the fact that it’s only currently available in certain launchers.

AO: Right. When you’re testing, it makes a lot of sense to test your implementation on different launchers, like Nova Launcher, Action Launcher, and the Google Now Launcher.

DF: What are some of the challenges that you’ve encountered while implementing app shortcuts on your personal projects?

AO: For starters, you can’t have an unlimited number of app shortcuts. In theory, you’re allowed a maximum of 5, which are any mix of static and dynamic shortcuts. Your app will actually crash if you provide more.

KG: Oh, that’s aggressive. I like it!

AO: They’re hard and fast with their limitations. In practice, you only see four app shortcuts, anyway. You can provide five, but I’ve never actually gotten that to show up. It’s kind of weird like that.

Another gotcha when you’re making app shortcuts comes when you want to disable shortcuts if the actions they represent become unavailable in your app. In Auracle, I include the most listened to playlists as shortcuts. But if they’ve pinned that shortcuts to their home screen, and then they delete the playlist, it’s a dead link. If they try to open a deleted playlist, the app could potentially crash. So every time a user deletes a playlist, I disable the shortcut for the playlist as well. When they try to click on the deleted playlist, the launcher will display a “shortcut disabled” message instead of potentially crashing your app.

KG: Those are considerations that you have to make, but in the larger scheme of things, this is pretty amazing! You know what? You’ve sold me. I want to implement this right away, because it sounds really interesting to me. How do I go about implementing app shortcuts? Where do I start? I mean, I have no clue. So, as a developer, what’s step 1?

AO: The first thing you should know is that there are two different types of app shortcuts: dynamic and static.

DF: What’s the difference between the two? When would you use a static one, and when would you use a dynamic one?

AO: A static shortcut is defined in the XML that’s bundled in your APK. That means that you can only update them when you update your app in the Play Store. Dynamic shortcuts, on the other hand, can be updated at runtime.

You’d use a static shortcut to represent core action for your app. For example, Google Maps has two shortcuts that offer directions to your home and your work. While I don’t have the source for the Maps application, I would have made those static shortcuts, because they’re core actions. They don’t just disappear at the whim of the user. On the other hand, if your app shortcuts represent actions performed on user-generated content, you should consider using dynamic app shortcuts. For example, a messaging app could provide shortcuts to a user’s most recent conversations or favorite contacts.

KG: Let’s keep step one simple. I know that are some cool things I’m already thinking of that can be done with dynamic shortcuts, but suppose I just want to make a basic application to help me get a feel of how this thing works. Let’s talk about just static shortcuts. How do I go ahead and implement one?

AO: When you’re implementing a static shortcut, it’s all in the XML, so the first thing you’re going to do is edit your Android Manifest. You’ll need to add a metadata tag to your launcher activity. You can actually drop this tag onto any launcher activity, so if you have multiple activities showing up in the launcher, each one can be assigned separate app shortcuts. So you add a metadata tag to your launcher activity, with the name android.app.shortcuts and the resource @xml/shortcuts.

The next step is to actually create the shortcuts.xml file in the xml-v25 folder. Note the resource qualifier saying that it’s only for version 25 and above. Technically, Android won’t crash without it, but Android Studio gives you a warning about it, so it’s best practices to just use the qualifier.

DF: You said that you were going to create an @xml/shortcuts resource. What’s contained inside of that XML metadata?

AO: There are a bunch of attributes which you can specify for static app shortcuts. The major ones are the shortcut labels (the text that you see associated with your shortcut), the icon (which you usually see to the left of the text), and the intent(s) used to launch the user into your app. You can actually specify multiple intents as you’re defining these in XML, if you would like to create a back stack when the user taps on your shortcut.

KG: Interesting. Actually, that makes sense now, assuming (like you said) that you have an action which takes you into an activity, and you want to back out into another activity—for example, if Twitter had a new tweet shortcut, and after backing out of that, they wanted to take you back into the timeline—you can do that. The framework allows that.

AO: That’s exactly right.

KG: Is there any possibility of shortcuts being enabled and disabled? How does that work? For example, maybe I don’t want a certain shortcut (taking the example of Twitter again, a new tweet) to happen, if they aren’t logged in. You cannot enter a new tweet unless you’re signed in, or something along those lines. Is there any way to handling that?

AO: You can mark your shortcut as disabled in code. Just as a note: you cannot modify static shortcuts at runtime. You will get an exception, and your app will crash. You can only disable dynamic shortcuts.

KG: Oh, that’s good to know.

AO: If you want to disable a static shortcut, you’ll have to do it in XML on the next APK update from the Play Store. But when you disable a shortcut, the launcher (at least, Google Now Launcher) turns the shortcut icon into grayscale. Then, even if it was pinned on the home screen, it’s not going to appear in the shortcuts menu at all either. If you click on the grayed out icon, a short toast will pop up containing the shortcut disabled message. The default is literally “Shortcut disabled,” but you can override that to provide more information to your user.

DF: Now you have these various different static and dynamic shortcuts. But from what I’ve been able to read, it seems that you can provide an icon to go with that. Does that icon have to be your app icon, or can it be a custom icon?

AO: It’s really a mix of both custom and app icons. So the app shortcut’s main icon will be the one you provide. That’s the big icon that you’ll see—the main icon. It’s going to appear as a small badge on top of the app shortcut icon.

DF: Okay. Are there any icon design guidelines we should follow as we develop these app shortcut icons?

AO: Absolutely. Google actually released design guidelines for app shortcuts. The basic gist of it is that you have a 48 dp square icon, which should feature a Material Gray 100 circle with a diameter of 44 dp. In the middle of that circle, you have a 24 dp square icon specifying the action.

KG: Wow. I guess that’s to bring some consistency to it, especially since it’s so visible to users.

AO: Exactly.

KG: Interesting. A quick follow-up question to that: you can’t use vectors there, I imagine—or can you?

AO: Vectors were introduced in API 21, and you’re on version 25 when you do app shortcuts, so you can definitely use vectors.

KG: Along the same lines of controlling what the user sees, what options do I have?

AO: You can control the label that the user sees in a couple of ways. There’s a short label and a long label. It’s recommended that the short label be less than or equal to 10 characters, and the long label be less than or equal to 25 characters. Android picks the appropriate one to display based on the space available, but I’ve noticed that the short label is usually used when something is placed on the home screen, and the long label is usually used whenever there is space in the app shortcut menu.

KG: Interesting. So that’s just a general guideline so far.

AO: Right, but if any of these labels are too long, they’ll just be truncated with ellipses.

DF: So how do we control what a shortcut does? Do they use the intent system? Do we have to create an intent? How does that work?

AO: It’s just a regular intent, but it has some requirements. It has to have an action specified, and you’ll crash if you don’t have one. If having an action doesn’t really make sense for your application, you still need to put something. I’d recommend using the value android.intent.action.VIEW, although the string you use doesn’t really matter. It could be an empty string if you wanted it to be. You’ll also need to specify the target class (the activity you want to launch) and the target package (your package name). Then, if you want to create a back stack (like we talked about earlier), you can define multiple intents in a list, and the last one in the list will be what the user sees when they click on your app shortcut.

KG: That makes sense. I’m sufficiently intrigued by static shortcuts, so I want to up my game and do dynamic shortcuts. Can you walk us through how dynamic shortcuts actually work, so that I can get a better understanding of how I’d go about implementing them?

AO: Dynamic app shortcuts have all the same attributes as static app shortcuts, but they can be updated, modified, created, or destroyed at runtime. That’s the main difference.

KG: What’s the reason why I’d want to use one of these, again (just so we refresh our understanding of this)?

AO: I would recommend using dynamic shortcuts if you’re going to deep-link to user generated content. In Auracle, I have dynamic shortcuts to the user’s most listened to playlists. Or, a messaging app could provide shortcuts for the most recent or most active conversations.

DF: You said before that there’s a limitation to the number of shortcuts you can have, but when I think of something dynamic, I think of something that can be updated at runtime. If I can’t have more than five shortcuts, would I be correct in assuming that I could technically update one particular shortcut with an infinite number of options?

AO: That totally makes sense. It’s a dynamic shortcut, so you can continuously update it, and it will continuously change. You could even change what actions it represents in code.

KG: Interesting. So, in that case, can even the short and long labels that you talked change, or would those have to be generic?

AO: When you’re creating a shortcut, you pass in a ShortcutInfo. That contains all of the attributes of the shortcut, including the long label and the short label. As long as you pass in the ID of the shortcut, it’ll update everything that’s in there with the current values from the ShortcutInfo.

KG: How do I go about creating, destroying, or even updating these shortcuts?

AO: You have to go through the ShortcutManager. The ShortcutManager is the class that you interact with whenever you’re dealing with app shortcuts.

DF: So if I’m going to work with the ShortcutManager, how do I get an instance of it? Where does it come from?

AO: You can get an instance using context: getSystemService(ShortcutManager.class). Make sure to only do that on API 25 and above, since ShortcutManager doesn’t exist on previous versions of Android. If you try to do this on API 24, you’re going to get a “class not found” exception.

KG: Does Lint warn us of that? I know there’s the Lint max API option, and there’s a Lint error that specifies when something is available only beyond your max API, but do you know (off the top of your head) if Lint warns you of this?

AO: I’ve got Android Studio open. I can check.

KG: Nice! That’s how we do it here!

AO: Let’s see. Android Studio doesn’t currently provide a Lint warning. My min SDK version is 19, and there’s no warning. Maybe I can file a bug for that.

KG: I was going to say that. You should hit those folks up, because they’re very open to suggestions.

DF: If we update shortcuts, what’s the procedure by which we need to go about it? Is there anything special we need to do?

AO: Whenever you’re interacting with the ShortcutManager, you’re usually interacting with batches of shortcuts, not just a single one. If you wanted to update some shortcuts, you would have a list of ShortcutInfos. Make sure that they all have the appropriate IDs and all of the up-to-date information, and then pass that list of ShortcutInfos to ShortcutManager.updateShortcuts.

KG: What are the steps again to create a dynamic shortcut?

AO: The first thing that you’re going to do is create a ShortcutInfo object. This details the attributes of the app shortcut, like the ID, the icon, the label, etc. There’s a really nice builder that you can use to get this done that helps you out with everything. You have to do this for every dynamic shortcut you make.

Then you pass the list of these shortcut info objects to ShortcutManager.setDynamicShortcuts.

DF: How do we get a reference to a particular shortcut? Say we wanted to remove one of those dynamic shortcuts—how would we go about that?

AO: If you know the ID of the shortcut, you could pass in a list of string IDs, because the IDs are strings. You call ShortcutManager.removeDynamicShortcuts and pass in that list.

DF: And then it just goes ahead and removes all of those.

It sounds like dynamic shortcuts are more work, but it seems that they do give you more flexibility. Would that be an accurate assessment?

AO: Yeah, that’s spot on. They’re super flexible.

In Auracle, the playlist icons for each app shortcut come from an icon font and color that’s customizable by the user. This means that there’s a ton of icon color combinations needed for the app shortcut icons. Instead of having my designer make assets for each and every different combination of icon color (bloating the APK), I have a custom view that draws the app shortcut icon to a bitmap. Then I use Icon.createWithBitmap, and pass the resulting icon to the ShortcutManager when I’m creating the shortcut.

KG: That’s pretty slick! You could play around with these things in so many ways.

So, is there some sort of heuristic that I can use when I’m starting out with a new application? Is there an easy way to say, “Okay, this is when you use a static shortcut, and this is when you use a dynamic shortcut”? This is just for people who want to try this out.

AO: In general, you should use a static shortcut for actions that your user can perform in your app that remain constant. For example, Evernote has an app shortcut that creates a note.

You should use dynamic shortcuts if you want to link to user-generated content, like conversations or playlists—things that are going to change over time.

DF: While we were having this conversation, I unlocked my device and went to Pandora. They actually have app shortcuts, and they’re great. It actually lists the top three stations that I play, which is a fantastic use of dynamic shortcuts.

Are there any best practices that you would recommend for app shortcuts in general?

AO: Every time a user navigates to a part of your app that’s accessible via shortcut, whether they got there using the shortcut or by navigating through the app, you should call ShortcutManager.reportShortcutUsed. That gives launcher apps the information they need to build a prediction model and promote the shortcuts that are likely to be used at any given moment.

KG: As you were mentioning this, I was playing around, and I opened up developer options and noticed something curious: there’s an option to “Reset ShortcutManager rate-limiting”. What’s up with that? I don’t even understand this concept. What does resetting the rate-limit mean?

AO: When you’re actively developing, you’re probably going to be using the updateShortcuts, setDynamicShortcuts, and addDynamicShortcuts methods pretty frequently. It’s important to know that Android limits how often these methods can be called if your app is in the background. If your app is backgrounded, Android just won’t let it update your shortcuts that often. It’s probably best for the user, actually.

In a production environment, this limit can be reset by bringing your app to the foreground. But in a development environment, you can go to developer options and hit “Reset ShortcutManager rate-limiting” to get rid of this limit.

KG: That makes sense. It’s nice to have the option there, so that you don’t have to manually figure out a way to trigger that.

DF: Can the same thing be done through ADB, if I wanted to automate this?

AO: There is an ADB shell command called reset-throttling.

DF: That makes it easier, especially in a test environment. That could be very useful.

Let’s bring this full circle. For me, one of the best ways I’ve found to learn things is by looking at sample apps and just reading and interacting with the code. Do you know of any sample apps that someone could inspect or download to see how to use static or dynamic shortcuts?

AO: I actually made a sample app called “Konstellations”. It simply has a list of constellations, and information about each one. Then I track the usage of each shortcut, so that on the home screen, it always provides app shortcuts for the most visited constellations. There’s also a static shortcut in there that will take you to a random constellation.

DF: Sweet. Where is this available at?

AO: On Github. Another thing to note about this project is that you can also toggle whether a shortcut is enabled or disabled via the app, so you get that behavior as well.

KG: Wait a minute…I just opened it up, and is this written in Kotlin?

AO: It’s 100% Kotlin. There’s a little bit of Java in there from the generated tests, but the entire project is written in Kotlin.

KG: People, if you also want to get a little dose of Kotlin, then this project is right up your alley as well.

App shortcuts seem to have been implemented pretty well. It doesn’t necessarily seem very daunting as a developer. I’m super curious about this, and I definitely want to try them out. Listeners, especially if you’re building apps, it’s easy enough to give this functionality to your users. I would encourage you to do it.

Thank you so much for letting us know about this, Andrew. It’s been an absolute pleasure.

AO: Thanks for having me on the show.

KG: If folks want to reach out to you with questions on some the nitty-gritty, interesting aspects of app shortcuts, is there a way they can do that?

AO: The best way to reach me online is via Twitter (@aorobator).

KG: I will say that you probably have one of the coolest last names of any guest we’ve ever had. It’s pretty badass.

AO: It’s Nigerian.

KG: Thank you so much again for coming on the show, Andrew.

DF: Thank you, Andrew.