You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何通过SMS listener判定双卡手机短信的接收SIM卡?开发求助

解决方案:区分双卡手机接收短信的SIM卡

Hey there! I’ve tackled this exact issue while building a dual-SMS management app, so let’s break down the practical solutions based on your target Android version—since the approach varies a lot between older and newer OS releases.

Android 11+(API 30及以上):官方API支持

Starting with Android 11, Google finally added official support to identify which SIM received a text. Here’s how to implement it smoothly:

  1. Register your SMS Broadcast Receiver (or use a foreground service with SMS_RECEIVED_ACTION if targeting Android 12+—background receivers are restricted now).
  2. Extract the Subscription ID directly from the broadcast intent. The system passes this via Telephony.Sms.Intents.EXTRA_SUBSCRIPTION_ID.
  3. Map Subscription ID to SIM Slot Index using TelephonyManager.getSimSlotIndexFromSubscriptionId().

Here’s a Kotlin code snippet to put this into action:

class DualSmsReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        if (intent?.action == Telephony.Sms.Intents.SMS_RECEIVED_ACTION) {
            val subscriptionId = intent.getIntExtra(Telephony.Sms.Intents.EXTRA_SUBSCRIPTION_ID, -1)
            if (subscriptionId != -1) {
                val telephonyManager = context?.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
                val simSlotIndex = telephonyManager.getSimSlotIndexFromSubscriptionId(subscriptionId)
                // simSlotIndex will typically be 0 or 1 for dual-SIM devices
                Log.d("DualSmsReceiver", "SMS received on SIM slot: $simSlotIndex")
            }
        }
    }
}

Android 10及以下:兼容方案

Before Android 11, there’s no official API, but two reliable workarounds get the job done:

Option 1: Query the SMS Content Provider

When a SMS arrives, you can query the content://sms/inbox URI and check the hidden but widely supported subscription_id column:

fun getSmsSubscriptionId(context: Context, latestSmsId: Long): Int? {
    val cursor = context.contentResolver.query(
        Uri.parse("content://sms/inbox"),
        arrayOf("subscription_id"),
        "_id = ?",
        arrayOf(latestSmsId.toString()),
        null
    )
    cursor?.use {
        if (it.moveToFirst()) {
            return it.getInt(it.getColumnIndexOrThrow("subscription_id"))
        }
    }
    return null
}

Note: You’ll need to listen for the SMS broadcast, then fetch the ID of the most recent incoming SMS to pass into this method.

Option 2: Reflect Hidden TelephonyManager Methods

Many devices expose hidden methods like getSimSlotId(int subscriptionId) that let you map subscription IDs to slot indices. Here’s a quick Java example:

private int getSimSlotFromSubscriptionId(Context context, int subscriptionId) {
    TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    try {
        Method method = tm.getClass().getMethod("getSimSlotId", int.class);
        return (int) method.invoke(tm, subscriptionId);
    } catch (Exception e) {
        e.printStackTrace();
        return -1; // Fallback if reflection fails
    }
}

⚠️ Heads up: Reflection can break across different device manufacturers or Android versions, so always add fallback logic for edge cases.

关键注意事项

  • Permissions: You’ll need READ_SMS and RECEIVE_SMS permissions. For Android 13+, add POST_NOTIFICATIONS if you plan to show alerts for incoming SMS.
  • Background Restrictions: On Android 12+, broadcast receivers can’t catch SMS_RECEIVED_ACTION while in the background. Switch to a foreground service or use SmsManager callbacks instead.
  • Device Compatibility: Test across multiple dual-SIM devices (especially Samsung, Xiaomi, Huawei) since some manufacturers tweak telephony APIs under the hood.

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

火山引擎 最新活动