从这个SOanswer,我可以通过setPackage将Intent设置为特定的应用程序。 对于我的场景,我需要将文本分享到 WhatsApp、Instagram 或 Line。是否可以设置多个包的bundle ID?
这是不可能的。你能做的就是拨打
setPackage(String)
索取其中一份,发送出去,然后冲洗并重复。
您可能想使用 PackageManager 来查看应用程序是否已安装,但从安全角度来看 setPackage 并不安全,因为任何应用程序都可以使用 WhatsApp、Instagram 等尚未安装的软件包。假设意图是广播,也许您应该考虑使用隐式意图,因为其他应用程序可能会感兴趣?
将对外部应用程序的查询添加到您的清单中,否则从 Android 11 开始,queryIntentActivities 将仅返回系统应用程序和您的应用程序
<manifest>
.....
<queries>
<package android:name="com.whatsapp" />
</queries>
.....
</manifest>
创建并实现您的意图
fun getIntent(uri: Uri): Intent = Intent()
.setAction(Intent.ACTION_VIEW)
.setData(uri)
使用Intent.setPackage和Intent.EXTRA_INITIAL_INTENTS
fun launchIntentForSpecificApps(activity: Activity, uri: Uri, apps: List<String>){
val intent = getIntent(uri)
val supportedIntents = getSupportedPackages(activity, intent)
.filter { apps.contains(it) }
.map { getIntent(uri).setPackage(it) }
val launchIntent: Intent? = when(supportedIntents.size) {
0 -> null
1 -> supportedIntents.first()
else -> Intent.createChooser(supportedIntents[0], "Choose application").run {
putExtra(
Intent.EXTRA_INITIAL_INTENTS,
supportedIntents.subList(1, supportedIntents.size).toTypedArray()
)
}
}
launchIntent
?.let { activity.startActivity(it) }
?: Unit //TODO Do something
}
fun getSupportedPackages(context: Context, intent: Intent): List<String> {
val supportedPackages = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
context.packageManager.queryIntentActivities(intent, PackageManager.ResolveInfoFlags.of(0L))
} else {
context.packageManager.queryIntentActivities(intent, 0)
}
return supportedPackages
.map { it.activityInfo.packageName }
.distinct()
}