Android ITelephony EndCall Remove 各版本挂断拦截电话方法
Posted 清霜之辰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android ITelephony EndCall Remove 各版本挂断拦截电话方法相关的知识,希望对你有一定的参考价值。
本文首发地址:https://blog.csdn.net/CSqingchen/article/details/121426660
最新更新地址:https://gitee.com/chenjim/chenjimblog
在 ITelephony.aidl 8.0 源码 、9.0 源码 中存在 endCall()
接口
在 10 源码 中,已经没有 endCall()
接口
在 android 10 之前可以通过如下方式 挂断 电话
//详细 参见 https://www.jianshu.com/p/a5662fad84b5
public void endCall()
try
//1.通过类加载器加载相应类的class文件
//Class<?> forName = Class.forName("android.os.ServiceManager");
Class<?> loadClass = getClassLoader().loadClass("android.os.ServiceManager");
//2.获取类中相应的方法
//name : 方法名
//parameterTypes : 参数类型
Method method = loadClass.getDeclaredMethod("getService", String.class);
//3.执行方法,获取返回值
//receiver : 类的实例
//args : 具体的参数
IBinder invoke = (IBinder) method.invoke(null, Context.TELEPHONY_SERVICE);
//aidl
ITelephony iTelephony = ITelephony.Stub.asInterface(invoke);
//挂断电话
iTelephony.endCall();
catch (Exception e)
e.printStackTrace();
那 Android 10 如何挂断电话呢?
在 TelephonyManager.java 9.0 源码 我们可以看到如下,也就是前面实现挂断电话的 framework 原理
@SystemApi
@RequiresPermission(android.Manifest.permission.CALL_PHONE)
public boolean endCall()
try
ITelephony telephony = getITelephony();
if (telephony != null)
return telephony.endCall();
catch (RemoteException e)
Log.e(TAG, "Error calling ITelephony#endCall", e);
return false;
...
private ITelephony getITelephony()
return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
在 TelephonyManager.java 10.0 源码 中我们可以看到如下
/**
* @removed Use @link android.telecom.TelecomManager#endCall() instead.
* @hide
* @removed
*/
@Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.CALL_PHONE)
public boolean endCall()
return false;
是不是可以使用 android.telecom.TelecomManager#endCall()
呢 ?
看下 TelecomManager.java 源码 9.0 、 10.0,可以看到如下
@RequiresPermission(Manifest.permission.ANSWER_PHONE_CALLS)
@Deprecated
public boolean endCall()
try
if (isServiceConnected())
return getTelecomService().endCall(mContext.getPackageName());
catch (RemoteException e)
Log.e(TAG, "Error calling ITelecomService#endCall", e);
return false;
所以问题不大了,最终代码如下
AndroidManifest.xml 需 添加以下权限
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
//保持 前面 ITelephony.aidl 包名相对路径复制到 应用代码
//注意动态申请权限(Permission.ANSWER_PHONE_CALLS)
private fun endCallAction()
try
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
val tcm = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
tcm.endCall()
else
val loadClass: Class<*> =
javaClass.classLoader.loadClass("android.os.ServiceManager")
val method: Method = loadClass.getDeclaredMethod("getService", String::class.java)
//这里也可以直接用 context.getSystemService(Context.TELEPHONY_SERVICE ) as TelephonyManager
//注意 TELECOM* 和 TELEPHONY* 区别
val invoke: IBinder = method.invoke(null, Context.TELEPHONY_SERVICE) as IBinder
val iTelephony: ITelephony = ITelephony.Stub.asInterface(invoke)
iTelephony.endCall()
catch (e: Exception)
e.printStackTrace()
这就完了,还没有,我们再看下 TelecomManager.java 中 endcall 注释
* @deprecated Companion apps for wearable devices should use the @link InCallService API
* instead. Apps performing call screening should use the @link CallScreeningService API instead.
*/
@RequiresPermission(Manifest.permission.ANSWER_PHONE_CALLS)
@Deprecated
public boolean endCall() ...
@Deprecated @Deprecated @Deprecated
也就是将来也可能会移除,那时怎么做呢?
上面注释中看到可穿戴设备用 InCallService
, 其它APP用 CallScreeningService
我们看下 InCallService.java 10.0 源码 和 CallScreeningService.java 10.0 源码
哇,类注释都非常详细,需要时参考下就好,本文暂时结束。
以上是关于Android ITelephony EndCall Remove 各版本挂断拦截电话方法的主要内容,如果未能解决你的问题,请参考以下文章
Android ITelephony EndCall Remove 各版本挂断拦截电话方法
Android ITelephony EndCall Remove 各版本挂断拦截电话方法
android 自动拨打电话和挂断电话(反射和intent方式)