我正在开发一个项目,将Android手机中收到的短信同步到在线数据库。我可以通过调用getOriginatingAddress()
方法获取发件人的号码。但我找不到任何解决方案来确定我的设备中的哪个SIM卡收到短信。
我在网上搜索了它,但找不到解决这个问题的方法。有没有办法获得短信接收者的电话号码?
答案 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";
}
}