You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

问题原因分析

  1. 小米系统对setPackage的特殊处理:给WhatsApp/Viber的Intent设置setPackage后,小米系统可能直接匹配该应用而非加入选择器列表,跳过选择器逻辑。
  2. 选择器创建方式兼容性问题:使用Intent.createChooser结合EXTRA_INITIAL_INTENTS的方式,在小米系统上可能无法正确识别所有可选Intent,导致仅第一个匹配应用被启动。
  3. 短信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>

关键修复点

  1. 短信Intent优化:使用ACTION_SENDTO替代ACTION_SEND,符合短信发送的标准Intent定义,避免类型冲突。
  2. 应用Intent构建逻辑:先通过通用ACTION_SEND查询可处理应用,再针对性设置包名,确保小米系统将其识别为可选应用。
  3. 选择器强制弹出:添加FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标志,绕过用户默认应用设置,强制弹出选择器。
  4. Manifest权限补全:添加WhatsApp的包名查询权限,确保高版本系统能正常检测应用安装状态。

内容的提问来源于stack exchange,提问作者Brle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 02:20:57