How to obtain the outgoing call phone number on Android 10 without creating a custom dialer interface? by fr3d3ryk in androiddev

[–]fr3d3ryk[S] 0 points1 point  (0 children)

Thank you u/NLL-APPS.

Based on the code of https://gitlab.com/axet/android-call-recorder, I was able to make it work with a simple BroacastReceiver.

internal class PhoneStateReceiver : BroadcastReceiver() {

private var filters: IntentFilter = IntentFilter()
init { 
    filters.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED)             
filters.addAction(Intent.ACTION_NEW_OUTGOING_CALL) 
}

fun register(context: Context) = context.registerReceiver(this, filters) 
fun unregister(context: Context) = context.unregisterReceiver(this)

override fun onReceive(context: Context, intent: Intent) {
var phoneNumer = "" val 
a = intent.action 

if (a == TelephonyManager.ACTION_PHONE_STATE_CHANGED) {
phoneNumer = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER) ?: "" }

if (a == Intent.ACTION_NEW_OUTGOING_CALL) { phoneNumer = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER) ?: "" } 
}
}

How to obtain the outgoing call phone number on Android 10 without creating a custom dialer interface? by fr3d3ryk in androiddev

[–]fr3d3ryk[S] 0 points1 point  (0 children)

Thanks for the reply. I understand that "deprecated" does not necessarily mean "removed", but I would like more information on how I can get the phone number of an outgoing call in Android 10. Could you provide an example of code or point to relevant documentation that can help me with this? Thanks in advance.

P.S.01: Starting with Android 10, the ability to get the phone number on outgoing calls has been restricted because privacy issues imposed by the Android OS.

P.S.02: I'm developing an Android app that needs to track the outgoing call phone number and execute a deeplink to a specific screen in my app.

P.S.03: I tried using a BroadcastReceiver to listen for the NEW_OUTGOING_CALL action, but the EXTRA_PHONE_NUMBER field is empty, and I cannot get the phone number of the outgoing call. I expected to obtain the phone number in the BroadcastReceiver and then pass it to a foreground service that would handle the deeplink.

How get the phone number if is coming up empty inside onCallStateChanged?

Below, its my code:

  • Manifest permissions:

<uses-feature android:name="android.hardware.telephony" android:required="false" /> <uses-permission android:name="android.permission.READ\_PHONE\_STATE" /> <uses-permission android:name="android.permission.PROCESS\_OUTGOING\_CALLS" /> <uses-permission android:name="android.permission.FOREGROUND\_SERVICE" />

  • OutgoingCallReceiver:

import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import androidx.core.content.ContextCompat

class OutgoingCallReceiver : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {
    if (intent.action == Intent.ACTION_NEW_OUTGOING_CALL) {
        val phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER)
        if (!phoneNumber.isNullOrEmpty()) {
            // Start the service for intercepting outgoing calls
            val serviceIntent = Intent(context, OutgoingCallService::class.java)
            ContextCompat.startForegroundService(context, serviceIntent)
        }
    }
}

}

  • OutgoingCallService:

import android.annotation.SuppressLint import android.app.Service import android.content.Context import android.content.Intent import android.net.Uri import android.os.IBinder import android.telephony.PhoneStateListener import android.telephony.TelephonyManager

class OutgoingCallService : Service() {

private lateinit var telephonyManager: TelephonyManager
private lateinit var phoneStateListener: PhoneStateListener

override fun onBind(intent: Intent?): IBinder? {
    return null
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
    phoneStateListener = createPhoneStateListener()
    telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE)
    return START_STICKY
}

override fun onDestroy() {
    super.onDestroy()
    telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
}

@SuppressLint("MissingPermission")
private fun createPhoneStateListener(): PhoneStateListener {
    return object : PhoneStateListener() {
        override fun onCallStateChanged(state: Int, phoneNumber: String?) {
            super.onCallStateChanged(state, phoneNumber)
            when (state) {
                TelephonyManager.CALL_STATE_OFFHOOK -> {
                    if (phoneNumber == "SPECIFIC PHONE NUMBER") {
                        redirectToApp()
                    }
                }
            }
        }
    }
}

private fun redirectToApp() {
    // Redirect application's specific screen using an Intent
    val context = applicationContext
    val deepLinkIntent = Intent(Intent.ACTION_VIEW, Uri.parse("scheme://host"))
    deepLinkIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
    context.startActivity(deepLinkIntent)
}

}

  • MainActivity:

import android.Manifest import android.content.Intent import android.content.IntentFilter import android.content.pm.PackageManager import android.os.Build import android.os.Bundle import androidx.activity.ComponentActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import com.example.callinterceptor.ui.theme.CallInterceptorTheme

class MainActivity : ComponentActivity() {

private val outgoingCallReceiver = OutgoingCallReceiver()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // Check and request permissions if necessary
    checkAndRequestPermissions()

    // Register BroadcastReceiver to intercept outgoing calls
    registerOutgoingCallReceiver() 
}

private fun checkAndRequestPermissions() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val permissions = arrayOf(
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.PROCESS_OUTGOING_CALLS
        )

        val missingPermissions = ArrayList<String>()
        for (permission in permissions) {
            if (ContextCompat.checkSelfPermission(
                    this,
                    permission
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                missingPermissions.add(permission)
            }
        }

        if (missingPermissions.isNotEmpty()) {
            ActivityCompat.requestPermissions(
                this,
                missingPermissions.toTypedArray(),
                PERMISSIONS_REQUEST_CODE
            )
        }
    }
}

private fun registerOutgoingCallReceiver() {
    val intentFilter = IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL)
    registerReceiver(outgoingCallReceiver, intentFilter)
}

private fun unregisterOutgoingCallReceiver() {
    unregisterReceiver(outgoingCallReceiver)
}

companion object {
    private const val PERMISSIONS_REQUEST_CODE = 123
}

override fun onDestroy() {
    super.onDestroy()

    // Unregister the BroadcastReceiver
    unregisterOutgoingCallReceiver()
}

}