How to programmatically answer/end a call in Android 4.1?
My application has been using the following code to answer the phone for about 6 months:
Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
i.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK));
context.sendOrderedBroadcast(i, null);
I have tested this on Android Versions from 2.2 to 4.2.2. I have not seen a SecurityException broadcasting "Intent.ACTION_MEDIA_BUTTON" in my testing n a 4.2.2 device, nor have I seen crash reports from the Play Store indicating such exceptions are occurring.
I will say that this does not always work. It does not work on HTC devices due to the fact that HTC devices have a HeadsetObeserver that listen for the actually plugging in of a wired headset. Without this event, which it is currently a SecurityException for a third party app to broadcast, the HeadsetHook KeyEvent goes ignored.
The previous answers are misleading. The following code block does nothing:
Intent headSetUnPluggedintent = new Intent(Intent.ACTION_HEADSET_PLUG);
headSetUnPluggedintent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
headSetUnPluggedintent.putExtra("state", 0);
headSetUnPluggedintent.putExtra("name", "Headset");
try {
sendOrderedBroadcast(headSetUnPluggedintent, null);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
except generate a SecurityException and catch it.
In the other answers where the code works, it is because of the KeyEvent.KEYCODE_HEADSETHOOK being broadcast.
Try this Answer for end the call using pro grammatically. Its working fine for me.
try {
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);
}
This works from Android 2.2 to 4.0 and now after adding the try catch to the last line it works for 4.1.2 and 4.2 Frankly speaking dont know how it works but it works for me.
Log.d(tag, "InSecond Method Ans Call");
// froyo and beyond trigger on buttonUp instead of buttonDown
Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);
buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED");
Intent headSetUnPluggedintent = new Intent(Intent.ACTION_HEADSET_PLUG);
headSetUnPluggedintent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
headSetUnPluggedintent.putExtra("state", 0);
headSetUnPluggedintent.putExtra("name", "Headset");
try {
sendOrderedBroadcast(headSetUnPluggedintent, null);
} catch (Exception e) {
e.printStackTrace();
}
This is working for me in Android 4.1.2 as well as i have tested on 4.2 This still gives an exception which is handled.
Edit for End Call
Hope this helps all the people looking for total solution for answer and end call.
/**
* Reject button click listener will reject the incoming call.
*/
private class RejectCallOnClickListener implements OnClickListener {
@Override
public void onClick(View v) {
Log.d(tag, "OnRejectButton: " + "Reject OnClick");
ignoreCall();
exitCleanly();
}
}
/**
* ignore incoming calls
*/
private void ignoreCall() {
if (USE_ITELEPHONY)
ignoreCallAidl();
else
ignoreCallPackageRestart();
}
/**
* AIDL/ITelephony technique for ignoring calls
*/
private void ignoreCallAidl() {
try {
// telephonyService.silenceRinger();
telephonyService.endCall();
} catch (RemoteException e) {
e.printStackTrace();
Log.d(tag, "ignoreCall: " + "Error: " + e.getMessage());
} catch (Exception e) {
e.printStackTrace();
Log.d(tag, "ignoreCall" + "Error: " + e.getMessage());
}
}
/**
* package restart technique for ignoring calls
*/
private void ignoreCallPackageRestart() {
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
am.restartPackage("com.android.providers.telephony");
am.restartPackage("com.android.phone");
}
/**
* cleanup and exit routine
*/
private void exitCleanly() {
unHookReceiver();
this.finish();
}