Android选择WhatsApp/Viber/短信APP发文本:小米设备自动启动WhatsApp问题
解决小米设备上WhatsApp自动启动、不弹出应用选择器的问题
问题说明
实现了一套支持选择WhatsApp、Viber及默认短信APP发送文本的Android方案,三星设备运行正常,但小米设备上会直接启动WhatsApp,无法让用户自主选择发送应用;联系人选择后文本框填充正常,仅小米设备的选择器问题未解决。
原代码与配置
核心逻辑代码
try { if (isAppInstalled(context, "com.whatsapp") && isAppInstalled(context,"com.viber.voip")) { // Create intents for sending SMS, WhatsApp, and Viber val smsIntent = Intent(Intent.ACTION_SEND) .setType("vnd.android-dir/mms-sms") .setData(Uri.parse("smsto:")) .putExtra("sms_body", text) val whatsappIntent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_TEXT, text) type = "text/plain" setPackage("com.whatsapp") } val viberIntent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_TEXT, text) type = "text/plain" setPackage("com.viber.voip") } // Create a list of Intent objects val intentList = listOf(smsIntent,whatsappIntent, viberIntent) // Check if there are any apps that can handle the given intents val filteredIntentList = intentList.filter { intent -> try { packageManager.queryIntentActivities( intent, PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_DEFAULT_ONLY.toLong()) ).isNotEmpty() } catch (e: Exception) { // Handle exceptions that may occur during querying activities false } }.distinctBy { it.`package`} if (filteredIntentList.isNotEmpty()) { // Create a chooser intent val chooserIntent = Intent.createChooser(filteredIntentList.first(), "Choose a messaging app") chooserIntent.putExtra( Intent.EXTRA_INITIAL_INTENTS, filteredIntentList.subList(1, filteredIntentList.size).toTypedArray() ) // Start the activity context.startActivity(chooserIntent) } else { // Handle the case when no apps can handle the given intents } } } catch (e: Exception) { e.printStackTrace() // Handle any exceptions that may occur during the process }
Manifest配置
<queries> <intent> <action android:name="android.intent.action.SEND" /> <data android:mimeType="text/plain" /> </intent> <!-- <package android:name="com.whatsapp" /> --> <package android:name="com.viber.voip" /> <package android:name="com.android.mms" /> </queries>
问题原因分析
- 小米系统对
setPackage的特殊处理:给WhatsApp/Viber的Intent设置setPackage后,小米系统可能直接匹配该应用而非加入选择器列表,跳过选择器逻辑。 - 选择器创建方式兼容性问题:使用
Intent.createChooser结合EXTRA_INITIAL_INTENTS的方式,在小米系统上可能无法正确识别所有可选Intent,导致仅第一个匹配应用被启动。 - 短信Intent选型不当:使用
ACTION_SEND搭配vnd.android-dir/mms-sms类型,不如ACTION_SENDTO贴合短信发送场景,可能干扰选择器正常识别。
修复方案
修改核心代码
try { val intentList = mutableListOf<Intent>() // 短信Intent:改用ACTION_SENDTO更精准 val smsIntent = Intent(Intent.ACTION_SENDTO) .setData(Uri.parse("smsto:")) .putExtra("sms_body", text) if (packageManager.queryIntentActivities(smsIntent, PackageManager.ResolveInfoFlags.of(0)).isNotEmpty()) { intentList.add(smsIntent) } // WhatsApp Intent:先查通用ACTION_SEND再过滤包名,避免系统直接跳转 val whatsappBaseIntent = Intent(Intent.ACTION_SEND) .setType("text/plain") .putExtra(Intent.EXTRA_TEXT, text) val whatsappResolves = packageManager.queryIntentActivities(whatsappBaseIntent, PackageManager.ResolveInfoFlags.of(0)) for (resolve in whatsappResolves) { if (resolve.activityInfo.packageName == "com.whatsapp") { val whatsappIntent = Intent(whatsappBaseIntent).apply { setPackage(resolve.activityInfo.packageName) } intentList.add(whatsappIntent) break } } // Viber Intent:同WhatsApp处理逻辑 val viberBaseIntent = Intent(Intent.ACTION_SEND) .setType("text/plain") .putExtra(Intent.EXTRA_TEXT, text) val viberResolves = packageManager.queryIntentActivities(viberBaseIntent, PackageManager.ResolveInfoFlags.of(0)) for (resolve in viberResolves) { if (resolve.activityInfo.packageName == "com.viber.voip") { val viberIntent = Intent(viberBaseIntent).apply { setPackage(resolve.activityInfo.packageName) } intentList.add(viberIntent) break } } if (intentList.isNotEmpty()) { // 构建选择器,强制弹出选择界面 val firstIntent = intentList.removeAt(0) val chooserIntent = Intent.createChooser(firstIntent, "Choose a messaging app") chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toTypedArray()) // 强制绕过默认应用设置,弹出选择器 chooserIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED context.startActivity(chooserIntent) } else { // 无可用应用的处理逻辑 } } catch (e: Exception) { e.printStackTrace() // 异常处理逻辑 }
调整Manifest配置
取消WhatsApp的包名注释,确保Android 11+能正常查询应用:
<queries> <intent> <action android:name="android.intent.action.SEND" /> <data android:mimeType="text/plain" /> </intent> <package android:name="com.whatsapp" /> <package android:name="com.viber.voip" /> <package android:name="com.android.mms" /> </queries>
关键修复点
- 短信Intent优化:使用
ACTION_SENDTO替代ACTION_SEND,符合短信发送的标准Intent定义,避免类型冲突。 - 应用Intent构建逻辑:先通过通用
ACTION_SEND查询可处理应用,再针对性设置包名,确保小米系统将其识别为可选应用。 - 选择器强制弹出:添加
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标志,绕过用户默认应用设置,强制弹出选择器。 - Manifest权限补全:添加WhatsApp的包名查询权限,确保高版本系统能正常检测应用安装状态。
内容的提问来源于stack exchange,提问作者Brle
相关产品推荐
相关产品推荐

