New ShareSheet in Android Q
Android Q is launching with some awesome features, It also launched Sharing Shortcuts. In Android Q, Direct Share API is replaced with the Sharing Shortcut API.
Direct Share API:
With Android M, Android provided this feature in which we can define direct user targets. This targets were shared with user by via Share Menu. This feature allows users to share content to targets, such as contacts, within other apps.
In Q, Direct Share API will still keep on working, but with Low Priority then Sharing Shortcuts.
Differences between Direct Share API and Sharing Shortcut API
- Sharing Shortcut API is faster compared to others, it provides the list of targets before hand only.
- In Direct Share API, we required to write a bit of code for ChooserTarget Service but in Sharing Shortcut it is handled by the API itself.
- The new API uses a push model, versus the pull model used in the old DirectShare API. This makes the process of retrieving direct share targets much faster when preparing the ShareSheet. From a developer’s point of view, when using the new API, the app needs to provide the list of direct share targets ahead of time, and potentially update the list of shortcuts every time the internal state of the app changes.
Implementing sharing shortcuts
For this, we need to provide a list of share targets that will be used at runtime. The way in which this is implemented is very similar to the shortcuts API that we’ve been using in our applications which allows users to easily access features of our app. And similar to how we declare static app shortcuts, defining these share shortcuts begins by declaring a share target within our res/xml directory. Here, we declare a shortcuts element with nested share-target — this target is used to define:
- Target class: Used to declare the activity to be launched when the share activity is invoked
- Mime type: The data type for which the share-target should be shown.
- Category name: The name of the share category, this will also be used programmatically when configuring the share target. It is possible to define multiple categories when it comes to a share-target.
Step 1: declare share target elements in a xml resource file (res/xml/shortcuts.xml).
<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <share-target android:targetClass="co.joebirch.androidqplayground.ShareActivity"> <data android:mimeType="text/plain" /> <category android:name="co.joebirch.androidqplayground.category.TEXT_SHARE_TARGET" /> </share-target> </shortcuts>
- <data> represents the type of the shared content, it’s similar to the data specification you’re used to seeing in <intent-filter>s.
- <category> is used to match the app’s published shortcuts with its share target definition. Its value can be arbitrary and is up to you to define. Note that a single <share-target> element can contain multiple categories.
- <share-target>
defines a shortcut in the app. In the example above, it deep links
into
SendMessageActivity
. which in consequence must be able to respond to incoming intents with an actionSEND
and a content typetext/plain
. Its declaration inside your app’s manifest should look something like this.
<activity android:name=".SendMessageActivity"> <!-- This activity can respond to intents with an action SEND and a content type text/plain --> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> </intent-filter> <!-- Needed if you import the sharetarget androidx library. It allows for this activity to be taken into account as a chooser target provider --> <meta-data android:name="android.service.chooser.chooser_target_service" android:value="androidx.sharetarget.ChooserTargetServiceCompat"/> </activity>
Step 2:Add a <meta-data> element in your manifest.xml. And it should be inside the launcher activity.
<activity android:name=".MainActivity"> ... <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts"/> </activity>
Step 3: For publish and manage the sharing shortcuts, we can do this inside our launcher activity .
Example for creating sharing shortcuts:-
fun addShareShortcuts(context: Context) { val shortcutInfoList = mutableListOf<ShortcutInfoCompat>() shortcutInfoList.add( ShortcutInfoCompat.Builder(context, /* A unique id for this shortcut */) .setShortLabel(/* A short label for the shortcut */) .setPerson(Person.Builder()...build()) .setIcon(/* Icon */) .setCategories(/* One or multiple categories defined in res/xml/shortcuts.xml */) .setIntent(Intent(Intent.ACTION_DEFAULT)) .build()) ShortcutManagerCompat.addDynamicShortcuts(context, shortcutInfoList) }
Few changes as of Android Q:
- setCategories: Whilst this function of the builder was already previously available, this is now required to be set if you are using share shortcuts. This is so that the system can filter out actions against share intents.
- setLongLived: When a shortcut is set to be long lived, it means that system services can still access it from the cache even after it has been removed as a dynamic shortcut.
- setPerson: This can be used to set the Person instance that is associated with this shortcut. Whilst this is not a required property when it comes to share shortcuts, it helps the system to provide appropriate suggestions within the share sheet. Note: There is also a setPersons builder function that can be used to add multiple Person instances.
It’s important to note that these share targets may still need to be updated within your app, as in it might not be a case of adding them a single time. For example, you may be working with a messaging app where the user has added a new friend to talk to or even want to change the share shortcuts based on who the user regularly shares content with.