【发布时间】:2020-01-10 18:16:16
【问题描述】:
背景
在 Android Q 之前,始终可以设置要在共享对话框中显示的项目以及显示顺序。我什至写过here。
例如,如果您希望某些应用优先于其他应用,您可以使用:
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
}
用法:
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)
这应该将“Total Commander”和“Gmail”作为顶部项目。示例项目可以在here找到。
如果您添加“com.whatsapp”,您可以将 WhatsApp 作为第三个。
问题
似乎 EXTRA_INITIAL_INTENTS 在 Q 上受到了很大限制,让我最多只能放 2 个项目。这意味着您不会像以前的版本那样看到所有项目,而只会看到我提到的 2 个应用程序。
我尝试过的
我查看了文档(例如here),并检查了一些候选人:
- EXTRA_EXCLUDE_COMPONENTS - 用于排除东西。没试过,但这不是我需要的。我想指定要显示的内容和顺序。
- EXTRA_INTENT - 出于某种原因,当我尝试使用它时,它只是直接打开它,而不显示共享对话框。
- EXTRA_ALTERNATE_INTENTS - 似乎什么也没做
- EXTRA_CHOOSER_TARGETS - 好像和直接分享的物品有关,不过还是有限制的。
查看文档和 Android 的源代码 (here),我可以看到,通过写它是有限的,它非常非常有限:最多只能放 2 个项目:
private static final int MAX_EXTRA_INITIAL_INTENTS = 2;
private static final int MAX_EXTRA_CHOOSER_TARGETS = 2;
我可能错了,但我认为 EXTRA_ALTERNATE_INTENTS 并不受此限制。只是我没有使用它。
当我发现这些问题后,我尝试在问题跟踪器上报告,但没有得到任何回复。
问题
在原生共享 UI 上,有没有办法设置显示哪些项目,每个项目都有自己的 Intent,以及按什么顺序显示?
如何使用 EXTRA_ALTERNATE_INTENTS ?它应该与 EXTRA_INTENT 一起使用吗?为什么我尝试使用EXTRA_INTENT时,它只是打开了它?这些额外的东西有什么用?这不是我真正要问的吗?
看到有EXTRA_CHOOSER_TARGETS,是不是说明我可以自己拿到直销项目了?也许可以创建一个完全自定义的共享 UI,看起来与原始 UI 非常相似,甚至还有直接共享项目?
【问题讨论】:
-
Relevant thread on the issue tracker,可能是同一作者。 ;)
-
@gmk57 是的,确实如此。你是怎么知道的?
-
好吧,我不是 100% 确定,但 the answer 建议,也许 some crosslinks 猜测。 ;)
-
@gmk57 聪明!
-
@Zippy 唯一的方法是拥有自己的用户体验。遗憾的是,我找不到一个不错的库。
标签: android android-intent android-10.0