I have an app that uses the following code to block calls:
TelephonyManager telephonyManager =
(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
try {
Class<?> telephonyManagerClass =
Class.forName(telephonyManager.getClass().getName());
Method getITelephonyMethod =
telephonyManagerClass.getDeclaredMethod("getITelephony");
getITelephonyMethod.setAccessible(true);
Object iTelephony = getITelephonyMethod.invoke(telephonyManager);
Class<?> iTelephonyClass = Class.forName(iTelephony.getClass().getName());
Method endCallMethod = iTelephonyClass.getDeclaredMethod("endCall");
endCallMethod.setAccessible(true);
endCallMethod.invoke(iTelephony);
} catch (ClassNotFoundException e) {
// ClassNotFoundException
} catch (NoSuchMethodException e) {
// NoSuchMethodException
} catch (IllegalAccessException e) {
// IllegalAccessException
} catch (InvocationTargetException e) {
// InvocationTargetException
} catch (Exception e) {
// Some other exception
}
To work, this required android.permission.MODIFY_PHONE_STATE in AndroidManifest.xml. In Android M and N, I also had to ask the user for permission Manifest.permission.CALL_PHONE.
But now in Android 8/Android O, the above code fails with InvocationTargetException: MODIFY_PHONE_STATE permission required
I found this related StackOverflow post: Android - Why does endCall method work but answerRingingCall doesn't work?
Here it is suggested that I might be able to use reflection on PhoneInterfaceManager (instead of ITelephony, like I have done above) and use the private method sendRequestAsync(int command) with the end call command, and by doing this getting around the security measure inside the endCall() method.
Has anyone tried something like this? Is it possible? How would I even get the PhoneInterfaceManager object/class instead of ITelephony?
I think this is the source code in question: https://android.googlesource.com/platform/packages/services/Telephony/+/oreo-release/src/com/android/phone/PhoneInterfaceManager.java
I can't see any difference between this and the code for Android N when it comes to ending calls, so I might be mistaken: https://android.googlesource.com/platform/packages/services/Telephony/+/nougat-release/src/com/android/phone/PhoneInterfaceManager.java
Thanks to Nikola Brežnjak's blog, I found an answer: https://dev.to/hitman666/how-to-make-a-native-android-app-that-can-block-phone-calls--4e15
Basically, you need to include the ITelephony interface in your project. Create a file ITelephony.class with the following code (keep the namespace):
package com.android.internal.telephony;
public interface ITelephony {
boolean endCall();
void answerRingingCall();
void silenceRinger();
}
Then from your code, use the following code to end a phone call:
// This is only useful on Android O and older
// Needs permission CALL_PHONE
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O
|| checkSelfPermission(Manifest.permission.CALL_PHONE)
== PackageManager.PERMISSION_DENIED) {
return;
}
try {
ITelephony telephonyService;
TelephonyManager telephonyManager = (TelephonyManager)
getSystemService(Context.TELEPHONY_SERVICE);
Method getITelephony = telephonyManager
.getClass()
.getDeclaredMethod("getITelephony");
getITelephony.setAccessible(true);
telephonyService = (ITelephony) getITelephony.invoke(telephonyManager);
telephonyService.endCall();
} catch (Exception ignored) {
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With