如何确定哪个SIM卡在双卡Android设备中收到短信

时间:2016-03-13 09:45:29

标签: android sms telephonymanager

我正在开发一个项目,将Android手机中收到的短信同步到在线数据库。我可以通过调用getOriginatingAddress()方法获取发件人的号码。但我找不到任何解决方案来确定我的设备中的哪个SIM卡收到短信。

我在网上搜索了它,但找不到解决这个问题的方法。有没有办法获得短信接收者的电话号码?

5 个答案:

答案 0 :(得分:11)

我有一些非常困难的时间来解决这个问题,最后我找到了一个解决方案,尽管我只在api 22级以上进行了测试。

您必须查看收到的意图中的额外信息。在我的情况下,意图的额外Bundle中有两个键是有用的:" slot"和"订阅"。

以下是示例:

public class IncomingSms extends BroadcastReceiver {

          public void onReceive(Context context, Intent intent) {

                // Retrieves a map of extended data from the intent.
                Bundle bundle = intent.getExtras();

                int slot = bundle.getInt("slot", -1);
                int sub = bundle.getInt("subscription", -1);

                /*
                  Handle the sim info
                */
            }
}

我没有找到关于Bundle中的密钥的文档,所以这可能是设备/制造商的依赖,我可以想象密钥是不同的或类似的东西。您可以通过转储捆绑包的密钥集来验证这一点:

Set<string> keyset = bundle.keySet();

修改

有关SIM卡电话号码的信息可能根本无法使用,因为如果SIM卡未存储在SIM卡上,则可能无法查询,但所有其他信息都可通过SubscriptionManager获取:

SubscriptionManager manager = SubscriptionManager.from(appContext);
SubscriptionInfo = manager.getActiveSubscriptionInfo(sub);

SubscriptionInfo = manager.getActiveSubscriptionInfoForSimSlotIndex(slot);

SubscriptionInfo中有一些有用的信息,例如电话号码,如上所述,我们无法保证提供这些信息。

我也忘了提到在22级api中增加了对双重SIM卡的支持。

答案 1 :(得分:1)

我使用Levente Püsök的答案稍加改动。但我没有在所有设备上进行测试。

try {
Bundle bundle = intent.getExtras();
int slot = -1;
if (bundle != null) {
Set<String> keySet = bundle.keySet();
for(String key:keySet){
  switch (key){
    case "slot":slot = bundle.getInt("slot", -1);
    break;
    case "simId":slot = bundle.getInt("simId", -1);
    break;
    case "simSlot":slot = bundle.getInt("simSlot", -1);
    break;
    case "slot_id":slot = bundle.getInt("slot_id", -1);
    break;
    case "simnum":slot = bundle.getInt("simnum", -1);
    break;
    case "slotId":slot = bundle.getInt("slotId", -1);
    break;
    case "slotIdx":slot = bundle.getInt("slotIdx", -1);
    break;
    default:
      if(key.toLowerCase().contains("slot")|key.toLowerCase().contains("sim")){
       String value = bundle.getString(key, "-1");
       if(value.equals("0")|value.equals("1")|value.equals("2")){
         slot = bundle.getInt(key, -1);
       }
    }


  }
}

 Log.d("slot", "slot=>"+slot);

 }

}catch (Exception e){
Log.d(TAG, "Exception=>"+e);
 }

答案 2 :(得分:0)

SMS具有thread_id字段,对于参与者集来说可能是唯一的。相同的发送者和两个SIM卡可能有所不同,至少有助于区分。

答案 3 :(得分:0)

这对我来说很好用,试试可能对你有帮助

        if (bundle != null) {
            int slot = -1;
            Set<String> keySet = bundle.keySet();
            for(String key:keySet){
                if(key.equals("phone")){slot = bundle.getInt("phone", -1);}//in api 29
                else if(key.equals("slot")){slot = bundle.getInt("slot", -1);}
                else if(key.equals("slotId")){slot = bundle.getInt("slotId", -1);}
                else if(key.equals("slot_id")){slot = bundle.getInt("slot_id", -1);}
                else if(key.equals("slotIdx")){slot = bundle.getInt("slotIdx", -1);}
                else if(key.equals("simId")){slot = bundle.getInt("simId", -1);}
                else if(key.equals("simSlot")){slot = bundle.getInt("simSlot", -1);}
                else if(key.equals("simnum")){slot = bundle.getInt("simnum", -1);}
            }
            System.out.println("  The sim no is >>>  "+slot);

            //or get subscription and do next


            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
                int sub = bundle.getInt("subscription", -1);
                SubscriptionManager manager = SubscriptionManager.from(context);
                SubscriptionInfo subnfo = manager.getActiveSubscriptionInfo(sub);//this requires READ_PHONE_STATE permission
                System.out.println(
                        "\n The sim no is >>>  "+subnfo.getSimSlotIndex()
                        //or subnfo.getCardId()
                        +"\n The sim no is >>>  "+subnfo.getCardId()//this requires api 29 and +++
                        //some infos may you need it
                        +"\n Phone No is >>>  "+subnfo.getNumber()//not guaranteed to be available
                        +"\n carrier Name is >>>  "+subnfo.getCarrierName()//the operator name
                        +"\n carrier display Name is >>>  "+subnfo.getDisplayName()//that you typed in dual sim settings
                );
            }

        }

答案 4 :(得分:0)

结合答案和更新,我取得了很好的结果

    private String detectSim(Bundle bundle) {
    int slot = -1;
    Set<String> keySet = bundle.keySet();
    for (String key : keySet)
    {
        switch (key) {
            case "phone":
                slot = bundle.getInt("phone", -1);
                break;
            case "slot":
                slot = bundle.getInt("slot", -1);
                break;
            case "simId":
                slot = bundle.getInt("simId", -1);
                break;
            case "simSlot":
                slot = bundle.getInt("simSlot", -1);
                break;
            case "slot_id":
                slot = bundle.getInt("slot_id", -1);
                break;
            case "simnum":
                slot = bundle.getInt("simnum", -1);
                break;
            case "slotId":
                slot = bundle.getInt("slotId", -1);
                break;
            case "slotIdx":
                slot = bundle.getInt("slotIdx", -1);
                break;
            default:
                if (key.toLowerCase().contains("slot") | key.toLowerCase().contains("sim")) {
                    String value = bundle.getString(key, "-1");
                    if (value.equals("0") | value.equals("1") | value.equals("2")) {
                        slot = bundle.getInt(key, -1);
                    }
                }
        }
    }

    Log.d("KKK",String.valueOf(slot));

    if (slot==0)
    {
        return "sim1";
    }
    else if (slot==1)
    {
        return "sim2";
    }
    else
    {
        return "undetected";
    }
}