[Android Development] Sharing text with different content for different apps using createChooser

Introduce problem

Thế Dũng
2 min readOct 26, 2022

When you need to share a link or some text from your app to other apps, Android provides a very convenient and friendly way to do:

val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
type
= "text/plain"
putExtra(Intent.EXTRA_TEXT, generateShareContent())
}
val chooser = Intent.createChooser(sendIntent, getString(R.string.share))
context?.startActivity(chooser)

After start this chooser intent, Android will then display a sharing window with list of apps for user to choose. But from now on you can not change the content for sharing action (Because you need to put it before the sharing window is display in putExtra action).

Resolved Idea

To solve this problem, I have a method for you. And here is how the main idea is:

  • Create a sharing intent which will return a list of intent activity when we use PackageManager to query.
  • Content for sharing. It is based on your need. I have the example bellow with 3 different contents for 3 different types of app.
  • Mapping content with app

Keywords and Code

Before we are going into the code, here is some keywords for you to research:

  • <queries> tag
  • queryIntentActivities
  • Intent.EXTRA_REPLACEMENT_EXTRAS

Above code block is how I choose to resolve this problem.

More detail

First of all, to allow us to use queryIntentActivities, Android 11 and higher require us to define a <queries> tag in manifest

<queries>
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="text/plain"/>
</intent>
</queries>


<application
...
</application>

You can read more about this tag on this Android Developer Document

When you queries a specific type of app (like above: android.intent.action.SEND), you don’t need to add the permission QUERY_ALL_PACKAGES. But if you were required to query all app in a device, then you need to add this permission. See this

val emailIntent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"))

I create this intent for filtering apps that can be used for sending email. For example: Your device have 3 apps can send email: Gmail / Outlook / Yahoo. Then you need to map the email content for these 3 apps. I added 3 app-packagename to an array name arrayEmailPackage.

val replacementExtra: MutableList<Pair<String, Bundle>> = ArrayList()

This is a list with pair element inside.

Pair element contain 2 things:

  • key: String — Package name of an app
  • value: Bundle — contain putExtra key and value. Here we need to change the putExtra(Intent.EXTRA_TEXT, “Share content”).

Now you can run a for loop to pick which content for which app. Then it into replacementExtra array.

After you’ve done that, create the chooser intent

val chooser = Intent.createChooser(sendIntent, getString(R.string.share))

Using the EXTRA_REPLACEMENT_EXTRAS to make the modify of content for each selected app:

chooser.putExtra(                    Intent.EXTRA_REPLACEMENT_EXTRAS,                    bundleOf(*replacementExtra.toTypedArray())                )                context?.startActivity(chooser)

Now you can map content to app when sharing.

Thanks for reading!

--

--

Thế Dũng
Thế Dũng

Written by Thế Dũng

Software engineer - Mobile developer

No responses yet