Android Studio - getting PreciseCallState of phone calls

Viewed 97

I'm trying to build an Android app in Android Studio to detect the precise call state of outgoing calls. I'm new to Java, and I'm going around in circles with a few problems.

The basic calls states are working fine for me per this youtube guide https://www.youtube.com/watch?v=rlzfcqDlovg. That tutorial uses "TelephonyManager.EXTRA_STATE" in its main class and the "android.intent.action.PHONE_STATE" receiver in the AndroidManifest. It successfully detects when an outgoing call is placed and ended, but NOT when it actually starts ringing/is answered/etc.

I'm trying to get the PreciseCallState of outgoing calls using a couple of StackOverFlow guides like this one How to Use PreciseCallState and other similar discussions, but I'm stuck with a few points:

  1. The basic receiver in AndroidManifest worked fine listening to "android.intent.action.PHONE_STATE". But my precise receiver, listening to "android.intent.action.PRECISE_CALL_STATE" doesn't fire at all, when a call is placed, answered, ended etc.

  2. Even if my receiver DID fire when the PRECISE_CALL_STATE changed, Android Studio doesn't recognize "TelephonyManager.EXTRA_FOREGROUND_CALL_STATE", and won't let me build the app when I try to use this line. I've tried using several "Hidden API bypass" scripts like this one https://github.com/LSPosed/AndroidHiddenApiBypass, but with no luck - I'm unsure how exactly to use this, as the instructions on these type of resources aren't clear to me. All I can figure out is to include their dependencies and "import" the package, not how to actually use it in my script.


Other points:

I know that Google introduced restrictopms on non-standard packages (including reflection) in API level 28 (refer https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces, so I've tried using API/SDK versions 25 through 32, all with no luck. My current attempt is using SDK version 30.

I've installed my app as a system app using Magisk Systemizer, per other Stackoverflow suggestions for using PreciseCallState, but this didn't fix my issues.

The app doesn't ask for the "READ_PRECISE_PHONE_STATE" permission at all, either when it's installed as a system app or a regular app. I'm not sure if this is okay, but I imagine I'm missing something.


I'd appreciate any help on these 2 issues, I've been trying to research and figure this out for a solid week now!


My code:

AndroidManifest:

<uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" />
<application...
    ...
    
    <receiver android:name=".CallReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <!-- (unused) <action android:name="android.intent.action.PHONE_STATE" />-->
            <action android:name="android.intent.action.PRECISE_CALL_STATE" />
            <!-- (unused) <action android:name="android.intent.action.NEW_OUTGOING_CALL" />-->
        </intent-filter>
    </receiver>
</application>

MainActivity:

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

CallReceiver:

public class CallReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String myString = "new PreciseCallState detected...";
        Toast.makeText(context, myString, Toast.LENGTH_LONG).show();
        //String myPreciseCallState = intent.getIntExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, -2);
        //Toast.makeText(context, myString + myPreciseCallState, Toast.LENGTH_LONG).show();
        // (unused) //String basicCallState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
    }
}
0 Answers
Related