Подтвердить что ты не робот

Завершить вызов в android программно

Я вижу много вопросов, которые невозможно завершить программным способом в Android. В то же время, я вижу множество приложений для набора номера на рынке googleplay, где вы можете активировать вызов и отбросить его. Как они работают?

Изменить. Я где-то читал, что мое приложение должно быть системным приложением. Затем, как сделать его системой, и в чем разница между системными и пользовательскими приложениями?

4b9b3361

Ответ 1

Вам не нужно быть системным приложением. Сначала создайте пакет com.android.internal.telephony в своем проекте и поместите его в файл с именем " ITelephony.aidl ":

package com.android.internal.telephony; 

interface ITelephony {      

boolean endCall();     

void answerRingingCall();      

void silenceRinger(); 

}

Как только у вас есть это, вы можете использовать этот код для завершения вызова:

TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
Class clazz = Class.forName(telephonyManager.getClass().getName());
Method method = clazz.getDeclaredMethod("getITelephony");
method.setAccessible(true);
ITelephony telephonyService = (ITelephony) method.invoke(telephonyManager);
telephonyService.endCall();

Вы можете использовать это внутри PhoneStateListener, например. Чтобы это работало, вам необходимы разрешения в манифесте:

<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

Редактировать: извинения за ужасное форматирование, я до сих пор не могу понять, как правильно делать блоки кода здесь:/

Ответ 2

Для Android P (начиная с бета-версии 2) и выше, наконец, существует формальный API для endCall:

https://developer.android.com/reference/android/telecom/TelecomManager#endCall()

Разрешение ANSWER_PHONE_CALLS требуется в манифесте:

<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />

С разрешения, для уровня API 28 или выше:

TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);

if (tm != null) {
    boolean success = tm.endCall();
    // success == true if call was terminated.
}

В то же время оригинальный endCall() в TelephonyManager теперь защищен разрешением MODIFY_PHONE_STATE и больше не может вызываться несистемными приложениями путем отражения без разрешения (в противном случае будет вызвано исключение безопасности).

Ответ 3

Наряду с добавлением интерфейса телефонии android и широковещательного приемника вам также потребуется добавить запись приемника манифеста android с действием android.intent.action.PHONE_STATE для приемника, с которым вы хотите справиться с намерением.

Вы получите ошибку времени компиляции, если вы добавите

uses-permission android:name="android.permission.MODIFY_PHONE_STATE`

в файле манифеста. Но даже если мы удалим это, он автоматически отклонит входящие вызовы.

Ответ 4

Для информации.

Может быть полезным в некоторых ситуациях. Существует потенциальный обходной путь с использованием класса InCallService. Большая часть необходимой информации здесь. https://developer.android.com/reference/android/telecom/InCallService.html#onCallRemoved(android.telecom.Call)

Это требует настройки вашего приложения в качестве телефонного приложения по умолчанию и обеспечения следующего.

<uses-permission android:name="android.permission.CALL_PHONE" />

Если вы реализуете свой собственный класс, расширяющий InCallService то, когда вызов начинается, он привязывается к вашему приложению, и вы получаете информацию о вызове через onCallAdded(). Затем вы можете просто call.disconnect() и вызов закончится.

Ответ 5

SilenceRinger() не работает для версий Android 2.3+. Просто прокомментируйте это, другой код будет работать нормально. Надеюсь, это сработает для вас!

Ответ 6

public static boolean isCallActive(Context context){
    AudioManager manager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
    if(manager.getMode()==AudioManager.MODE_IN_CALL || manager.getMode()==AudioManager.MODE_IN_COMMUNICATION){
        return true;
    }

    return false;
}

Ответ 7

To end call in older version then 9.0
use this:


        TelephonyManager tm = (TelephonyManager)context.getSystemService(TELEPHONY_SERVICE);

        Method m1 = null;
        try {
            m1 = tm.getClass().getDeclaredMethod("getITelephony");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        m1.setAccessible(true);
        Object iTelephony = null;
        try {
            iTelephony = m1.invoke(tm);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        Method m3 = null;
        try {
            m3 = iTelephony.getClass().getDeclaredMethod("endCall");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        try {
            m3.invoke(iTelephony);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

& for pie

 TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
            if (telecomManager != null) {
                return telecomManager.endCall();
            }

Make sure your compile SDK version is 28

Ответ 8

Просто чтобы добавить в ответ @headuck. Для API 28 вам также необходимо добавить:

<uses-permission android:name="android.permission.READ_CALL_LOG"/>

затем запросите разрешение в вашей деятельности. В общей сложности я запросил эти разрешения, чтобы он работал (READ_PHONE_STATE, CALL_PHONE, ANSWER_PHONE_CALLS, READ_CONTACTS, READ_CALL_LOG)