072: App Shortcuts with Andrew Orobator

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].

Download directly

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.