ITelephony.endCall () больше не работает для блокировки вызовов в Android 8 / Android O / API 26 - PullRequest
0 голосов
/ 08 июня 2018

У меня есть приложение, которое использует следующий код для блокировки вызовов:

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
}

Для работы требуется android.permission.MODIFY_PHONE_STATE в AndroidManifest.xml.В Android M и N мне также пришлось запросить у пользователя разрешение Manifest.permission.CALL_PHONE.

Но теперь в Android 8 / Android O вышеприведенный код завершается ошибкой с InvocationTargetException: требуется разрешение MODIFY_PHONE_STATE

Я нашел этот связанный пост StackOverflow: Android - почему метод endCall работает, но answerRingingCall не работает?

Здесь предлагается использовать отражение в 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 голосов
/ 06 мая 2019

Благодаря блогу Николы Брежняка я нашел ответ: 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) {
}
...