Background
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.
The problem
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.
What I've tried
I've looked at the docs (here for example) , and I've checked some candidates:
- EXTRA_EXCLUDE_COMPONENTS - used to exclude stuff. Didn't try, but it's not what I need anyway. I want to specify what to show and in which order.
- EXTRA_INTENT - for some reason when I try to use it, it just opens it directly, without showing the sharing dialog.
- EXTRA_ALTERNATE_INTENTS - Doesn't seem to do anything
- EXTRA_CHOOSER_TARGETS - seems to be related to the direct share items, but even then it's restricted.
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.
The 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?
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?
See Question&Answers more detail:
os