Android 四大组件之 Service_4_挂断电话(AIDL)

App 可以通过调用当前系统的接口, 进行挂断电话,但是需要对应的权限。

根据SDK 版本有不同的方式。

方式1: android skd < 28 , 使用反射调用 Telephony.endCall

参考: https://stackoverflow.com/questions/24580508/how-to-import-com-android-internal-telephony-itelephony-to-the-android-application

(1) 创建一个和系统ITelephony包名一样的包: com.android.internal.telephony,

(2) 创建  ITelephony.aidl 文件

// ITelephony.aidl
package com.android.internal.telephony;

// Declare any non-default types here with import statements

interface ITelephony {
    boolean endCall();
}

(3) 通过反射调用 

- 获取ServiceManager的类对象 :   c = Class.forName("android.os.ServiceManager");

- 获取getService的Method对象: method = c.getMethod("getService", String.class);

- 调用方法获取远程服务即Telephony对应的 IBinder对象 :   iBinder = (IBinder) method.invoke(null, TELEPHONY_SERVICE);

- 根据IBinder对象获取服务端接口对象 ITelephony:    telephony = ITelephony.Stub.asInterface(iBinder)

- 结束通话调用:  telephony.endCall();

完整代码如下:

    private void endCallByTelephonyInterface() {
        // 通过反射,调用隐藏的api
        Class c = null;
        Method method = null;
        //1. 得到隐藏类的Class对象
        try {
            c = Class.forName("android.os.ServiceManager");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        if (c == null) {
            return;
        }

        //2. 得到方法所对用的Method对象
        try {
            method = c.getMethod("getService", String.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        if (method == null) {
            return;
        }

        IBinder iBinder = null;
        //3. 调用方法
        try {
            iBinder = (IBinder) method.invoke(null, TELEPHONY_SERVICE);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        if (iBinder == null) {
            return;
        }

        //4. 得到接口对象
        ITelephony telephony = ITelephony.Stub.asInterface(iBinder);
        //5. 结束通话
        try {
            telephony.endCall();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

并且需要以下权限:

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

方式2:android sdk =28 , 使用 TelecomManager.endCall

参考:https://www.codenong.com/cs106716569/
https://developer.android.com/reference/android/telecom/TelecomManager.html#endCall()

    private void endCallByTelecomManager() {
        log("endCallByTelecomManager");
        if (Build.VERSION.SDK_INT < 28) {
            log("endCallByTelecomManager return because sdk < 28");
            return;
        }
        if (this.checkSelfPermission(Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED) {
            TelecomManager manager = (TelecomManager) this.getSystemService(TELECOM_SERVICE);
            boolean ret = manager.endCall();
            log("endCallByTelecomManager endCall ret=" + ret);
        } else {
            log("endCallByTelecomManager do not grant ANSWER_PHONE_CALLS");
        }
    }

需要声明权限:  <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />

方式3:android sdk >=29,  使用 InCallService

待续...

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值