Android App Shortcuts in Xamarin

Great mobile apps and luxury cars are similar, in that a lot of attention is paid to even the smallest details. Since Android version 7.1 (API 25) there is a new feature that lets users get to a specific screen or an action right from the home screen — Shortcuts. Although the feature has been available for quite a long time (since Dec 2016) there are tons of apps which haven’t adopted it yet. Having Shortcuts will not only make your app more professional but will also significantly improve UX. Let’s take a deeper look!


Long tap on the app icon to open a shortcut menu

There are three types of shortcuts:

  • Static shortcuts — defined in a resource file which is a part of the app;
  • Dynamic shortcuts — shortcuts that are created (also updated or removed) during runtime;
  • Pinned shortcuts — also created during runtime which appear in launchers as separate app icons. Pinned shortcuts cannot be removed programmatically.

Let’s walk through creating shortcuts using a real example. Meet the STAmina app — an app used by athletes of all kinds of underwater sports to improve breath-holding skills.

 

The app doesn’t publish any shortcuts yet

Note: Before proceeding to shortcuts itself, we need to make sure that the targetSdkVersion (Android Project -> Options -> Android Application -> Target Android version in VS for Mac) is set to 25 or greater.

Static Shortcuts

A good candidate for a static shortcut is the Add Apnea Exercise page. It’s used quite often and is always available. First, we need to let the OS know that the app has static shortcuts. This is done by adding a new meta-data to the android manifest (in Xamarin by having an additional class attribute for the Main Activity):

[Activity (Label = "STAmina",
  MainLauncher = true,
  Icon = "@mipmap/ic_launcher",
  RoundIcon = "@mipmap/ic_launcher_round",
  Theme = "@style/Theme.Splash",
  NoHistory = true,
  ScreenOrientation = ScreenOrientation.Portrait)]
[MetaData("android.app.shortcuts", Resource = "@xml/shortcuts")]
public class SplashScreen : MvxSplashScreenActivity
{
}

Notice that we reference an @xml/shortcuts resource. Let’s create it by adding a new shortcuts.xml file under the Resources/xml/ folder.

<shortcuts xmlns:android="https://schemas.android.com/apk/res/android">
  <shortcut
    android:shortcutId="add_new"
    android:enabled="true"
    android:icon="@drawable/shortcut_add"
    android:shortcutShortLabel="@string/shortcut_add_new_short"
    android:shortcutLongLabel="@string/shortcut_add_new_long"
    android:shortcutDisabledMessage="@string/shortcut_add_new_disabled">
    <intent
      android:action="android.intent.action.VIEW"
      android:targetPackage="com.squarecrowdapps.stamina"
      android:targetClass="com.squarecrowdapps.stamina.MainView">
            <extra android:name="shortcut" android:value="add_new" />
      </intent>
    <categories android:name="android.shortcut.conversation" />
  </shortcut>
  <!-- Specify more shortcuts here. -->
</shortcuts>

It is recommended to limit the length of shortcutShortLabel to 10 characters and the length of shortcutLongLabel to 25 characters due to the limited space within the menu.

There is a design guidelines document on how to design shortcut icons. You can find it here.

The enabled attribute works in pair with the shortcutDisabledMessage attribute. If for some reason we will decide to disable the ‘Add Apnea Exercise’ shortcut in the future, we will set enabled to false and put an explanation of why it’s disabled into shortcutDisableMessage and publish a new version of the app. This will do the following:

  1. The ‘Add Apnea Exercise’ shortcut will be removed from the shortcut menu;
  2. If a user had pinned the ‘Add Apnea Exercise’ shortcut to the home screen, the shortcut will be greyed out and shortcutDisableMessage will be displayed if the user taps on it.

Next, we provide the intent to navigate users to the correct place within the app. Before referencing an activity, make sure that the Activity attribute of that activity has the Exported property set to true and specifies the type name in the Name property (by default, the type name of an activity is based on the MD5SUM of the assembly-qualified name of the type being exported, which is not quite user friendly).

[Activity(Label = "STAmina",
          Theme = "@style/StaminaAppTheme",
          ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait,
          Exported = true,
          Name = "com.squarecrowdapps.stamina.MainView")]
public class MainView : MvxAppCompatActivity<MainViewModel>, View.IOnClickListener, Toolbar.IOnMenuItemClickListener
{
}

Note: Make sure that you have set these properties and the value of the targetClass attribute from the shortcuts.xml matches the type name, otherwise users will be getting an ‘App isn’t installed’ error when tapping on the shortcut.

And last we check extras within the ‘OnCreate’ method and do the navigation.

protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    ...
    if (Intent?.Extras?.ContainsKey("shortcut") == true)
    {
        // Check the value and navigate to the appropriate screen
    }
    ...
}

That’s it with static shortcuts!

Dynamic Shortcuts

Now it’s time to create some dynamic shortcuts. From the UX point of view, it’s worth adding links to the most frequently used screens and actions. Let’s update the app to show shortcuts to recently used exercises (users tend to use 2–3 different kinds of exercises until they advance to more difficult ones), but before creating shortcuts, make sure that the API version is 25 or greater.

if (Build.VERSION.SdkInt < BuildVersionCodes.NMr1)
{
    return;
}

To create a dynamic shortcut we will use ShortcutManager. 

