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

时间:2018-06-08 11:52:41

标签: 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权限

我发现这个相关的StackOverflow帖子:Android - Why does endCall method work but answerRingingCall doesn't work?

这里建议我可以在PhoneInterfaceManager上使用反射(而不是像我上面所做的那样使用ITelephony)并使用私有方法sendRequestAsync(int命令)和end call命令,并通过这样做来解决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

1 个答案:

答案 0 :(得分:1)

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

基本上,您需要在项目中包括ITelephony界面。使用以下代码创建文件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) {
}