Android A12设备指定SIM卡自动拨号代码适配咨询
Android 12 下指定SIM卡拨号修复方案
你的问题出在Android 12及以上版本对双卡拨号的API做了调整,原来依赖的com.android.phone.extra.slot这类非系统标准的Extra字段已经不再被拨号应用识别了。要实现指定SIM卡拨号,得改用官方的TelecomManager API来完成。
步骤1:添加必要权限
在AndroidManifest.xml里添加权限:
<uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
注意:READ_PHONE_STATE用于获取SIM卡订阅信息,Android 12及以上需要动态申请该权限。
步骤2:修改拨号代码
替换你原来的代码为以下实现:
if (services == "Giros Tigo") { // 获取TelecomManager实例 val telecomManager = getSystemService(Context.TELECOM_SERVICE) as TelecomManager // 构建拨号Uri val dialString = "*555*1*${txtnumber.text}*${txtcedula.text}*1*${txtmonto.text}#" val uri = Uri.parse("tel:${Uri.encode(dialString)}") // 获取指定slot对应的SubscriptionId(这里slot为0) val subscriptionManager = getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager val subscriptionInfoList = subscriptionManager.activeSubscriptionInfoList val targetSubscriptionId = subscriptionInfoList?.firstOrNull { it.slotIndex == 0 }?.subscriptionId // 准备拨号参数 val extras = Bundle().apply { targetSubscriptionId?.let { putInt(TelecomManager.EXTRA_PHONE_ACCOUNT_ID, it) } } // 执行拨号 try { telecomManager.placeCall(uri, extras) } catch (e: SecurityException) { // 处理权限缺失异常 e.printStackTrace() } // 保留原剪贴板逻辑 val cd = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clip = ClipData.newPlainText("AutoCopiado", dialString) cd.setPrimaryClip(clip) }
关键说明
- 不再使用
Intent.ACTION_CALL,转而用TelecomManager.placeCall,这是Android官方推荐的双卡拨号方式。 - 用
SubscriptionManager获取对应slot的subscriptionId,这是系统识别SIM卡的唯一标识,替代原来直接传入的slot index。 - 原代码里的
startActivityForResult和重复的startActivity(intent)属于冗余逻辑,直接用placeCall即可完成拨号动作。
注意事项
- 必须动态申请
CALL_PHONE和READ_PHONE_STATE权限,否则会抛出SecurityException。 - 如果设备只有单SIM卡,
targetSubscriptionId会是null,此时系统会自动使用唯一的SIM卡拨号。
内容的提问来源于stack exchange,提问作者Zolu
相关产品推荐
相关产品推荐

