Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
AlekseyCyber
0 / 0 / 0
Регистрация: 30.01.2015
Сообщений: 14
#1

Блокировка входящего вызова

20.07.2016, 16:09. Просмотров 612. Ответов 3
Метки нет (Все метки)

Коллеги, всех приветствую!
Суть задачи, думаю, всем ясна из темы, собственно - описание текущей ситуации.
В одном из классов - назовем его N1 в методе onCreate(Bundle savedInstanceState):

Java
1
2
3
4
5
6
7
8
9
10
11
...
br = new BroadcastReceiver() {
 @Override
 public void onReceive(Context context, Intent intent) {
   TelephonyManager telephony = (TelephonyManager)  context.getSystemService(Context.TELEPHONY_SERVICE);
   CustomPhoneStateListener customPhoneListener = new [B]CustomPhoneStateListener[/B] (context);
   telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
 }
};
IntentFilter inf = new IntentFilter(Intent.ACTION_CALL);
registerReceiver(br, inf);
Выключение широковещательного приемника происходит сразу после этого же метода onCreate(Bundle savedInstanceState):

Java
1
2
3
4
5
6
7
8
@Override
protected void onDestroy() {
 super.onDestroy();
 PaymentFragment pf = new PaymentFragment();
 if(!pf.flagIbox) {
  unregisterReceiver(br);
 }
}
Класс CustomPhoneStateListener содержит код:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class CustomPhoneStateListener extends PhoneStateListener {
    Context context;
 
    public CustomPhoneStateListener(Context context) {
        super();
        this.context = context;
    }
 
    @Override
    public void onCallStateChanged(int state, String callingNumber)
    {
        super.onCallStateChanged(state, callingNumber);
        switch (state) {
            case TelephonyManager.CALL_STATE_IDLE:  //неактивен
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK: //вызов активен
                //handle out going call
                endCallIfBlocked(callingNumber);
                break;
            case TelephonyManager.CALL_STATE_RINGING:   //есть входящий
                //handle in coming call
                endCallIfBlocked(callingNumber);
                break;
            default:
                break;
        }
    }
 
    private void endCallIfBlocked(String callingNumber) {
        try {
 
            // Java reflection to gain access to TelephonyManager's
            // ITelephony getter
            TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            Class<?> c = Class.forName(tm.getClass().getName());
            Method m = c.getDeclaredMethod("getITelephony");
            m.setAccessible(true);
 
            ITelephony telephonyService = (ITelephony) m.invoke(tm);
 
            telephonyService.silenceRinger();
            telephonyService.endCall();
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Все бы неплохо, но вот только получаю сообщение об ошибке типа:
android.internal.ITelephony$Stub$Proxy cannot be cast to com...
Понимаю, что частично дело в строке:
Java
1
ITelephony telephonyService = (ITelephony) m.invoke(tm);
В примерах прописано:
Java
1
android.internal.telephony.ITelephony telephonyService = (ITelephony) m.invoke(tm);
Выходит, что в android.internal.telephony должен располагаться .java-файл? И, как кто-то пишет, это переименованный ITelephony.aidl...

В одном пакете с вышеуказанными файлами находится ITelephony.java с кодом:
Java
1
2
3
4
5
public interface ITelephony {
    boolean endCall();
    void answerRingingCall();
    void silenceRinger();
}
В пакете android.internal.telephony расположен файл ITelephony.aidl с кодом, который можно посмотреть на разных ресурсах.
Может, кто знает, как решить проблему?
Спасибо!

Добавлено через 13 часов 57 минут
Аналогичная проблема наблюдается у другого разработчика. Там обращают его внимание на файл proguard.cfg..

Добавлено через 46 минут
Здесь пишут, что необходимо исключить ITelephony из proguard.
Попробовал найти файл proguard.cfg в корне - не нашел. Пишут, что необходимо обновить Android SDK. Посмотрим..

Добавлено через 5 часов 3 минуты
К счастью для PM задача решена оперативно, к моему сожалению - другими методами. Озвученная проблема остается актуальной..
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.07.2016, 16:09
Ответы с готовыми решениями:

Как определить "переадресованность" входящего вызова
Доброго времени суток! Подскажите из какого свойства и каким образом можно...

Перехват входящего sms
Всем привет. Недавно начал изучение Android. Задача такая: при получении SMS...

Переадресация вызова
Товарищи, переадресацию средствами андроида сделать можно или это полностью...

Вызова метода по таймеру
Есть рабочий метод, реализовывающий изменение TextView по таймеру. Скопипастил...

Причина вызова onStop()
Здравствуйте! У меня короткий вопрос. Метод onStop() может вызваться при...

3
DarkVortex
103 / 69 / 19
Регистрация: 07.07.2014
Сообщений: 240
20.07.2016, 21:53 #2
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    private void BreakCall(){
        try {
            String serviceManagerName = "android.os.ServiceManager";
            String serviceManagerNativeName = "android.os.ServiceManagerNative";
            String telephonyName = "com.android.internal.telephony.ITelephony";
            Class<?> telephonyClass;
            Class<?> telephonyStubClass;
            Class<?> serviceManagerClass;
            Class<?> serviceManagerNativeClass;
            Method telephonyEndCall;
            Object telephonyObject;
            Object serviceManagerObject;
            telephonyClass = Class.forName(telephonyName);
            telephonyStubClass = telephonyClass.getClasses()[0];
            serviceManagerClass = Class.forName(serviceManagerName);
            serviceManagerNativeClass = Class.forName(serviceManagerNativeName);
            Method getService = // getDefaults[29];
            serviceManagerClass.getMethod("getService", String.class);
            Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class);
            Binder tmpBinder = new Binder();
            tmpBinder.attachInterface(null, "fake");
            serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder);
            IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone");
            Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class);
            telephonyObject = serviceMethod.invoke(null, retbinder);
            telephonyEndCall = telephonyClass.getMethod("endCall");
            telephonyEndCall.invoke(telephonyObject);
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
0
AlekseyCyber
0 / 0 / 0
Регистрация: 30.01.2015
Сообщений: 14
21.07.2016, 11:42  [ТС] #3
Спасибо, надо протестировать.

Добавлено через 6 минут
Честно говоря, использовал нечто подобное через рефлексию:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class CustomPhoneStateListener extends PhoneStateListener {
 
    Context context;
 
    private static boolean keyIn;
 
    public void setKeyIn(boolean newKeyIn) {
        keyIn = newKeyIn;
    }
 
    public CustomPhoneStateListener(Context context) {
        super();
        this.context = context;
    }
 
    @Override
    public void onCallStateChanged(int state, String callingNumber)
    {
        super.onCallStateChanged(state, callingNumber);
        switch (state) {
            case TelephonyManager.CALL_STATE_IDLE:
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK: 
                //handle out going call
                endCallIfBlocked(callingNumber);
                break;
            case TelephonyManager.CALL_STATE_RINGING:
                //handle in coming call
                endCallIfBlocked(callingNumber);
                break;
            default:
                break;
        }
    }
 
    private void endCallIfBlocked(String callingNumber) {
        try {
 
            // Java reflection to gain access to TelephonyManager's
            TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            Class<?> c = Class.forName(tm.getClass().getName());
            Method m = c.getDeclaredMethod("getITelephony");
 
            /* keyIn - если значение параметра равно false, блокировка не происходит;
            *  если true - происходит
            */
            m.setAccessible(keyIn);
 
            Object telephonyService = m.invoke(tm);
            Class<?> telephonyServiceClass = Class.forName(telephonyService.getClass().getName());
            Method endCallMethod = telephonyServiceClass.getDeclaredMethod("endCall");
            endCallMethod.invoke(telephonyService);
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Добавлено через 2 минуты
Ситуация осложнялась тем, что блокировка входящих вызовов должна происходить не всегда, а только в определенных активностях - в этом участвует глобальная переменная с булевыми значениями keyIn.

Добавлено через 2 минуты
Ее значение передается в:

Java
1
m.setAccessible(keyIn);
false - блокировка не происходит, true - блокировка происходит.
0
DarkVortex
103 / 69 / 19
Регистрация: 07.07.2014
Сообщений: 240
21.07.2016, 12:11 #4
Цитата Сообщение от AlekseyCyber Посмотреть сообщение
Спасибо, надо протестировать.
Честно говоря, это довольно давно использовал этот метод, и не могу сказать корректно ли он работает на android 5+, так что проверьте. Но работал он хорошо и вызывать его можно абсолютно из любого места.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.07.2016, 12:11

Совершение вызова из приложения
Добрый день! Вопрос такой, во втором активити необходимо принимать номер...

Неправильная периодичность вызова метода по таймеру
Есть необходимость запускать некую задачу в фоне по таймеру. Для этого я...

Метод вызова Activiti через ListView
Всем привет. Каким образом реализовать следующее: Любое значение списка...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru