Martynas B
Martynas B

Reputation: 3143

How to detect outgoing call number in Android Q

I'm unable to get outgoing call number in Android Q.

I've registered receiver in the manifest with this intent filter android.intent.action.NEW_OUTGOING_CALL and in code i'm detecting outgoing phone number like this

@Override
public void onReceive(Context context, Intent intent) {
    if(intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL"))
        String nr = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
}

But i can never get the outgoing call number in Android Q, is there a workaround to get this number differently or since Android Q it is completely impossible to detect outgoing call number?

Edit: It works with previous android versions

Upvotes: 4

Views: 9833

Answers (3)

Lucas Soares
Lucas Soares

Reputation: 56

Answered in Kotlin, not Java:

From sdk >=29 (Android 10 and up) you can register your app as a CallRedirectionService, "to interact between Telecom and its implementor for making outgoing call with optional redirection/cancellation purposes."

This removes the need to create a custom BroadcastReceiver.

1. On your AndroidManifest.xml file:

<service
       android:name=".MyCallRedirectionService"
       android:exported="true"
       android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE">
       <intent-filter>
           <action android:name="android.telecom.CallRedirectionService" />
       </intent-filter>
</service>

2. Create MyCallRedirectionService:

class MyCallRedirectionService : CallRedirectionService() {

    override fun onPlaceCall(
        handle: Uri,
        initialPhoneAccount: PhoneAccountHandle,
        allowInteractiveResponse: Boolean
    ) {

        // We can get the outgoing number from the handle parameter:
        Log.i("Phone Number:", handle.toString())
    }
}

3. Use the RoleManager class to prompt the user to select your app as their CallRedirectionService:

In this case, I'm requesting as soon as the app is created, over on the MainActivity onCreate() method:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (!isRedirection())
            roleAcquire(RoleManager.ROLE_CALL_REDIRECTION)
}

Here are the used functions:

    private fun isRedirection(): Boolean {
        return isRoleHeldByApp(RoleManager.ROLE_CALL_REDIRECTION)
    }

    private fun isRoleHeldByApp(roleName: String): Boolean {
        val roleManager: RoleManager? = getSystemService(RoleManager::class.java)
        return roleManager!!.isRoleHeld(roleName)

    }

    private fun roleAcquire(roleName: String) {
        val roleManager: RoleManager?
        if (roleAvailable(roleName)) {
            roleManager = getSystemService(RoleManager::class.java)
            val intent = roleManager.createRequestRoleIntent(roleName)
            startActivityForResult(intent, 1)
        } else {
            Toast.makeText(
                this,
                "Redirection call with role in not available",
                Toast.LENGTH_SHORT
            ).show()
        }

    }

    private fun roleAvailable(roleName: String): Boolean {
        val roleManager: RoleManager? = getSystemService(RoleManager::class.java)
        return roleManager!!.isRoleAvailable(roleName)
    }

Upvotes: 2

Mahmoud Waked
Mahmoud Waked

Reputation: 405

You need to add PROCESS_OUTGOING_CALLS permission

Create OutgoingCallReceiver

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;

public class OutgoingCallReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

            TelephonyManager tm = (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);
            if (tm.getCallState() == TelephonyManager.CALL_STATE_OFFHOOK) {

                String number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

            }

    }

}

Add required permissions to read outcomming call in AndroidManifest file

  <uses-permission android:name="android.permission.NEW_OUTGOING_CALL" />
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

Request permissions at runtime

if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.PROCESS_OUTGOING_CALLS, Manifest.permission.READ_PHONE_STATE},
                    1);
        }

Add OutgoingCallReceiver in AndroidManifest file

  <receiver
        android:name=".application.services.OutgoingCallReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.PHONE_STATE" />
        </intent-filter>
    </receiver>

This code will work fine with you, but when you need to upload your application on Google play, It is ok with NEW_OUTGOING_CALL and READ_PHONE_STATE permission but, you will receive a policy notice from playStore as:

Your app manifest requests the Call Log permission group (e.g. PROCESS_OUTGOING_CALLS) It must be actively registered as the default Phone or Assistant handler on the device.

in this case you have 2 solution only if you want to read OutCommingCall Number:

Send declaration form to google declaration form

Or Make your application dialer app

Check Developer Policy Center

Upvotes: 7

mjn
mjn

Reputation: 36664

From the documentation for android.intent.action.NEW_OUTGOING_CALL:

This constant was deprecated in API level 29. Apps that redirect outgoing calls should use the CallRedirectionService API. Apps that perform call screening should use the CallScreeningService API.

https://developer.android.com/reference/android/content/Intent

So I would implement this API first and check if it works as expected.

Upvotes: 0

Related Questions