Reputation: 2877
I am working on an android application where I do intercept the incoming phone call and ending it programmatically on some user action.
To achieve that have used ITelephony.endCall
.
This implementation works fine only till API level 24.
private void rejectCallViaTelephonyManager() {
ITelephony telephonyService = getTelephonyService();
if (telephonyService != null) {
telephonyService.endCall();
}
}
private ITelephony getTelephonyService() {
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
return (ITelephony) m.invoke(tm);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
I also came across new API TelecomManager.endCall
which got introduced in API level 28. which works fine for P beta device.
private void rejectCall() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P /* 28 */) {
TelecomManager manager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
if (manager != null) {
// complains required API app requires API level 28 (current min is 21).
manager.endCall();
}
} else {
rejectCallViaTelephonyManager();
}
Log.d(TAG, "call ended successfully.");
} catch (Exception e) {
e.printStackTrace();
}
}
Now I am looking for solution to make it work for API level 25,26,27 too.
Any idea how can we do that ?
My goal is to "end incoming phone call" functionality should work for all the version API level 21 onward.
Upvotes: 2
Views: 902
Reputation: 2013
Here is how I archived this and also work on android P version.
First of all.
Manifest Permissions:
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS"/>
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.PROCESS_INCOMING_CALLS" />
<uses-permission
android:name="android.permission.MODIFY_PHONE_STATE"
tools:ignore="ProtectedPermissions" />
Now on API greater than 21 ask users to give runtime permissions in code also. if lower than oreo then ask like this.
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.READ_PHONE_STATE},REQUEST_CONTACTS);
But if greater than oreo then.
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.ANSWER_PHONE_CALLS,Manifest.permission.READ_PHONE_STATE,Manifest.permission.READ_CALL_LOG},REQUEST_CONTACTS);
Now create a complete package in your app like this.
com.android.internal.telephony
In this package place this interface.
package com.android.internal.telephony;
public interface ITelephony {
boolean endCall();
void answerRingingCall();
void silenceRinger();
}
Now end call like this.
private void endCall(){
ITelephony telephonyService;
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (tm == null)
return;
try {
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(tm);
} catch (Exception e) {
e.printStackTrace();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
if (telecomManager != null) {
telecomManager.endCall();
}
} else {
if (telephonyService != null) {
telephonyService.silenceRinger();
telephonyService.endCall();
}
}}
Upvotes: 1