var shortcutManager = (ShortcutManager)context.GetSystemService(Context.ShortcutService);
var newIntent = new Intent(context, typeof(MainView));
newIntent.SetFlags(ActivityFlags.ReorderToFront | ActivityFlags.ClearTop);
newIntent.PutExtra("shortcut", "table");
newIntent.PutExtra("tableId", tableId);
newIntent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
newIntent.AddCategory("android.intent.category.LAUNCHER");
newIntent.SetAction("android.intent.action.MAIN");
ShortcutInfo shortcut = new ShortcutInfo.Builder(context, "table-" + tableId)
                                        .SetShortLabel(tableName)
                                        .SetLongLabel(tableName)
                                        .SetIcon(Icon.CreateWithResource(globals.ApplicationContext, Resource.Drawable.shortcut_o2))
                                        .SetIntent(newIntent)
                                        .Build();

Here we fill the same information as we did in the shortcuts.xml. The only difference is that since we’re creating a link to the user-generated content, we put an additional piece of information in the extras (that is exercise id). Also, notice that the shortcut ID is unique.

And finally, let’s create a shortcut.

shortcutManager.SetDynamicShortcuts(new List<ShortcutInfo> { shortcut });

SetDynamicShortcuts will replace all current shortcuts with new ones (the ones that are passed as the parameter merged with static shortcuts). Alternatively, we could use AddDynamicShortcuts which adds shortcuts to the existing list. It is recommended to have no more than 4 shortcuts.

Static and dynamic shortcuts in action

Looks good, we’re almost there! Now let’s do some housekeeping. Imagine that the user deleted the ‘Easy — 10 m’ exercise. Or even had pinned the shortcut to the home screen and then deleted the exercise (remember, pinned shortcuts cannot be removed programmatically). What will happen with the shortcuts? Nothing. They’ll still be there and will take the user to a non-existing page (which probably will crash the app). To avoid that we need to remove (dynamic) and disable (pinned) shortcuts each time when an exercise is deleted.

var shortcutManager = (ShortcutManager)context.GetSystemService(Context.ShortcutService);
shortcutManager.RemoveDynamicShortcuts(new List<string> { "table-" + tableId });
shortcutManager.DisableShortcuts(new List<string> { "table-" + tableId });

Notice that we reuse the same unique shortcut ID here.

Disabled pinned shortcut

App Shortcuts are an easy to implement feature that your app can benefit from. Well thought out navigation simplifies the use of the application and improves user satisfaction. Don’t miss this opportunity.

Related Blog Posts

We hope you’ve found this to be helpful and are walking away with some new, useful insights. If you want to learn more, here are a couple of related articles that others also usually find to be interesting:

Our Gear Is Packed and We're Excited to Explore with You

Ready to come with us? 

Together, we can map your company’s tech journey and start down the trails. If you’re set to take the first step, simply fill out the form below. We’ll be in touch – and you’ll have a partner who cares about you and your company. 

We can’t wait to hear from you! 

This field is for validation purposes and should be left unchanged.

Together, we can map your company’s tech journey and start down the trails. If you’re set to take the first step, simply fill out the form below. We’ll be in touch – and you’ll have a partner who cares about you and your company. 

We can’t wait to hear from you! 

Montage Portal

Montage Furniture Services provides furniture protection plans and claims processing services to a wide selection of furniture retailers and consumers.

Project Background

Montage was looking to build a new web portal for both Retailers and Consumers, which would integrate with Dynamics CRM and other legacy systems. The portal needed to be multi tenant and support branding and configuration for different Retailers. Trailhead architected the new Montage Platform, including the Portal and all of it’s back end integrations, did the UI/UX and then delivered the new system, along with enhancements to DevOps and processes.

Logistics

We’ve logged countless miles exploring the tech world. In doing so, we gained the experience that enables us to deliver your unique software and systems architecture needs. Our team of seasoned tech vets can provide you with:

Custom App and Software Development

We collaborate with you throughout the entire process because your customized tech should fit your needs, not just those of other clients.

Cloud and Mobile Applications

The modern world demands versatile technology, and this is exactly what your mobile and cloud-based apps will give you.

User Experience and Interface (UX/UI) Design

We want your end users to have optimal experiences with tech that is highly intuitive and responsive.

DevOps

This combination of Agile software development and IT operations provides you with high-quality software at reduced cost, time, and risk.

Trailhead stepped into a challenging project – building our new web architecture and redeveloping our portals at the same time the business was migrating from a legacy system to our new CRM solution. They were able to not only significantly improve our web development architecture but our development and deployment processes as well as the functionality and performance of our portals. The feedback from customers has been overwhelmingly positive. Trailhead has proven themselves to be a valuable partner.

– BOB DOERKSEN, Vice President of Technology Services
at Montage Furniture Services

Technologies Used

When you hit the trails, it is essential to bring appropriate gear. The same holds true for your digital technology needs. That’s why Trailhead builds custom solutions on trusted platforms like .NET, Angular, React, and Xamarin.

Expertise

We partner with businesses who need intuitive custom software, responsive mobile applications, and advanced cloud technologies. And our extensive experience in the tech field allows us to help you map out the right path for all your digital technology needs.

  • Project Management
  • Architecture
  • Web App Development
  • Cloud Development
  • DevOps
  • Process Improvements
  • Legacy System Integration
  • UI Design
  • Manual QA
  • Back end/API/Database development

We partner with businesses who need intuitive custom software, responsive mobile applications, and advanced cloud technologies. And our extensive experience in the tech field allows us to help you map out the right path for all your digital technology needs.

Our Gear Is Packed and We're Excited to Explore with You

Ready to come with us? 

Together, we can map your company’s tech journey and start down the trails. If you’re set to take the first step, simply fill out the contact form. We’ll be in touch – and you’ll have a partner who cares about you and your company. 

We can’t wait to hear from you! 

This field is for validation purposes and should be left unchanged.

Thank you for reaching out.

You’ll be getting an email from our team shortly. If you need immediate assistance, please call (616) 371-1037.