Android去电监听

项目要实现的功能:1 按下设备上的按钮后自动拨号   2 拨号中、通话中显示自定义界面

1  按下按钮自动拨号?当时就懵逼了,我怎么监听硬件上的点击事件,网上一查,GPIO是什么鬼,没办法网上各种翻找,什么设置输出、输入、高电平、低电平、IO口、索引值,慢慢弄明白了一些,可问题是不同的厂商提供的板子索引值什么的不同啊,没办法,只能应用里面switch case 一个一个适配了

2  去电监听,刚开始也是各种查找,各种失败,只能一步一步来了,当然前提是打系统签名包:步骤如下

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package=""
    android:sharedUserId="android.uid.system"> //添加系统权限

下载signapk.jar ,platform.pk8,platform.x509.pem这3个文件放在同目录下

java -jar signapk.jar platform.x509.pem platform.pk8 old.apk new.apk

cmd cd到目录下 执行java -jar signapk.jar platform.x509.pem platform.pk8 old.apk new.apk 

platform.pk8,platform.x509.pem这两个文件我用的是设备厂商提供的,不是Android原生的,不同版本,不同厂商可能会不同,这个需要问下各自厂商,当然了,如果你们公司牛掰,你可以自己定制这两个文件,让设备厂商统一使用你们的

继续:

首先开机自启动

public class BootBroadCast extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent == null)
            return;
        LogUtil.e(intent.getAction());
        //开机监听 自启动Service
        if (TextUtils.equals(intent.getAction(), Constant.ACTION_BOOT)) {
            Intent it = new Intent(context, PhoneService.class);
            context.startService(it);         
        }

        //关机监听 停止录像
        if (TextUtils.equals(intent.getAction(),Constant.ACTION_SHUTDOWN)){
            EventBus.getDefault().post(new Msg(Constant.STOP_RECORD));
        }
    }
}

去源码里下载相应的AIDL文件,结构如下,包名必须是这样的不能更改

     监听到GPIO事件后开始拨号

try {
            LogUtil.e("自动拨号");
            Class<TelephonyManager> managerClass = TelephonyManager.class;//得到TelephonyManager的Class对象
            Method getITelephony = managerClass.getDeclaredMethod("getITelephony", (Class[]) null);
            //打开权限
            getITelephony.setAccessible(true);
            //得到TelephonyManager对象
            TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            //得到ITelephony对象,进行所需要的操作
            ITelephony iTelephony = (ITelephony) getITelephony.invoke(manager, (Object[]) null);

            //打电话
            iTelephony.call(context.getPackageName(), "被拨打的号码");

//            Thread.sleep(1500);
//            context.startActivity(new Intent(context, MainActivity.class));
        } catch (Exception e) {
            e.printStackTrace();
        }

     定义广播监听电话状态

public class PhoneCallReciver extends BroadcastReceiver {
private static final String ACTION_CALL_PHONE = "android.intent.action.NEW_OUTGOING_CALL";
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent == null)
            return;
        if (TextUtils.equals(Constant.ACTION_CALL_PHONE, intent.getAction())) {
            LogUtil.e(intent.getAction());
//            Intent it=new Intent(context,MainActivity.class);
//            it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//            context.startActivity(it);
            EventBus.getDefault().post(new Msg(Constant.DIALING));//进入拨号页面
              //实时抓取log
            AppUtil.getInCallLog("logcat -s Telecom");

        }
//        if (TextUtils.equals(Constant.ACTION_STATE, intent.getAction())) {
//            TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
//            LogUtil.e(manager.getCallState());
//            switch (manager.getCallState()) {
                      //来电
//                case TelephonyManager.CALL_STATE_RINGING: 
//                    break;
                      //来电通话中
//                case TelephonyManager.CALL_STATE_OFFHOOK:
//                    break;
                  //本来想在这里监听挂断状态的,结果不行
