Direct Share is a feature that allows an application to share content to other applications. Users can then access your app directly when sharing content to another app.
Direct Share works with the concept of Sharing Shortcuts. An app proposes to pre-publish shareable targets, published Sharing Shortcuts will be kept by the system until the app updates them, or the app is uninstalled. When displayed to the user, the system ranks any applicable shortcuts using a prediction service, showing the shortcuts more likely to be used.
Setup and requirements:
In order to use this feature, the minimum complieSDK
is 29. Direct Share uses Sharing Shortcuts so you have to create a file shortcuts.xml
1 2 3 4 5 6 7 | <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <share-target android:targetClass="com.example.android.directshare.SendMessageActivity"> <data android:mimeType="text/plain" /> <category android:name="com.example.android.directshare.category.TEXT_SHARE_TARGET" /> </share-target> </shortcuts> |
The shortcuts.xml
file needs to be declared in an activity whose intent filter is set to action android.intent.action.MAIN
and category android.intent.category.LAUNCHER
in the AndroidManifest.xml
file.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <!-- Reference resource file where the app's shortcuts are defined --> <meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" /> </activity> |
Use the ShortcutManager API
Once the shared target elements are defined, we need to publish the dynamic shortcuts matching those definitions to the ShortcutManager API. Sharing shortcuts remain in the system until they are updated by the same or uninstalled app.
build.gradle
1 2 | implementation "androidx.core:core:${versions.androidxCore}" |
SharingShortcutsManager
is the class in charge of interacting with ShortcutManager. Every time the user opens the app we will push the saved sharing shortcuts.
MainActivity.kt
1 2 3 4 5 6 7 8 9 | override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... sharingShortcutsManager = SharingShortcutsManager().also { it.pushDirectShareTargets(this) } } |
We can configure the same applications with Direct Share
1 2 | <category android:name="com.example.android.directshare.category.TEXT_SHARE_TARGET" /> |
Here I use share text / plain style.
SharingShortcutsManager.kt
1 2 3 4 5 6 7 | private val categoryTextShareTarget = "com.example.android.directshare.category.TEXT_SHARE_TARGET" fun pushDirectShareTargets(context: Context) { ... val contactCategories = setOf(categoryTextShareTarget) ... } |
Create shareable lists.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | data class Contact(val name: String) { companion object { val invalidId = -1 val id = "contact_id" val contacts = arrayOf( Contact("Nam"), Contact("Vuong"), Contact("Ngan") ) fun byId(id: Int) = contacts[id] } } |
The app only publishes four shortcuts due to a limited shortcut. Never add more shortcuts than what is defined in ShortcutManagerCompat.getMaxShortcutCountPerActivity
.
To create the name and icon:
SharingShortcutsManager.kt
1 2 3 4 5 6 7 8 | val staticLauncherShortcutIntent = Intent(Intent.ACTION_DEFAULT) ShortcutInfoCompat.Builder(context, Integer.toString(id)) .setShortLabel(contact.name) .setIcon(IconCompat.createWithResource(context, contact.icon)) .setIntent(staticLauncherShortcutIntent) .build() |
If a shortcut persists, it can be cached by various system services and may appear as a share target even if it has not been unpublished or deleted by the application. .
1 2 3 4 5 | ShortcutInfoCompat.Builder(context, Integer.toString(id)) ... .setLongLived(true) .build() |
Publish sharing
SharingShortcutsManager.kt
1 2 | ShortcutManagerCompat.addDynamicShortcuts(context, shortcuts) |
AndroidManifest.xml
1 2 3 4 5 6 7 8 9 10 11 12 | <activity // Activity sẽ tiến hành share. android:name=".SendMessageActivity" android:label="@string/app_name" android:theme="@style/DirectShareDialogTheme"> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> </activity> |
SendMessageActivity.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | private fun handleIntent(intent: Intent): Boolean { if (Intent.ACTION_SEND == intent.action && "text/plain" == intent.type) { textToShare = intent.getStringExtra(Intent.EXTRA_TEXT) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && intent.hasExtra(Intent.EXTRA_SHORTCUT_ID)) { val shortcutId = intent.getStringExtra(Intent.EXTRA_SHORTCUT_ID) contactId = Integer.valueOf(shortcutId!!) } else { contactId = Contact.invalidId } return true } return false } |
And the end result.
Thank you for watching
Code lab: https://developer.android.com/codelabs/android-direct-share#0