Before Android Q, it was always possible to set which items to show on the sharing dialog, and in which order. I even wrote about it here.
For example, if you wanted to prioritize some apps over others, you could use:
fun getChooserIntent(context: Context, intent: Intent, chooserTitle: String?, vararg preferredOrderOfApps: String): Intent? {
val resolveInfos = context.packageManager.queryIntentActivities(intent, 0)
if (resolveInfos.isNullOrEmpty())
return null
val packageNameToOrderMap = HashMap<String, Int>()
for ((index, packageName) in preferredOrderOfApps.withIndex())
packageNameToOrderMap[packageName] = preferredOrderOfApps.size - index
val targetIntents = ArrayList<Intent>()
for (resolveInfo in resolveInfos) {
val activityInfo = resolveInfo.activityInfo
val targetIntent = intent.clone() as Intent
targetIntent.setPackage(activityInfo.packageName)
targetIntent.component = ComponentName(activityInfo.packageName, activityInfo.name)
targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
val labeledIntent = LabeledIntent(targetIntent, activityInfo.packageName, resolveInfo.labelRes, resolveInfo.icon)
targetIntents.add(labeledIntent)
}
targetIntents.sortWith(Comparator<Intent> { lhs, rhs ->
val lhsPackageName = lhs.`package`!!
val lhsPriority = packageNameToOrderMap[lhsPackageName] ?: -1
val rhsPackageName = rhs.`package`!!
val rhsPriority = packageNameToOrderMap[rhsPackageName] ?: -1
return@Comparator when {
lhsPriority > rhsPriority -> -1
lhsPriority < rhsPriority -> 1
else -> 0
}
})
val chooserIntent = Intent.createChooser(
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> Intent()
else -> targetIntents.removeAt(0)
}, chooserTitle)
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toTypedArray<Parcelable>())
return chooserIntent
}
Usage:
val intent = getShareFileIntent(this@MainActivity, file.absolutePath)
val chooserIntent = getChooserIntent(this@MainActivity, intent, "look at the results...", "com.ghisler.android.TotalCommander", "com.google.android.gm")
startActivity(chooserIntent)
This should put "Total Commander" and "Gmail" as the top items. Sample project can be found here.
If you add "com.whatsapp", you could have WhatsApp as the third one.
It seems EXTRA_INITIAL_INTENTS got very restricted on Q, letting me put only up to 2 items. This means that instead of seeing all items as on previous versions, you would see only the 2 apps I've mentioned.
I've looked at the docs (here for example) , and I've checked some candidates:
Looking at the docs, and on Android's source code for it (here), I can see that by writing that it's limited, it's very very limited: Just up to 2 items that I can put:
private static final int MAX_EXTRA_INITIAL_INTENTS = 2;
private static final int MAX_EXTRA_CHOOSER_TARGETS = 2;
I might be wrong, but I think EXTRA_ALTERNATE_INTENTS isn't limited as such. It's just that I've failed to use it.
When I've found about these problems, I tried to report it on the issue tracker, but I didn't get any response.
On the native share UI, Is there any way to set which items to show, each with its own Intent, and in which order?
How do you use EXTRA_ALTERNATE_INTENTS ? Should it be used with EXTRA_INTENT ? How come when I tried to use EXTRA_INTENT, it just opened it? What's the use of these extras? Isn't it what I actually ask about?
Seeing that there is EXTRA_CHOOSER_TARGETS, does it mean I can get the direct-share items myself? Maybe it's possible to create a completely customized sharing UI, which looks very similar to the original one, and even has direct-share items?
You have to run lab3a_MyBrowser before you run lab3a_IntentsLab , so that the browser gets installed on your phone. Then it will be visible to your chooser.
Most commonly, ACTION_SEND action sends URL of build-in Browser app. While sharing the data, Intent call createChooser() method which takes Intent object and specify the title of the chooser dialog. Intent. createChooser() method allows to display the chooser.
putExtra method is used.
For all types of sharing, create an intent and set its action to Intent. ACTION_SEND . In order to display the Android Sharesheet you need to call Intent. createChooser() , passing it your Intent object.
Let me see if I can answer some of your questions.
On the native share UI, Is there any way to set which items to show, each with its own Intent, and in which order?
You can use what you're using now, but, as you discovered, it's only possible to provide 2 intents to specifically promote to the top. That said, the change to get the system to populate the rest of the list in alpha order is small:
val chooserIntent = Intent.createChooser(
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> intent
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> Intent()
else -> targetIntents.removeAt(0)
}, chooserTitle
)
This actually looks like what you were doing according to the bug report.
Unfortunately, it's not possible to change the title from "Share" when using Intent.ACTION_SEND
or Intent.ACTION_SEND_MULTIPLE
.
Seeing that there is EXTRA_CHOOSER_TARGETS, does it mean I can get the direct-share items myself?
No. It's provided so that your app can surface its own direct share targets that are appropriate for the action being taken. (source)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With