Quick Tip: Introducing Android O’s Adaptive Icons and Pinned Shortcuts

In this series of quick tips we’ve been looking at some of the upcoming UI changes you can start working with today, via the Android O Developer Preview.

Quick Tip: Introducing Android O’s Adaptive Icons and Pinned Shortcuts

In this final post in the series, we’re going to look at how you can create launcher icons that integrate perfectly with the device’s wider UI, and how to create shortcuts that enable users to jump directly to your app’s most important actions, directly from their homescreen.

Creating Adaptive Icons

With the release of Android O, Original Equipment Manufacturers (OEM) such as HTC and Samsung are going to have the option to provide a mask which the system will apply to all application launcher icons. Masks ensure that all the icons that appear on that device have the same shape: if the OEM provides a circular mask then all the application launcher icons will be circular, and if it provides a rounded square (or “squircle”) mask, then all the icons will have rounded corners.

These adaptive icons are intended to provide a more consistent look and feel across the device’s launcher and in other areas where launcher icons feature prominently, such as your device’s Settings and sharing dialogues.

To ensure that your launcher icons display correctly regardless of the mask being used, you’ll need to make a few adjustments.

Before you get started, check that your Manifest’s android:icon attribute is pointing at the image you want to use as your launcher icon:

<application
  android:label="@string/app_name"
  android:allowBackup="true"
  android:icon="@mipmap/ic_launcher"
  android:supportsRtl="true"
  android:theme="@style/AppTheme">

Each adaptive icon consists of a background layer, a foreground layer, and a mask. The latter is provided by the OEM, but you’ll need to provide the background and foreground layers. For the best results, these layers should be PNGs without any masks or background shadows. Both layers must be 108×108 dpi, but the inner 72×72 dpi is the content that’ll appear within the masked viewport, as the system reserves the outer 36 dpi around the icon for visual effects, such as pulsing or parallax.

Create your background and foreground layers and then add them to your project. Next, create a res/mipmap-anydpi/ic_launcher.xml file and use it to reference the two drawables you want to use as your background and foreground layers, for example:

<?xml version="1.0" encoding="utf-8"?>
  http://schemas.android.com/apk/res/android">
      <foreground android:drawable="@mipmap/ic_foreground"/>
      <background android:drawable="@mipmap/ic_background"/>
  </adaptive-icon>

Quick Tip: Introducing Android O’s Adaptive Icons and Pinned Shortcuts

Depending on the design of your particular icon, it’s possible that circular masks may cut off some important content. If you suspect that circular masks might pose a problem for your icon, then you can create a dedicated circular icon that the system will use whenever it’s applying a circular mask.

Create this circular icon, add it your project, and then reference this version of your icon in your project’s Manifest, using the android:roundIcon attribute.

<application
  android:label="@string/app_name"
  android:allowBackup="true"
  android:icon="@mipmap/ic_launcher"
  android:roundIcon="@mipmap/ic_launcher_round"
  android:supportsRtl="true"
  android:theme="@style/AppTheme">

Pinning Shortcuts

Some devices running Android will allow users to pin application shortcuts to their launcher. These shortcuts appear as separate icons that the user launches by tapping, in exactly the same way they interact with regular application launcher icons.

Each application shortcut will reference one or more Intents, which each launch a specific action within your app. This makes pinned shortcuts a great way of allowing users to jump to your app’s most important tasks and content straight from their homescreen. For example, you might create a shortcut that takes the user to the latest save point in your gaming app, or to their most frequently used contact.

There’s no limit to the number of pinned shortcuts you can offer, although to ensure your app doesn’t take over the user’s launcher it’s recommended that you only offer four shortcuts at any one time.

To offer one or more pinned shortcuts, you’ll first need to create an instance of ShortcutManager:

ShortcutManager myShortcutManager =
       context.getSystemService(ShortcutManager.class);

Then, check that the user’s device actually supports pinned shortcuts:

if (mShortcutManager.isRequestPinShortcutSupported()) {

This returns TRUE if the default launcher supports requestPinShortcut.

Assuming that the device does support in-app shortcuts, you can then create a ShortcutInfo object that contains an ID, an intent, and a label for this particular shortcut.

ShortcutInfo pinShortcutInfo = ShortcutInfo.Builder(context, "my-shortcut");
  .setShortLabel(getString(R.string.shortcut_label))    
  .setLongLabel(getString(R.string.shortcut_long_label))
  .setIcon(Icon.createWithResource(context, R.mipmap.ic_launcher))
  .setIntent(new Intent(Intent.ACTION_VIEW,
                  Uri.parse("https://www.google.com")))
   .build();

Finally, you pin the shortcut by calling requestPinShortcut().The default launcher will receive this request and then ask the user to approve or deny the pinning operation. If your app needs to know whether the pinning operation was a success, then at this point you can also create a PendingIntent object.

//Here, we’re assuming that our project already includes a createShortcutResultIntent() method, which will return the broadcast intent//
Intent pinnedShortcutCallbackIntent =
           createShortcutResultIntent(pinShortcutInfo);

PendingIntent successCallback = PendingIntent.createBroadcast(context, 0,
           pinnedShortcutCallbackIntent);
mShortcutManager.requestPinShortcut(pinShortcutInfo,
           successCallback.getIntentSender());

This PendingIntent will only send a resultIntent if the pinning operation is a success. Your app won’t receive a notification if the operation fails.

Once the pin has been created, you can update its content using the updateShortcuts() method. Just be aware that pinned content or actions usually have a shelf-life. In our gaming example, the user may reach the end of the game or delete their save file, at which point your pinned shortcut won’t have any content to display.

While it’s tempting to recycle a pinned shortcut by tweaking its original purpose, it’s far less confusing for the user if you disable shortcuts that are no longer relevant. If a pinned shortcut does reach the end of its life, then you can disable it by calling disableShortcuts().

Conclusion

In this series we’ve looked at some of the Android O user interface updates that you can start experimenting with today by installing the first Developer Preview. In part one, I showed you how to create text that auto scales based on the current screen configuration; in part two we looked at adding custom fonts to your Android projects, and in this final post in the series we’ve covered adaptive icons and pinned shortcuts.

While you’re here, check out some of our other posts on Android app development!

  • Quick Tip: Introducing Android O’s Adaptive Icons and Pinned Shortcuts
    Android SDK
    RxJava 2 for Android Apps: RxBinding and RxLifecycle
    Jessica Thornsby
  • Quick Tip: Introducing Android O’s Adaptive Icons and Pinned Shortcuts
    Android
    Introduction to Android Things
    Paul Trebilcox-Ruiz
  • Quick Tip: Introducing Android O’s Adaptive Icons and Pinned Shortcuts
    Android SDK
    Java vs. Kotlin: Should You Be Using Kotlin for Android Development?
    Jessica Thornsby
  • Quick Tip: Introducing Android O’s Adaptive Icons and Pinned Shortcuts
    Android SDK
    Sending Data With Retrofit 2 HTTP Client for Android
    Chike Mgbemena