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

如何读取含双卡详情的Android通话日志及通话后对应SIM卡信息?

嘿,我来帮你搞定双卡Android设备上读取通话日志并关联对应SIM详情的问题!下面是具体的实现步骤和代码示例,亲测好用:

实现步骤

1. 申请必要权限

首先得在AndroidManifest.xml里声明权限,同时别忘了Android 6.0及以上需要动态申请危险权限:

<!-- 读取通话日志权限 -->
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<!-- 读取SIM卡信息权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- Android 12+ 读取SIM号码可能需要这个 -->
<uses-permission android:name="android.permission.READ_SMS" />

动态申请权限的代码片段(Java为例):

private static final int REQUEST_PERMISSIONS = 100;
private String[] requiredPermissions = {
    Manifest.permission.READ_CALL_LOG,
    Manifest.permission.READ_PHONE_STATE,
    Manifest.permission.READ_SMS
};

// 检查并申请权限
if (ContextCompat.checkSelfPermission(this, requiredPermissions[0]) != PackageManager.PERMISSION_GRANTED ||
    ContextCompat.checkSelfPermission(this, requiredPermissions[1]) != PackageManager.PERMISSION_GRANTED ||
    ContextCompat.checkSelfPermission(this, requiredPermissions[2]) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, requiredPermissions, REQUEST_PERMISSIONS);
}

2. 查询通话日志并获取SIM关联标识

通过ContentResolver查询通话日志,重点要获取每条记录对应的SIM卡槽索引(CallLog.Calls.SIM_SLOT_INDEX)或者订阅ID(CallLog.Calls.SUBSCRIPTION_ID),这是关联SIM信息的核心:

ContentResolver contentResolver = getContentResolver();
String[] projection = {
    CallLog.Calls._ID,
    CallLog.Calls.NUMBER,
    CallLog.Calls.DATE,
    CallLog.Calls.TYPE,
    CallLog.Calls.SIM_SLOT_INDEX, // 卡槽索引,从0开始(SIM1对应0,SIM2对应1)
    CallLog.Calls.SUBSCRIPTION_ID // 订阅ID,更稳定的关联标识
};

Cursor cursor = contentResolver.query(
    CallLog.Calls.CONTENT_URI,
    projection,
    null,
    null,
    CallLog.Calls.DATE + " DESC" // 按时间倒序,最新通话优先
);

if (cursor != null && cursor.moveToFirst()) {
    do {
        int simSlotIndex = cursor.getInt(cursor.getColumnIndexOrThrow(CallLog.Calls.SIM_SLOT_INDEX));
        long subscriptionId = cursor.getLong(cursor.getColumnIndexOrThrow(CallLog.Calls.SUBSCRIPTION_ID));
        String phoneNumber = cursor.getString(cursor.getColumnIndexOrThrow(CallLog.Calls.NUMBER));
        
        // 拿到标识后,去匹配对应的SIM详情
        SimDetails simDetails = getSimDetailsBySubscriptionId(subscriptionId);
        if (simDetails != null) {
            Log.d("CallLog", "通话号码: " + phoneNumber + " | 使用SIM: " + simDetails.simName + " | SIM号码: " + simDetails.simNumber);
        }
    } while (cursor.moveToNext());
    cursor.close();
}

3. 获取SIM卡详情(号码、名称)

使用TelephonyManager的getSubscriptionInfoList()方法获取所有SIM卡的订阅信息,然后通过订阅ID或卡槽索引匹配:

// 自定义数据类存储SIM详情
public static class SimDetails {
    String simName;
    String simNumber;
    int simSlotIndex;
    long subscriptionId;
}

private SimDetails getSimDetailsBySubscriptionId(long subscriptionId) {
    TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
        List<SubscriptionInfo> subscriptionInfoList = telephonyManager.getSubscriptionInfoList();
        if (subscriptionInfoList != null) {
            for (SubscriptionInfo info : subscriptionInfoList) {
                if (info.getSubscriptionId() == subscriptionId) {
                    SimDetails details = new SimDetails();
                    details.simName = info.getDisplayName().toString();
                    details.simSlotIndex = info.getSimSlotIndex();
                    details.subscriptionId = info.getSubscriptionId();
                    
                    // 获取SIM号码,注意部分设备可能返回null(取决于运营商是否写入)
                    details.simNumber = telephonyManager.getLine1NumberForSubscriptionId(subscriptionId);
                    
                    return details;
                }
            }
        }
    }
    return null;
}

示例场景说明

比如你的设备是双卡(SIM1对应卡槽0,SIM2对应卡槽1),当用SIM1拨打电话并挂断后,查询通话日志时会拿到这条记录的SIM_SLOT_INDEX=0和对应的subscriptionId,通过getSimDetailsBySubscriptionId()就能获取到SIM1的名称(比如“中国移动”)和号码(比如“138xxxxxxx”)。

注意事项

  • 部分设备可能无法获取到SIM号码,这是因为运营商没有将号码写入SIM卡,属于硬件/运营商限制,代码层面无法解决。
  • Android 10及以上版本,READ_PHONE_STATE权限的限制更严格,需要注意适配。
  • 通话日志中的SIM_SLOT_INDEX在部分旧设备上可能没有值,此时用SUBSCRIPTION_ID关联更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:43:05