android - ITelephony.endCall() 不再适用于阻止 Android 8/Android O/API 26 中的调用

标签 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
}

要工作,这需要 AndroidManifest.xml 中的 android.permission.MODIFY_PHONE_STATE。在 Android M 和 N 中,我还必须向用户征求许可 Manifest.permission.CALL_PHONE。

但是现在在 Android 8/Android O 中,上面的代码失败并出现 InvocationTargetException: MODIFY_PHONE_STATE permission required

我找到了这篇相关的 StackOverflow 帖子:Android - Why does endCall method work but answerRingingCall doesn't work?

这里建议我可以在 PhoneInterfaceManager 上使用反射(而不是 ITelephony,就像我在上面所做的那样)并使用私有(private)方法 sendRequestAsync(int command) 和结束调用命令,并通过这样做绕过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-release/src/com/android/phone/PhoneInterfaceManager.java

最佳答案

感谢 Nikola Brežnjak 的博客,我找到了答案:https://dev.to/hitman666/how-to-make-a-native-android-app-that-can-block-phone-calls--4e15

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

package com.android.internal.telephony;

public interface ITelephony {
    boolean endCall();
    void answerRingingCall();
    void silenceRinger();
}

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

// This is only useful on Android O and older
// Needs permission CALL_PHONE
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O
    || checkSelfPermission(Manifest.permission.CALL_PHONE)
        == PackageManager.PERMISSION_DENIED) {
    return;
}

try {
    ITelephony telephonyService;

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

    Method getITelephony = telephonyManager
            .getClass()
            .getDeclaredMethod("getITelephony");

    getITelephony.setAccessible(true);

    telephonyService = (ITelephony) getITelephony.invoke(telephonyManager);

    telephonyService.endCall();

} catch (Exception ignored) {
}

关于android - ITelephony.endCall() 不再适用于阻止 Android 8/Android O/API 26 中的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50760074/

相关文章:

android - API 26 上的 SYSTEM_ALERT_WINDOW PERMISSION 未按预期工作。窗口类型 2002 的权限被拒绝

Android 8.0 Oreo 在聚焦 TextInputEditText 时崩溃

android-studio-3.0 - Android 键盘 (AOSP) 一直停止使用 Android O 模拟器

android - Picasso : want to cache a image without displaying it . 以便我以后可以使用它

Android 视频 Intent : Control back button?

android - 在自定义 ListView 中覆盖或添加单行

android - Android O 中的图标

android - 前台服务在 Android O 的打瞌睡模式下不接收位置更新

Android:获取对膨胀 View 的引用/为膨胀 View 设置唯一ID

android - 在 Google Play 上更新 Android 应用 - Android 开发者控制台