ITelephony.endCall()不再可用于阻止Android 8 / Android O / API 26中的呼叫

Bja*_*sen 6 android android-8.0-oreo

我有一个使用以下代码阻止呼叫的应用程序:

TelephonyManager telephonyManager = 
    (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

try {
    Class<?> telephonyManagerClass = 
        Class.forName(telephonyManager.getClass().getName());
    Method getITelephonyMethod = 
        telephonyManagerClass.getDeclaredMethod("getITelephony");
    getITelephonyMethod.setAccessible(true);
    Object iTelephony = getITelephonyMethod.invoke(telephonyManager);
    Class<?> iTelephonyClass = Class.forName(iTelephony.getClass().getName());
    Method endCallMethod = iTelephonyClass.getDeclaredMethod("endCall");
    endCallMethod.setAccessible(true);
    endCallMethod.invoke(iTelephony);
} catch (ClassNotFoundException e) {
    // ClassNotFoundException
} catch (NoSuchMethodException e) {
    // NoSuchMethodException
} catch (IllegalAccessException e) {
    // IllegalAccessException
} catch (InvocationTargetException e) {
    // InvocationTargetException
} catch (Exception e) {
    // Some other exception
}
Run Code Online (Sandbox Code Playgroud)

要工作,这需要AndroidManifest.xml中的android.permission.MODIFY_PHONE_STATE。在Android M和N中,我还必须询问用户权限Manifest.permission.CALL_PHONE。

但现在在Android 8 / Android O中,以上代码因InvocationTargetException而失败:需要MODIFY_PHONE_STATE权限

我发现了以下与此相关的StackOverflow帖子:Android-为什么endCall方法有效,但是answerRingingCall不起作用?

在这里建议我可以在PhoneInterfaceManager上使用反射(而不是像上面所做的ITelephony一样),并在end call命令中使用私有方法sendRequestAsync(int命令),并通过这样做来解决安全问题在endCall()方法中。

有没有人尝试过这样的事情?可能吗?我什至将如何获得PhoneInterfaceManager对象/类而不是ITelephony?

我认为这是有问题的源代码:https : //android.googlesource.com/platform/packages/services/Telephony/+/oreo-release/src/com/android/phone/PhoneInterfaceManager.java

结束通话时,我和Android N的代码之间看不到任何区别,所以我可能会误会:https : //android.googlesource.com/platform/packages/services/Telephony/+/nougat-发布/src/com/android/phone/PhoneInterfaceManager.java

Bja*_*sen 2

感谢 Nikola Bre\xc5\xbenjak\ 的博客,我找到了答案:https ://dev.to/hitman666/how-to-make-a-native-android-app-that-c​​an-block-phone-呼叫--4e15

\n\n

基本上,您需要在项目中包含 ITelephony 接口。使用以下代码创建文件 ITelephony.class(保留命名空间):

\n\n
package com.android.internal.telephony;\n\npublic interface ITelephony {\n    boolean endCall();\n    void answerRingingCall();\n    void silenceRinger();\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后在您的代码中使用以下代码结束电话:

\n\n
// This is only useful on Android O and older\n// Needs permission CALL_PHONE\nif (Build.VERSION.SDK_INT > Build.VERSION_CODES.O\n    || checkSelfPermission(Manifest.permission.CALL_PHONE)\n        == PackageManager.PERMISSION_DENIED) {\n    return;\n}\n\ntry {\n    ITelephony telephonyService;\n\n    TelephonyManager telephonyManager = (TelephonyManager)\n            getSystemService(Context.TELEPHONY_SERVICE);\n\n    Method getITelephony = telephonyManager\n            .getClass()\n            .getDeclaredMethod("getITelephony");\n\n    getITelephony.setAccessible(true);\n\n    telephonyService = (ITelephony) getITelephony.invoke(telephonyManager);\n\n    telephonyService.endCall();\n\n} catch (Exception ignored) {\n}\n
Run Code Online (Sandbox Code Playgroud)\n