How do you programmatically end a call on 2.3+?
Asked Answered
D

3

11

Up to Android 2.2 I know I can use reflection and terminate the call through getITelephony.

However, as of 2.3 this no longer works because even if you grant the MODIFY_PHONE_STATE permission to your app, it's now a system app only permission: https://mcmap.net/q/358768/-how-to-grant-modify_phone_state-permission-for-apps-ran-on-gingerbread

That said, it's possible still because a myriad of applications on the google play market are doing it just fine on ICS, for example, this one:

https://play.google.com/store/apps/details?id=com.androminigsm.fscifree&hl=en

So the question is, how do they do it? I know I can pick up the call using simulating a headset hook, but I can't figure out how to end the call.

Thank you.

Dalhousie answered 7/4, 2012 at 12:9 Comment(0)
D
16

Well after much soul-searching I realize something really, really, really dumb. On the plus side no one on StackOverflow seems to have noticed it either. MODIFY_PHONE_STATE is no longer working on silenceRinger() since 2.3+, but endCall is just fine.

So the solution is to comment out the call to silenceRinger().

Can't believe I've just spent a week on this! I'll try to update the other questions as there seem to be tons of dupe on SO along the lines of 'it's not possible to use reflection to terminate the calls anymore'.

Dalhousie answered 7/4, 2012 at 21:17 Comment(6)
You mean, we can stil use the ITelephony.aidl technique to accept and reject calls programatically but it only doesn't work for silenceRinger ? Then the only solution remains is to comment the silenceRinger in the aidl file ? Pls suggest, as your discovery on this would allow me to utilise this technique in designing a new app.Valente
On 2.3.6, endCall() through iTelephony does just that. It's indeed silenceRinger() that triggers the permission issue. You can just comment silenceRinger() in your actual code, leave the AIDL as such. I haven't tested this on 1.5 to 2.2, am about to do so soon though. Will let you know on this page.Dalhousie
Wow... I was actually had endCall() in my code, but it wasn't getting hit because of some if-statements. I just assumed it wasn't working because the API was disabled. I'm tempted to flag your answer for deletion so Google doesn't fix this issue! :) +1Chifley
Will endCall() cause the ringer to become silent? I would think it would as well...Ewart
@ stephan Tual Can you upload your whole code or post a link of you downloadable projectCapita
Hi @Pro_Zeck, unfortunately I'm not in a position to do this as I've moved on to pastures new. If one day I get back to android programming I'll push something on Git as-is. Sorry!Dalhousie
H
3

The call() , endcall() functions work fine for me as well. But there is also another way tha works without using iTelephony.aidl. Its published in this post. BTW I think google already knows but for some reason they havent done anything with the rest of functions, wich is good!!!

http://androidbridge.blogspot.com/2011/05/how-to-answer-incoming-call-in-android.html

Huberthuberto answered 28/7, 2012 at 20:20 Comment(1)
As the blog states, it is now blocked.Retinue
J
1

private void endCall(final String cutofftime) {

TelephonyManager telephony = (TelephonyManager) srvs
            .getSystemService(Context.TELEPHONY_SERVICE);
    Class c;
    final com.android.internal.telephony.ITelephony telephonyService;
    try {
        c = Class.forName("android.telephony.TelephonyManager");//telephony.getClass().getName());
        Log.i("TelephonyClass Name", telephony.getClass().getName());
        Method m = c.getDeclaredMethod("getITelephony");
        m.setAccessible(true);
        telephonyService = (ITelephony) m.invoke(telephony);
        TimerTask task = new TimerTask() {

            @Override
            public void run() {
                try {
                    if (telephonyService.isIdle()
                            || telephonyService.isOffhook()
                            || telephonyService.isRinging())
                        telephonyService.endCall();
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        long delay = Integer.parseInt(cutofftime) * 1000;
        new Timer().schedule(task, delay);
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
Jeremyjerez answered 13/1, 2014 at 10:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.