android - 如何特别在设备 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;
}
我还遇到TelecomManager.endCall
了在 API 级别 28 中引入的新 API。它适用于 P beta 设备。
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 以后的所有版本。
解决方案
这是我存档的方法,也适用于 android P 版本。首先。
清单权限:
<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" />
现在在大于 21 的 API 上也要求用户在代码中给予运行时权限。如果低于奥利奥然后这样问。
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.READ_PHONE_STATE},REQUEST_CONTACTS);
但如果大于奥利奥那么。
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();
}
}}
推荐阅读
- php - 使用 phpseclib SCP 下载二进制文件的问题
- json - 如何使用播放框架在 Json 中转换响应体
- c++ - 为什么从向量构建一个集合是 O(N)
- ffmpeg - 来自原始视频流的 FFMPEG 持续时间不正确
- database - MongoDB跨ID数组加入
- html - 如何在按钮单击时在 jquery 中创建多个引导卡
- javascript - 如何从多个输入类型 =“文件”中删除某些文件?
- docker - 将 prometheus 数据挂载到主机卷 /mnt/resources/
- python - 在 python 中创建简单的 tar.gz 时会创建嵌套的 tar
- javascript - 使用提示中的值作为 highcharts 导出文件名