识别来自 Sim1 和 Sim2 的通话记录

Identify Call logs from Sim1 and Sim2

我正在尝试分别显示 Sim1 和 Sim2 的通话记录。我收到了所有通话记录,但无法区分它是来自 Sim1 还是来自 Sim2。我试过下面的代码,

 val managedCursor = activity?.contentResolver?.query(CallLog.Calls.CONTENT_URI, null, null,
        null, null)
    managedCursor?.let {
      val number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER)
      val name = managedCursor.getColumnIndex(CallLog.Calls.CACHED_NAME)
      val type = managedCursor.getColumnIndex(CallLog.Calls.TYPE)
      val date = managedCursor.getColumnIndex(CallLog.Calls.DATE)
      val duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION)
      val simType = managedCursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID)
      sb.append("Call Details :")
      while (managedCursor.moveToNext()) {
        val phNumber = managedCursor.getString(number)
        val displayName = managedCursor.getString(name)
        val callType = managedCursor.getString(type)
        val callDate = managedCursor.getString(date)
        val callDayTime = Date(callDate.toLong())
        val callDuration = managedCursor.getString(duration)
        var dir: String = "";
        val dircode = Integer.parseInt(callType)
        val simTypes = managedCursor.getString(simType)
        when (dircode) {
          CallLog.Calls.OUTGOING_TYPE -> dir = "OUTGOING"
          CallLog.Calls.INCOMING_TYPE -> dir = "INCOMING"
          CallLog.Calls.MISSED_TYPE -> dir = "MISSED"
        }
      }
      managedCursor.close()
    }

我已阅读显示 PHONE_ACCOUNT_ID 的文档可能有助于识别它。但是它在不同的手机上给出不同的数字。

我也阅读了很多SO问题,但找不到任何解决方案。

赞:1) How to get SIM1 or SIM2 from call logs programatically 2) how to get call log for sim1, sim2 seperatly from an android activity?

如有任何帮助,我们将不胜感激。

首先,您提到您在不同的手机上获得了字段 PHONE_ACCOUNT_ID 的不同号码,这是完全正确的。

但你不必担心,它不应该打扰你。

So Why there are different values for the PHONE_ACCOUNT_ID?

好吧,subscription_idPHONE_ACCOUNT_ID 对于您设备上的每张 SIM 卡都是唯一的。清除假设假设您的设备上有两张 SIM 卡,那么场景将是这样的

  • Sim 1 的订阅 ID 为 1
  • Sim 2 的订阅 ID 为 2

现在假设您删除一个 sim 说 Sim 1 并输入一个以前从未插入到设备上的新 sim,我们称它为 Sim 3。那么这个 sim 将具有 subscription_id 作为 3,而不是在 1 或 2

类似地,当您在设备上插入第 4 个 sim 时,在它的 id 之前未插入的 sim 将不是 1,2,3 但是如果您再次插入 sim 1,它将具有 subscription_id 作为 1和以前一样

Note: It's not necessary for subscription_id's to appear in sequential order they can be anything even more than 2 digits

现在要访问与当前在设备上的 sim 相关的实际联系人日志。但是日志也可以包含与其他模拟人生相关的日志,即旧模拟人生,让我们称它们为旧日志。所以我们需要获取当前 sim 的当前 simid 你可以这样做

创建 Class 调用 CallHistory

data class CallHistory(var number:String,
                       var name:String?,
                       var type:Int,
                       var date:Long,
                       var duration: Long,
                       var subscriberId:String) {

    val cachedName:String  // Separate property for cachedName
        get() {
      return  if(name==null) number else name as String
    }

}

然后写这个函数来获取激活的sim卡信息

    /**
     * This Function Will return list of SubscriptionInfo
     */
    private fun getSimCardInfos() : List<SubscriptionInfo>?{
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
            val subscriptionManager: SubscriptionManager = getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
            if (ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.READ_PHONE_STATE
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                throw Exception("Permission Not Granted -> Manifest.permission.READ_PHONE_STATE")
            }
            return subscriptionManager.activeSubscriptionInfoList
        }else{
            return null
        }
    }

写这个函数获取所有通话记录

 // This function will return the all Call History
    fun getAllCallHistory() : MutableList<CallHistory>{

        val managedCursor = if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.READ_CALL_LOG
            ) != PackageManager.PERMISSION_GRANTED
        ) {
           throw Exception("Permission Not Granted -> Manifest.permission.READ_CALL_LOG")
        }else{
            this.contentResolver?.query(
                CallLog.Calls.CONTENT_URI, null, null,
                null, null)
        }

        managedCursor?.let {
            val callHistoryList= mutableListOf<CallHistory>()
            while (it.moveToNext())
            {
                callHistoryList.add(CallHistory(number = it.getString(it.getColumnIndex(CallLog.Calls.NUMBER)),
                    name = it.getString(it.getColumnIndex(CallLog.Calls.CACHED_NAME))?:null,
                    type = it.getString(it.getColumnIndex(CallLog.Calls.TYPE)).toInt(),
                    date = it.getString(it.getColumnIndex(CallLog.Calls.DATE)).toLong(),
                    duration = it.getString(it.getColumnIndex(CallLog.Calls.DURATION)).toLong(),
                    subscriberId = it.getString(it.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID)))
                )

             }
            it.close()
            return callHistoryList
        }

        return mutableListOf<CallHistory>()

    }

现在我们需要根据 subscription_id,即 PHONE_ACCOUNT_ID 来分离通话记录,但是这有一个问题,即一些设备商店 sim ICCID [这是一个 19-20 位的代码,每个 sim 卡都是唯一的] PHONE_ACCOUNT_ID 但有些设备存储实际的订阅 ID,只有 1 位或 2 位。所以我们需要检查 subscription_id 是否等于原始 sim subscription_id 或者是否等于 iccid

编写此函数以仅获取所选 sim 的通话记录

fun getCallHistoryOfSim(simInfo:SubscriptionInfo?, allCallList:MutableList<CallHistory> ) : MutableList<CallHistory> {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1){
       return allCallList.filter { it.subscriberId==simInfo?.subscriptionId.toString() || it.subscriberId.contains(simInfo?.iccId?:"_")}.toMutableList()
    }else{
        throw Exception("This Feature Is Not Available On This Device")
    }

}

所以上面的函数只给出了所选 sim 的日志

您可以调用上述函数并获取列表。调用示例如下

       for(log in getCallHistoryOfSim( getSimCardInfos()?.get(0),getAllCallHistory()) )
        {
            Log.d("Sim1LogDetails", "$log\n____________________________________")
        }

        for(log in getCallHistoryOfSim( getSimCardInfos()?.get(1),getAllCallHistory()) )
        {
            Log.d("Sim2LogDetails", "$log\n____________________________________")

        }

In order to get this code get work you need to specify 2 permissions

<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

应用程序应针对 API 级别 22

这是一个很长的答案希望你明白它的作用。如果有任何疑问,请告诉我