如何以编程方式在2.3+上结束呼叫?

11

在Android 2.2及以下版本中,我知道可以使用反射并通过 getITelephony 终止呼叫。

然而,在2.3及以上版本中,即使你向应用程序授予 MODIFY_PHONE_STATE 权限,它也已成为系统应用程序的专属权限: https://dev59.com/Um445IYBdhLWcg3wwcyg#5095956

尽管如此,仍有可能做到这一点,因为谷歌Play市场上的许多应用程序在ICS上运行得很好,例如这个应用程序:

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

所以问题是,他们是怎么做到的?我知道可以通过模拟耳机挂钩来接听电话,但是我无法想象如何结束通话。

谢谢。

3个回答

16

经过深思熟虑,我意识到了一件非常愚蠢的事情。好的一面是,在StackOverflow上似乎没有人注意到这一点。自从2.3版本以来,MODIFY_PHONE_STATE在静音铃声(silenceRinger())的功能上已经不再起作用了,但是endCall仍然可以正常使用。

因此,解决方案是注释掉对silenceRinger()的调用。

真不敢相信我刚刚花了一周的时间在这个问题上!我将尝试更新其他问题,因为在SO上似乎有很多重复的问题,比如“无法使用反射来终止通话了”。


你的意思是,我们仍然可以使用ITelephony.aidl技术编写程序来接受和拒绝呼叫,但它只是不能静音响铃?那么唯一的解决方案就是在aidl文件中注释掉silenceRinger吗?请建议,因为你的发现将使我能够在设计新应用程序时利用这种技术。 - omkar.ghaisas
在2.3.6上,通过iTelephony结束通话(endCall()),确实能够实现这个功能。问题的关键在于silenceRinger()会触发权限问题。你可以在实际代码中注释掉silenceRinger(),但是保留AIDL。我还没有在1.5到2.2上测试过这个问题,不过我很快就会去测试,并在此页面上告诉你结果。 - Stephan Tual
哇...我实际上在我的代码中已经有endCall(),但由于一些if语句,它并没有被执行。我只是假设它不起作用是因为API被禁用了。我想删除你的答案,这样谷歌就不会修复这个问题了!:) +1 - you786
endCall()会使铃声变为静音吗?我认为它也会... - hsanders
@Stephan Tual,您能否上传您的整个代码或发布可下载项目的链接? - Pro_Zeck
嗨@Pro_Zeck,很遗憾我无法做到这一点,因为我已经转行了。如果有一天我回到Android编程,我会将代码原封不动地推送到Git上。抱歉! - Stephan Tual

3

正如博客所述,它现在被封锁了。 - George

1
私有的 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();
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接