//                case TelephonyManager.CALL_STATE_IDLE:
//                    PhoneService.current_click = 0;
//                    EventBus.getDefault().post(new Msg(Constant.END_CALL));
//                    break;
//            }
//        }
    }
}
 public static void getInCallLog(final String cmd) {
//抓取log日志 过滤刷选出Telecom字段
        new Thread(new Runnable() {
            @Override
            public void run() {
                Process pro = null;
                BufferedReader bufferedReader = null;
                try {
//                    String[] running = new String[]{"logcat", "|find", "NEW_OUTGOING_CALL"};
                    pro = Runtime.getRuntime().exec(cmd);
                    bufferedReader = new BufferedReader(new InputStreamReader(
                            pro.getInputStream()));

                    //筛选需要的字串
//                String strFilter = " CallList - onUpdate - [Call_";
//                String active = "ACTIVE, [Capabilities: CAPABILITY_HOLD CAPABILITY_SUPPORT_HOLD CAPABILITY_MUTE CAPABILITY_CANNOT_DOWNGRADE_VIDEO_TO_AUDIO]";
//                    String strFilter = "CallsManager:setCallState:";
                    String dialing = "CallsManager: setCallState DIALING -> DIALING";
                    String dialing_active = "CallsManager: setCallState DIALING -> ACTIVE";
                    String active_disconnect = "CallsManager: setCallState ACTIVE -> DISCONNECTED";
                    String dialing_disconnect = "CallsManager: setCallState DIALING -> DISCONNECTED";
                    String removed = "InCallController: onCallRemoved";
                    String line = null;
                    while ((line = bufferedReader.readLine()) != null) {

//                        if (line.contains(dialing)) {//拨号中
//                            EventBus.getDefault().post(new Msg(Constant.DIALING));
//                        }
                        if (line.contains(dialing_active)) {//通话中
                            LogUtil.e(line);
                            EventBus.getDefault().post(new Msg(Constant.CALLING));
//                            getInCallLog("logcat -c");
//                            break;
                        }
//                        if (line.contains(active_disconnect) || line.contains(dialing_disconnect)) {//通话结束
//                            EventBus.getDefault().post(new Msg(Constant.END_CALL));
//                            break;
//                        }
                        if (line.contains(removed)) {//通话结束
                            LogUtil.e(line);
                            EventBus.getDefault().post(new Msg(Constant.END_CALL));
   //                         clearLog("logcat -c");
                            break;
                        }
                    }
                    pro.waitFor();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (pro != null) {
                            pro.destroy();
                            pro = null;
                        }
                        if (bufferedReader != null) {
                            bufferedReader.close();
                            bufferedReader = null;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }
        }).start();
    }

清除日志缓存

public static void clearLog() {
    Process pro = null;
    try {
        pro = Runtime.getRuntime().exec("logcat -b all -c");
        pro.waitFor();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (pro != null) {
            pro.destroy();
            pro = null;
        }
    }
}

   然而还是存在问题,显示自定义正在拨号界面后会弹出系统拨号界面,刚开始想到的是监听到正在拨号后,延时显示自定义界面,后面想有没有办法禁用系统电话app,解决如下

 public static void forbidSysApp(Context context, String pkgName) {
//将APP或组件设置为manifest定义的状态。
//        COMPONENT_ENABLED_STATE_DEFAULT,
        //启用APP或组件,忽略manifest的定义。
//                COMPONENT_ENABLED_STATE_ENABLED,
        //禁用APP或组件,忽略manifest的定义。
//                COMPONENT_ENABLED_STATE_DISABLED,
        //以用户身份禁用APP,忽略manifest的定义。不能用于组件操作。
//                COMPONENT_ENABLED_STATE_DISABLED_USER,
        //禁用APP直到用户想用才出现。也就是说,正常情况下,用户看不到(比如在Launcher上);但是特殊情况下,用户还是能看到并选择到(比如输入法APP)。不能用于组件操作。
//                COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
        PackageManager pm = context.getPackageManager();
        //禁止系统电话应用运行
       pm.setApplicationEnabledSetting(pkgName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER, 0);
      //启用系统电话应用
      //pm.setApplicationEnabledSetting(pkgName, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0);
    }

好,打系统签名包,adb push 进 /system/app ,再adb reboot

测试正常,可是连续多测几次后界面出现错乱,发现LogUtil.e(line)输出的还是上一次的通话信息,然后不断logcat -b all -c , logcat -s Telecom发现日志缓存存在2分钟左右才清空,每次挂断后,等2分钟左右再测试都是正常的,找不到原因为什么日志缓存没有实时清除    

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

雕·不懒惰

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值