I am developing an application where one of the things we need is to control the outgoing call, at least to be able to stop it from our application.
I've tried using Intent.ACTION_CALL
from an existing activity:
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber)); startActivity(callIntent);
But stopping the call seems to be disallowed through the API.
Can you suggest some workaround?
For example: enabling airplane mode during the call? Just an example; this hack didn't work for me.
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();
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); }
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