Как завершить входящий телефонный звонок программно специально на устройствах уровня API 25,26,27
Я работаю над приложением для Android, где я перехватываю входящий телефонный звонок и завершаю его программным способом при каких-либо действиях пользователя. Для достижения этого использовали ITelephony.endCall
,
Эта реализация работает нормально только до уровня API 24.
private void rejectCallViaTelephonyManager() {
ITelephony telephonyService = getTelephonyService();
if (telephonyService != null) {
telephonyService.endCall();
}
}
private ITelephony getTelephonyService() {
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
return (ITelephony) m.invoke(tm);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Я тоже наткнулся на новый API TelecomManager.endCall
который был введен в API уровня 28. который отлично работает для P бета-устройства.
private void rejectCall() {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P /* 28 */) {
TelecomManager manager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
if (manager != null) {
// complains required API app requires API level 28 (current min is 21).
manager.endCall();
}
} else {
rejectCallViaTelephonyManager();
}
Log.d(TAG, "call ended successfully.");
} catch (Exception e) {
e.printStackTrace();
}
}
Сейчас я ищу решение, чтобы оно работало и для уровня API 25,26,27.
Есть идеи, как мы можем это сделать?
Моя цель состоит в том, чтобы функциональность "завершения входящего телефонного звонка" работала для всех версий API уровня 21 и выше.
1 ответ
Вот как я это заархивировал, а также работаю на Android P версии. Прежде всего.
Манифест Permissions:
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS"/>
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.PROCESS_INCOMING_CALLS" />
<uses-permission
android:name="android.permission.MODIFY_PHONE_STATE"
tools:ignore="ProtectedPermissions" />
Теперь в API больше 21 попросите пользователей дать права на выполнение в коде. если ниже, чем Oreo, спросите, как это.
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.READ_PHONE_STATE},REQUEST_CONTACTS);
Но если больше, чем Oreo, то.
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.ANSWER_PHONE_CALLS,Manifest.permission.READ_PHONE_STATE,Manifest.permission.READ_CALL_LOG},REQUEST_CONTACTS);
Теперь создайте полный пакет в вашем приложении, как это.
com.android.internal.telephony
В этом пакете поместите этот интерфейс.
package com.android.internal.telephony;
public interface ITelephony {
boolean endCall();
void answerRingingCall();
void silenceRinger();
}
Теперь закончите звонок вот так.
private void endCall(){
ITelephony telephonyService;
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (tm == null)
return;
try {
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(tm);
} catch (Exception e) {
e.printStackTrace();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
if (telecomManager != null) {
telecomManager.endCall();
}
} else {
if (telephonyService != null) {
telephonyService.silenceRinger();
telephonyService.endCall();
}
}}