识别来自Sim1和Sim2的通话记录 [英] Identify Call logs from Sim1 and Sim2

查看:86
本文介绍了识别来自Sim1和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)如何获取SIM1或呼叫记录中的SIM2编程方式 2)解决方案

首先,您提到您在PHONE_ACCOUNT_ID字段中使用不同的电话获得了不同的号码,这是绝对正确的.

但是您不必为此担心,它也不会打扰您.

那为什么PHONE_ACCOUNT_ID会有不同的值?

好吧,subscription_id,即PHONE_ACCOUNT_ID对于设备上的每个SIM卡都是唯一的.要明确地说,假设您的设备上有两个SIM卡,那么情况将是这样

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

现在假设您删除一个说Sim 1的sim,然后输入一个以前从未在设备上插入过的新sim,我们将其称为Sim3.然后此sim的subscription_id将为3,而不是1或2.

类似地,当您在未插入其ID的设备上插入第四个sim卡时,将不是1,2,3,但是如果再次插入Sim 1,它将像以前一样将subscription_id设为1

注意:subscription_id不必按顺序出现,它们甚至可以是2位数以上的数字

现在要访问与设备上当前存在的SIM卡相关的实际联系人日志.但是日志中还可以包含与其他SIM卡相关的日志,即旧的SIM卡让我们将其称为旧日志.因此,我们需要获取当前sim卡的当前 simid ,您可以像这样

创建一个名为 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)来分隔通话记录,但这存在问题,例如某些设备存储卡 ICCID [ PHONE_ACCOUNT_ID中的每个sim唯一的19-20位代码],但某些设备存储的实际订阅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____________________________________")

        }

为了获得此代码,您需要指定2个权限

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

并且应用程序应定位到API级别22

很长的答案,希望您能明白它的作用.如有任何疑问,请告诉我

I'm trying to show call logs from Sim1 and Sim2 separately. I'm getting all call logs, but not able to differentiate it whether it is from Sim1 or Sim2. I have tried below code,

 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()
    }

I have read documents showing PHONE_ACCOUNT_ID may help to identify it. But it's giving different numbers in different phones.

I have also read many SO questions as well, but not able to find any solution.

like: 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?

Any help will be appreciated, thanks.

解决方案

To start off you mentioned that you are getting different numbers in different phones for the field PHONE_ACCOUNT_ID which is absolutely correct.

But you don't need to worry about that and it should not bother you.

So Why there are different values for the PHONE_ACCOUNT_ID?

Well, subscription_id i.e PHONE_ACCOUNT_ID will be unique for each sim card on your device. To clear suppose say you have two sim cards on your device then scenario will be like this

  • Sim 1 will have a subscription id as 1
  • Sim 2 will have a subscription id as 2

Now suppose you remove one sim says Sim 1 and enter a new sim which is never inserted on the device before, let's call it as Sim 3. Then this sim will be having subscription_id as 3, not in 1 or 2

Similarly when you insert a 4th sim on the device which is not inserted before it's id will be something other than 1,2,3 But if you insert Sim 1 again it will be having subscription_id as 1 just as before

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

Now coming to accessing the actual contacts logs related to the sim's present currently on the device is to be done. But the logs can also have the logs related to other sims i.e old sims let's call them old logs. So we need to get the current simid for the current sim's you can do it like this

Create A Class Called 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
    }

}

Then Write this function to get the active sim card info

    /**
     * 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
        }
    }

Write this function to get all call logs

 // 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>()

    }

Now we need to separate call logs based on the subscription_id's i.e PHONE_ACCOUNT_ID but there is a problem with this i.e some device store sim ICCID [ It's a 19-20 digit code which is unique for each sim] in PHONE_ACCOUNT_ID but some devices store The actual subscription id which is 1 or 2 digit only. So we need to check whether the subscription_id is equal to original sim subscription_id or it is equal to iccid

Write this function to get Call Logs of only selected 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")
    }

}

So the above function gives logs of the selected sim only

you can call the functions the above functions and get the list. An example call is like this

       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" />

And App Should Target API level 22

It's Quite a long answer hope you got what It does. If any doubts let me know

这篇关于识别来自Sim1和Sim2的通话记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