How to hang up outgoing call in Android?
Solution 1
Capturing the outgoing call in a BroadcastReceiver
has been mentioned and is definitely the best way to do it if you want to end the call before dialing.
Once dialing or in-call, however, that technique no longer works. The only way to hang up that I've encountered so far, is to do so through Java Reflection. As it is not part of the public API, you should be careful to use it, and not rely upon it. Any change to the internal composition of Android will effectively break your application.
Prasanta Paul's blog demonstrates how it can be accomplished, which I have summarized below.
Obtaining the ITelephony
object:
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
try {
// Java reflection to gain access to TelephonyManager's
// ITelephony getter
Log.v(TAG, "Get getTeleService...");
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
com.android.internal.telephony.ITelephony telephonyService =
(ITelephony) m.invoke(tm);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG,
"FATAL ERROR: could not connect to telephony subsystem");
Log.e(TAG, "Exception object: " + e);
}
Ending the call:
telephonyService.endCall();
Solution 2
EDIT: To Android P or newer, please see: https://stackoverflow.com/a/51121175/450148
Try this:
(I used Reflection to access advanced telephony features and modify somethings)
// required permission <uses-permission android:name="android.permission.CALL_PHONE"/>
try {
//String serviceManagerName = "android.os.IServiceManager";
String serviceManagerName = "android.os.ServiceManager";
String serviceManagerNativeName = "android.os.ServiceManagerNative";
String telephonyName = "com.android.internal.telephony.ITelephony";
Class telephonyClass;
Class telephonyStubClass;
Class serviceManagerClass;
Class serviceManagerStubClass;
Class serviceManagerNativeClass;
Class serviceManagerNativeStubClass;
Method telephonyCall;
Method telephonyEndCall;
Method telephonyAnswerCall;
Method getDefault;
Method[] temps;
Constructor[] serviceManagerConstructor;
// Method getService;
Object telephonyObject;
Object serviceManagerObject;
telephonyClass = Class.forName(telephonyName);
telephonyStubClass = telephonyClass.getClasses()[0];
serviceManagerClass = Class.forName(serviceManagerName);
serviceManagerNativeClass = Class.forName(serviceManagerNativeName);
Method getService = // getDefaults[29];
serviceManagerClass.getMethod("getService", String.class);
Method tempInterfaceMethod = serviceManagerNativeClass.getMethod(
"asInterface", IBinder.class);
Binder tmpBinder = new Binder();
tmpBinder.attachInterface(null, "fake");
serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder);
IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone");
Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class);
telephonyObject = serviceMethod.invoke(null, retbinder);
//telephonyCall = telephonyClass.getMethod("call", String.class);
telephonyEndCall = telephonyClass.getMethod("endCall");
//telephonyAnswerCall = telephonyClass.getMethod("answerRingingCall");
telephonyEndCall.invoke(telephonyObject);
} catch (Exception e) {
e.printStackTrace();
Log.error(DialerActivity.this,
"FATAL ERROR: could not connect to telephony subsystem");
Log.error(DialerActivity.this, "Exception object: " + e);
}
Solution 3
- Create a
BroadcastReceiver
with a priority of 0. - In the BC intercept the
ACTION_NEW_OUTGOING_CALL
intent in itsonReceive
method - call
setResultData(null)
in the same method
This will prevent the call from initiating (as long as your receiver is the last to process the intent I think)
Solution 4
Here's the most updated code, which will work for Android P too, because it has an official API for it (here) :
in manifest, add this:
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS"/>
In code, use this:
Java:
@SuppressLint("PrivateApi")
public static boolean endCall(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
final TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
if (telecomManager != null && ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED) {
telecomManager.endCall();
return true;
}
return false;
}
//use unofficial API for older Android versions, as written here: https://stackoverflow.com/a/8380418/878126
try {
final Class<?> telephonyClass = Class.forName("com.android.internal.telephony.ITelephony");
final Class<?> telephonyStubClass = telephonyClass.getClasses()[0];
final Class<?> serviceManagerClass = Class.forName("android.os.ServiceManager");
final Class<?> serviceManagerNativeClass = Class.forName("android.os.ServiceManagerNative");
final Method getService = serviceManagerClass.getMethod("getService", String.class);
final Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class);
final Binder tmpBinder = new Binder();
tmpBinder.attachInterface(null, "fake");
final Object serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder);
final IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone");
final Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class);
final Object telephonyObject = serviceMethod.invoke(null, retbinder);
final Method telephonyEndCall = telephonyClass.getMethod("endCall");
telephonyEndCall.invoke(telephonyObject);
return true;
} catch (Exception e) {
e.printStackTrace();
LogManager.e(e);
}
return false;
}
or in Kotlin:
@SuppressLint("PrivateApi")
fun endCall(context: Context): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED) {
telecomManager.endCall()
return true
}
return false
}
//use unofficial API for older Android versions, as written here: https://stackoverflow.com/a/8380418/878126
try {
val telephonyClass = Class.forName("com.android.internal.telephony.ITelephony")
val telephonyStubClass = telephonyClass.classes[0]
val serviceManagerClass = Class.forName("android.os.ServiceManager")
val serviceManagerNativeClass = Class.forName("android.os.ServiceManagerNative")
val getService = serviceManagerClass.getMethod("getService", String::class.java)
val tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder::class.java)
val tmpBinder = Binder()
tmpBinder.attachInterface(null, "fake")
val serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder)
val retbinder = getService.invoke(serviceManagerObject, "phone") as IBinder
val serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder::class.java)
val telephonyObject = serviceMethod.invoke(null, retbinder)
val telephonyEndCall = telephonyClass.getMethod("endCall")
telephonyEndCall.invoke(telephonyObject)
return true
} catch (e: Exception) {
e.printStackTrace()
return false
}
}
Solution 5
You can try enabling then disabling airplane mode:
android.provider.Settings.System.putInt(getContentResolver(),
android.provider.Settings.System.AIRPLANE_MODE_ON, 1);
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", 1);
sendBroadcast(new Intent("android.intent.action.AIRPLANE_MODE"));
sendBroadcast(intent);
android.provider.Settings.System.putInt(getContentResolver(),
android.provider.Settings.System.AIRPLANE_MODE_ON, 0);
intent.putExtra("state", 0);
sendBroadcast(new Intent("android.intent.action.AIRPLANE_MODE"));
sendBroadcast(intent);
Copain
Updated on December 31, 2020Comments
-
Copain over 3 years
Need advice trying to build Student Management Database using Laravel below is my Diagram need your advice if i'm doing the right way..
-
Admin almost 14 yearsTerminating the call is possible. TextMe4Callback on the Android market does this.
-
Bahadır Yıldırım over 13 yearsDid using
BroadcastReceiver
work for you? Could you revise this question and/or accept an answer? -
LobsterBaz over 4 yearsCan a user be both a staff member and a student?
-
Strawberry over 4 yearsWhat's the difference between points and score_user? In general, this looks overly complex to me, but I don't know your precise requirements
-
Copain over 4 yearsNope each has different role to play..student can login check his scores attendance subjects , Staff can update all student information example. grades,subject class etc.. @LobsterBaz
-
Copain over 4 years@Strawberry points will represent as type of points example. EXAM , HOMEWORK, PARTICIPATION, ORAL, etc.. where value represent the allocated average in percentage like EXAM=50% then score user is the actual result like studen EXAM result=60points out of 50%
-
-
Admin over 13 yearsat this time there's no way to hang up an outgoing call, itself, the solution proposed by Gung Shi Jie is a good idea, but does not work, changes to the state "AIRPLANE MODE" will be ignored during an outgoing call, its works only on emulaterd terminals during developing, i've tried and failed in both HTC Desire and Acer Liquid phones.
-
Bahadır Yıldırım over 13 yearsThis is an explanation to Ash's answer, which uses
setResultData(null)
. -
Bjarke Freund-Hansen almost 13 years+1 Not good practice to do, but the OP asks specifically for a workaround for something that is not allowed by the API, thus this is a good answer.
-
Felipe over 12 yearsSure it is possible. See the answer above.
-
TacB0sS over 12 yearsIf this is the only solution, then I think this is a great answer!
-
Ronak Mehta about 12 yearshey i am not able to block particlar call by this code i checked
-
Bahadır Yıldırım about 12 years@Rstar What kind of exception are you getting? Which line or method is failing? Which device are you running? Which version of Android?
-
Ronak Mehta about 12 yearsi am not getting any exception see this code and i have also written some notes in pastebin.com/3TW0ieVZ
-
you786 about 12 yearsThis is a much better answer than Ash's. The OP obviously states that he wants to end a call rather than stop it from being answered.
-
shereifhawary about 12 yearsthanks it works just fine to hangup a telephone call throw an application
-
Bahadır Yıldırım almost 12 years@Rstar I would suggest adding some debug statements to check that your
BroadcastReceiver
is correctly registered from the manifest. -
DonnaLea over 11 yearsAny thoughts on why this works on Android 2.3.3 and earlier, but not Android 4.0 and later? I can't seem to pick up on the ACTION_NEW_OUTGOING_CALL with my BroadcastReceiver. I'm not interested in the cancelling call part though, just even knowing about a call I can't get working. Any thoughts would be appreciated, thanks!
-
VISHAL VIRADIA over 11 yearsworks excellent. [ required permission "<uses-permission android:name="android.permission.CALL_PHONE"/>" ]
-
android developer about 11 yearsworks really well. do you know of other useful call actions, like enable speaker, answer, ... ?
-
Felipe almost 11 yearsSorry @androiddeveloper I don't know. Actually, I make this code based on a lot of other tips found on StackOverflow. After a lot of tries, I built it.
-
android developer almost 11 years@FelipeMicaroniLalli thank you. wonder why it's sometimes so hard to find out how to do things on android.
-
kagali-san over 10 yearsworked on 4.2 within emulator (with modified .jar's to avoid hiding APIs by Eclipse-ADT)
-
Buddy over 8 yearsHow do you import com.android.internal.telephony.ITelephony? It generates 'Cannot resolve symbol error'.
-
Bahadır Yıldırım over 8 years@EnesBattal You need to include ITelephony.aidl in your project to provide an interface to the class.
-
android developer almost 6 years@Felipe This doesn't work anymore on Android P. Here's an updated code: stackoverflow.com/a/51121175/878126
-
FilipeOS almost 6 yearsany reason why telecomManager.endCall() cannot be resolved?
-
android developer almost 6 years@FilipeOS It's only from Android P. You need to change compileSdkVersion in the gradle file to be at least 28 in order to use it in code.
-
FilipeOS almost 6 yearsyeah... noob fail, thanks! I'm using almost this code in my app but on many phones can't work, specially sound and reject, any advise or good example link please?
-
android developer almost 6 yearsWell, I don't know of more ideas, except maybe having accessibility service to hang the phone, but this requires you to know on what exactly to click or perform the operation. I also don't know how to perform gestures on the accessibility service, if it's even possible. I also wonder if it's possible to reject calls via the notification of the Phone app, maybe by the special permission to handle notifications? If you succeed using this idea, please let me know.
-
Muhammad Babar over 4 yearsThanks a lot. Working perfect (y)
-
Felipe over 4 yearsNote that developer.android.com/reference/android/telecom/… was deprecated in API level 29 :-(
-
Muhammad Babar over 2 years@Felipe any work around except CallScreeningApi?
-
android developer over 2 years@Felipe Indeed, but still works.
-
android developer over 2 years@MuhammadBabar See here: xda-developers.com/…