识别 Android 通话记录中使用 PHONE_ACCOUNT_ID 的 SIM 卡槽

huangapple go评论65阅读模式
英文:

Identifying a SIM card slot with PHONE_ACCOUNT_ID in Android CallLogCalls

问题

在双卡手机中,我成功地使用以下代码中的 PHONE_ACCOUNT_ID 属性区分通话记录中的 SIM 卡。现在我需要知道实际上是哪张 SIM 卡(卡1还是卡2)用于拨打或接收通话。PHONE_ACCOUNT_ID 的显示类似于 8953011201104578086F,对于一张 SIM 卡是这样的,而对于另一张卡则类似但不相同。这在三星手机上经过测试:

fun readCallLog() {
    val cursor = context.contentResolver.query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE + " DESC")
    val number = cursor?.getColumnIndex(CallLog.Calls.NUMBER)
    val date = cursor?.getColumnIndex(CallLog.Calls.DATE)
    val type = cursor?.getColumnIndex(CallLog.Calls.TYPE)
    val account_id = cursor?.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID)

    val tmp: MutableList<List<String?>> = mutableListOf()

    while (cursor?.moveToNext() == true) {
        val call_number = if (number != null) cursor.getString(number) else ""
        val call_date = if (date != null) cursor.getString(date) else ""
        val call_type = if (type != null) cursor.getInt(type).toString() else ""
        val call_account_id = if (account_id != null) cursor.getString(account_id) else ""

        tmp.add(listOf(call_number, call_date, call_type, call_account_id))
    }
}
英文:

In dual-SIM card mobiles I manage to differentiate SIM cards in the calllog using the PHONE_ACCOUNT_ID property as shown in the code below. Now I need to know what SIM card actually was use (1 or 2) to make or receive the call. PHONE_ACCOUNT_ID shows something like this 8953011201104578086F for and one SIM card and similar, but no equal to the other. This was tested in a Samsung mobile:

fun readCallLog() {
    val cursor = context.contentResolver.query(CallLog.Calls.CONTENT_URI,null, null, null, CallLog.Calls.DATE + &quot; DESC&quot;)
    val number = cursor?.getColumnIndex(CallLog.Calls.NUMBER)
    val date = cursor?.getColumnIndex(CallLog.Calls.DATE)
    val type = cursor?.getColumnIndex(CallLog.Calls.TYPE)
    val account_id = cursor?.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID)


    val tmp : MutableList&lt;List&lt;String?&gt;&gt; = mutableListOf()

    while (cursor?.moveToNext() == true ) {
        val call_number = if (number != null) cursor.getString(number) else &quot;&quot;
        val call_date = if(date != null) cursor.getString(date) else &quot;&quot;
        val call_type = if(type != null) cursor.getInt(type).toString() else &quot;&quot;
        val call_account_id = if(account_id != null) cursor.getString(account_id) else &quot;&quot;

        tmp.add( listOf(call_number, call_date, call_type, call_account_id))
    }
}

答案1

得分: 2

你可以使用SubscriptionManager.getActiveSubscriptionInfoList()获取有关SIM卡的信息。

在某些设备上,Call.PHONE_ACCOUNT_ID等于subscriptionInfo.getSubscriptionId();然而在其他设备上(您的情况),subscriptionInfo.getIccId()是其子字符串,因此您需要同时检查两者。

还可参考SubscriptionManager的参考资料。

英文:

You can get information on SIM cards with SubscriptionManager.getActiveSubscriptionInfoList().

On some devices, Call.PHONE_ACCOUNT_ID equals subscriptionInfo.getSubscriptionId(), however on other devices (your case) subscriptionInfo.getIccId() is a substring of it, so you need to check both.

See also SubscriptionManager reference.

答案2

得分: 0

以下是翻译好的部分:

正式方法是检查账户ID(文档链接在此),但在某些设备上,它只返回SIM卡槽索引,因此以下是带有解决方法的代码(来自Android 6.0(Marshmallow)):

fun getSimSlotIndexFromAccountId(context: Context, accountIdToFind: String): Int {
    // 实际上应该找到的是官方数据,就像在模拟器上一样,但遗憾的是,并非所有手机都会在这里返回正确的值
    val telecomManager = context.getSystemService<TelecomManager>()
    telecomManager.callCapablePhoneAccounts.forEachIndexed { index, account: PhoneAccountHandle ->
        val phoneAccount: PhoneAccount = telecomManager.getPhoneAccount(account)
        val accountId: String = phoneAccount.accountHandle
            .id
        if (accountIdToFind == accountId) {
            return index
        }
    }
    accountIdToFind.toIntOrNull()?.let {
        if (it >= 0)
            return it
    }
    return -1
}

用法:

val simIdColumnIndex = callLogCursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID)
val accountId: String = callLogCursor.getString(simIdColumnIndex)
val simCardSlotIndex = getSimSlotIndexFromAccountId(applicationContext, accountId)

我已经在这里报告了这个问题(某些设备不遵循官方API):

Bug:在某些设备上,PHONE_ACCOUNT_ID只返回SIM卡槽索引

英文:

The official way is to check the account-id (documentation here), but on some devices it just returns the SIM card slot index, so here's the code with a workaround (from Android 6.0 (Marshmallow)):

fun getSimSlotIndexFromAccountId(context: Context, accountIdToFind: String): Int {
    // This is actually the official data that should be found, as on the emulator, but sadly not all phones return here a proper value
    val telecomManager = context.getSystemService&lt;TelecomManager&gt;()
    telecomManager.callCapablePhoneAccounts.forEachIndexed { index, account: PhoneAccountHandle -&gt;
        val phoneAccount: PhoneAccount = telecomManager.getPhoneAccount(account)
        val accountId: String = phoneAccount.accountHandle
            .id
        if (accountIdToFind == accountId) {
            return index
        }
    }
    accountIdToFind.toIntOrNull()?.let {
        if (it &gt;= 0)
            return it
    }
    return -1
}

Usage:

val simIdColumnIndex = callLogCursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID)
val accountId: String = callLogCursor.getString(simIdColumnIndex)
val simCardSlotIndex = getSimSlotIndexFromAccountId(applicationContext, accountId)

I've reported about this issue (that some devices don't follow official API) here:

Bug: on some devices, PHONE_ACCOUNT_ID just returns the SIM-card slot index

huangapple
  • 本文由 发表于 2020年9月11日 00:43:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/63834168.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定