herz88888888
herz88888888

Reputation: 69

Get info about incoming call from selected sim

I use a broadcast receiver to intercept calls coming to the phone and send them and then process them. I need to receive calls only from a certain SIM card in a two-key phone. I can try to do it like this

    override fun onReceive(context: Context, intent: Intent) {

        if (intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
            try {
                val number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER)
                intent.extras
                if (number != null) {
                    val now = Date()
                    val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE)
                    Log.d(TAG, "stateName: $state number: $number")
                    Handler(Looper.getMainLooper()).postDelayed({
                        val c: Cursor? = context.contentResolver.query(
                            CallLog.Calls.CONTENT_URI,
                            null,
                            null,
                            null,
                            CallLog.Calls.DATE + " DESC"
                        )
                        var duration: Int? = null
                        var id: Int? = null
                        var num: String? = null
                        var type: Int = -100
                        var date: Date? = null
                        var iccId: String = ""
                        if (c?.columnCount?:0 > 0) {
                            c?.moveToFirst()
                            num = c?.getString(c.getColumnIndex(CallLog.Calls.NUMBER))
                            duration = c?.getInt(c.getColumnIndex(CallLog.Calls.DURATION))
                            type = (c?.getString(c.getColumnIndex(CallLog.Calls.TYPE)) ?: "-100").toInt()
                            iccId = c?.getString(c.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID))?:""
                            id = c?.getInt(c.getColumnIndex(CallLog.Calls._ID))
                            date = c?.getLong(c.getColumnIndex(CallLog.Calls.DATE))?.let { Date(it) }
                        }
                        c?.close()

                        if (id != null && number.equals(num, true)
                            && duration != null && date != null
                            && abs(now.time - duration - date.time) < 5_000) {
                            id = null
                            date = null
                            duration = null
                            iccId = ""
                        }

                        if (!SettingsStore(context).findEnabledFilters().contains(iccId)) {
                            sendToHandlers(context, number, state, duration, id, date)
                        }
                    }, 1_500)
                }
            } catch (e: Exception) {
                CrashMonitor.trackWarning(e.message, e.stackTraceToString())
                e.printStackTrace()
            }
        }
    }

I'm trying to filter calls by iccId, but I always get in intent from receiver the iccId of the PREVIOUS telephony status. Is there a way to somehow get the current iccID of the call, or perhaps there is another more correct and working way to get information only about calls to a specific SIM card?

Upvotes: 0

Views: 100

Answers (1)

herz88888888
herz88888888

Reputation: 69

I went the other way and started using a custom PhoneStateListener, creating inside broadcast receiver a telephonymanager subscription by the subscription id of the desired SIM card in the desired slot.

Below is a slightly unfinished, but already working implementation example

BroadcastReceiver

class CallReceiver : BroadcastReceiver() {

    private val TAG = this::class.java.simpleName

    var telephony: TelephonyManager? = null

    @SuppressLint("Range", "UnsafeProtectedBroadcastReceiver")
    override fun onReceive(context: Context, intent: Intent) {
        val number: String?
        if (intent.action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
            try {
                number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER)
                intent.extras
                if (number != null) {
                    val phoneListener = MyPhoneStateListener(context, number)
                    telephony = context
                        .getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
                    val sm =
                        context.getSystemService(TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
                    if (ActivityCompat.checkSelfPermission(
                            context,
                            Manifest.permission.READ_PHONE_STATE
                        ) != PackageManager.PERMISSION_GRANTED
                    ) {
                        // TODO: Consider calling
                        //    ActivityCompat#requestPermissions
                        return
                    }

                    val mSim0TelephonyManager = telephony!!.createForSubscriptionId(1)
                    mSim0TelephonyManager!!.listen(
                        phoneListener,
                        PhoneStateListener.LISTEN_CALL_STATE
                    )
                }


            } catch (e: Exception) {
            }
        }
    }

    fun onDestroy() {
        telephony!!.listen(null, PhoneStateListener.LISTEN_NONE)
    }


}

PhoneStateListener

class MyPhoneStateListener(val context: Context, var number: String?) : PhoneStateListener() {
    private var stateName = ""
    override fun onCallStateChanged(state: Int, incomingNumber: String) {
        when (state) {
            TelephonyManager.CALL_STATE_IDLE -> {
                Log.d("DEBUG", "IDLE")
                phoneRinging = false
                stateName = "IDLE"
            }

            TelephonyManager.CALL_STATE_OFFHOOK -> {
                Log.d("DEBUG", "OFFHOOK")
                phoneRinging = false
                stateName = "OFFHOOK"
            }

            TelephonyManager.CALL_STATE_RINGING -> {
                Log.d("DEBUG", "RINGING")
                phoneRinging = true
                stateName = "RINGING"
            }
        }

        number?.let { hand(context = context, number = it, duration = 1, id=10, state = stateName  ) }
    }

    companion object {
        var phoneRinging = false
    }
}

Upvotes: -1

Related Questions