Direct Share is a new feature in Android Marshmallow that allows users to share content to targets, such as contacts, within other apps. The core idea is that the user can directly share the relevant content without having to first open a second app, so Direct Share allows the user to skip a step in the usual sharing flow.

I came across Direct Share while working on our upcoming 1-day Android Platform Features and Community Tools classes, and now it’s become one of my favorite new additions in Android Marshmallow.

Direct Share Overview

One great example of Direct Share is sharing content to a contact in a messaging app. Here’s what that would end up looking like:

The usual share options appear, with Hangouts, Messages and Inbox listed at the bottom. However, the Direct Share targets are the various people listed at the top of this share dialog. Instead of clicking to share and then clicking into the desired messaging app like Hangouts, the most important contacts appear in the chooser dialog itself. In this flow, the user doesn’t have to click into the Hangouts app and then choose a contact, instead being able to choose a contact immediately.

For a compare and contrast example, we’re going to use a sample app that just shares a bit of text to a selected contact. Here’s what the share dialog looks like on Lollipop:

And here’s the Marshmallow version with Direct Share enabled:

Now, this is the same app on both versions, so the important takeaway here is that the feature gracefully falls back on older versions of Android to the standard chooser dialog. In this way, the Direct Share options can be added to newer versions, with the sharing functionality working just the same on older versions.

Building a ChooserTargetService

So Direct Share can save the user a bit of time and make sharing content more streamlined. But how do we actually add Direct Share to an existing app?

The first step is to create a service that extends the platform’s ChooserTargetService, which is demonstrated by the following SampleChooserTargetService.java snippet:

public class SampleChooserTargetService extends ChooserTargetService { @Override public List < ChooserTarget > onGetChooserTargets ( ComponentName targetActivityName , IntentFilter matchedFilter ) { final List < ChooserTarget > targets = new ArrayList <>(); for ( int i = 0 ; i < length ; i ++) { final String targetName = ... final Icon targetIcon = ... final float targetRanking = ... final ComponentName targetComponentName = ... final Bundle targetExtras = ... targets . add ( new ChooserTarget ( targetName , targetIcon , targetRanking , targetComponentName , targetExtras )); } return targets ; } }

Override the onGetChooserTargets() method, which will return a List of ChooserTargets that are the Direct Share options that appear in the sharing dialog.

Each ChooserTarget has a few parameters:

The name of the target

The icon to represent the target

The ranking score for this target (between 0.0f and 1.0f), which is used if there’s too many direct share items, then items with low ranking scores will be omitted.

The name of the component to start if the target is chosen

A Bundle of Extras that will be merged into the original Intent before launching the next component with that intent

The order of the targets in the chooser dialog is the same as the ordering of the list of targets that we provide. Any sorting of the targets should be done here, during list construction.

How you create those targets is entirely up to you, though typically the ChooserTarget information is constructed from the model layer of your specific app.

While we have built our ChooserTargetService, we now need to hook it up in our app, so that the system knows about the service and can use it.

First, you’ll need to declare your custom ChooserTargetService in your AndroidManifest.xml , like so:

<service android:name= ".SampleChooserTargetService" android:label= "@string/app_name" android:permission= "android.permission.BIND_CHOOSER_TARGET_SERVICE" > <intent-filter> <action android:name= "android.service.chooser.ChooserTargetService" /> </intent-filter> </service>

This accomplishes two things:

Binds the Service using the android.permission.BIND_CHOOSER_TARGET_SERVICE permission

permission Includes an IntentFilter with the android.service.chooser.ChooserTargetService action

Next, you’ll need to update your AndroidManifest.xml with some meta-data tags:

<activity android:name= ".SendMessageActivity" android:label= "@string/app_name" > <intent-filter> <action android:name= "android.intent.action.SEND" /> <category android:name= "android.intent.category.DEFAULT" /> <data android:mimeType= "text/plain" /> </intent-filter> <meta-data android:name= "android.service.chooser.chooser_target_service" android:value= ".SampleChooserTargetService" /> </activity>

For each activity that you want to expose to ChooserTargetService, add a meta-data element to it. Specify the name as android.service.chooser.chooser_target_service , and point the value to the Service defined earlier. When an implicit intent is sent out that matches with one of these activities, then the intent chooser dialog will show both the normal app icon for that activity and also the list of ChooserTarget icons. The normal app icon just opens the activity like a standard share intent would, while the ChooserTarget icons will open the activity with some initial data on the intent (specified in the ChooserTargetService).

Direct Share Flow

Let’s take a quick look at the flow between screens from a user’s perspective of Google’s Direct Share sample app. The user is starting on a normal-looking app screen, with a nice big share button that sends out an implicit intent.

Next, the user hits the share button, causing the share dialog to pop up.

When the Activity that we attached our Chooser Service to via metadata is able to respond to an implicit intent, that’s when the Chooser Service will generate its list of choices using the onGetChooserTargets() from our custom ChooserTargetService. The list of Chooser Targets will then be used to populate the dialog asking how you want to answer the intent.

In addition, the actual Activity that the meta-data was attached to will be listed alongside the generated Chooser Targets, allowing a user to just pick the Activity normally and opt away from using Direct Share. Normally, this Activity would be some kind of list of contacts or list of users to pick from.

If the user taps on one of the Chooser Targets, then the ‘choose a contact from a list’ step that is normally part of the flow can be skipped, and the user goes right to sending the content, wherever that may lead.

Avoid Clutter

We must always remember to be a good citizen—while Direct Share is neat feature, you shouldn’t use it in a way that clutters up the chooser dialog with unnecessary options. Otherwise, you might drown out the sharing options your users actually want.

In the above example, the app lists eight different users as Chooser Targets, but perhaps only the most frequently messaged contacts should be shown instead.

Learning More

Direct Share is an excellent way to streamline the user experience of sharing content, allowing users to share more easily to their most common targets.

If you found this blog post interesting and would like to learn more about the exciting features of Android Marshmallow or the various new community tools, then check out our new pair of one-day classes on the Android Platform and Community Tools. As a bonus, we’ll be taking these classes on the road, visiting cities around the continental United States. See you there!