Identifying sim slot with PHONE_ACCOUNT_ID in android CallLogCalls

Viewed 566

in dual sim mobiles i manage to differentiate sims in the calllog using the PHONE_ACCOUNT_ID property as shown in the code below. Now I need to know what sim actually was use(1 or 2) to make or receive the call. PHONE_ACCOUNT_ID shows something like this 8953011201104578086F for and one sim and similiar 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 + " 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))
    }
}
2 Answers

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.

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

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

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:

https://issuetracker.google.com/issues/247339277

Related