androidtelephonytelephonymanagerandroid-12

TelephonyManager deprecated listen() CALL_STATE_RINGING on android 12


I'd like to listen if there's a phone call happening while my app is in the foreground.

It was like this before but now listen() is deprecated:

val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
            tm.listen(object : PhoneStateListener() {
                override fun onCallStateChanged(state: Int, phoneNumber: String?) {
                    super.onCallStateChanged(state, phoneNumber)
                    when (state) {
                        TelephonyManager.CALL_STATE_RINGING -> transcribingAudioConsumer.stopTranscription(null)
                        else -> {}
                    }
                }
            }, PhoneStateListener.LISTEN_CALL_STATE)

I tried something like this but I couldn't find the correct way to implement it.

         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                        tm.registerTelephonyCallback({ it.run() }, MyPhoneStateListener())
                    }
  @RequiresApi(Build.VERSION_CODES.S)
    class MyPhoneStateListener : TelephonyCallback(), TelephonyCallback.CallStateListener {
        override fun onCallStateChanged(state: Int) {
            when (state) {
                TelephonyManager.CALL_STATE_RINGING -> {
                    Timber.e("omg RING")
                }

                TelephonyManager.CALL_STATE_OFFHOOK -> {
                    Timber.e("omg hook")
                }
                TelephonyManager.CALL_STATE_IDLE -> {
                    Timber.e("omg idle")
                }
            }
        }
    }

Solution

  • Since the listen method is deprecated since api 31 android 12 I made a simple way to listen to the telephony callbacks.

    val telephonyManager: TelephonyManager =
        context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        telephonyManager.registerTelephonyCallback(
            context.mainExecutor,
            object : TelephonyCallback(), TelephonyCallback.CallStateListener {
                override fun onCallStateChanged(state: Int) {
                }
            })
    } else {
        telephonyManager.listen(object : PhoneStateListener() {
            override fun onCallStateChanged(state: Int, phoneNumber: String?) {
            }
        }, PhoneStateListener.LISTEN_CALL_STATE)
    }
    

    Note that the new callback does not include a phone number. At least for broadcast receiver the phone number can be retrieved via

    intent.extras.getString("incoming_number")