博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 来去电自动录音 (二)
阅读量:6388 次
发布时间:2019-06-23

本文共 8432 字,大约阅读时间需要 28 分钟。

  hot3.png

 2、介绍完了来电自动录音,下面就来介绍去电自动录音的实现方法。上面说过,相比来电状态的监听,去电的要麻烦些,甚至这种方法不是通用的,这个主要是因为android api 中没有提供去电状态监听的相应类和方法(也许我刚接触,没有找到)。刚开始网上搜索了一通也没有找到对应的解决方法,大多是 来电监听的,也就是上面的方法。不过中途发现一篇博文(后来就搜不到了),记得是查询系统日志的方式,从中找到去电过程中的各个状态的关键词。无奈之中,最终妥协了此方法。

我的(联想A65上的)去电日志内容如下

过滤关键词为 mforeground

 
01-06 16:29:54.225: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING  01-06 16:29:54.245: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : DIALING  01-06 16:29:54.631: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING  01-06 16:29:54.645: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : DIALING  01-06 16:29:54.742: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING  01-06 16:29:54.766: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : DIALING  01-06 16:29:54.873: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING  01-06 16:29:54.877: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : DIALING  01-06 16:29:55.108: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING  01-06 16:29:55.125: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : DIALING  01-06 16:29:57.030: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE  01-06 16:29:57.155: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE  01-06 16:29:57.480: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE  01-06 16:29:57.598: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE  01-06 16:29:59.319: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DISCONNECTING  01-06 16:29:59.373: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : DISCONNECTING  01-06 16:30:00.392: D/InCallScreen(251): - onDisconnect: currentlyIdle:true ; mForegroundCall.getState():DISCONNECTED  01-06 16:30:00.399: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): - onDisconnect: currentlyIdle:true ; mForegroundCall.getState():DISCONNECTED  01-06 16:30:01.042: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : IDLE  01-06 16:30:01.070: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : IDLE  01-06 16:30:01.558: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : IDLE  01-06 16:30:01.572: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : IDLE 

 

过滤关键词  mbackground

 

 
01-06 16:29:54.226: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:54.256: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:54.638: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:54.652: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:54.743: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:54.770: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:54.875: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:54.882: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:55.109: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:55.142: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:57.031: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:57.160: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:57.481: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:57.622: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:59.319: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:29:59.373: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:30:01.042: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:30:01.070: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:30:01.559: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE  01-06 16:30:01.573: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE 

从上面的日志可以看到,每一行的末尾的大写英文词就是去电的状态,状态说明如下:

DIALING 拨号,对方还未响铃
ACTIVE   对方接通,通话建立
DISCONNECTING 通话断开时
DISCONNECTED  通话已断开,可以认为是挂机了
由于我拨打的是10010,没有响铃过程(电脑自动接通的够快),还少了一个状态,状态是ALERTING  这个就是对方正在响铃的状态
有了这几个去电状态就好办了,现在我们要做的就是读取系统日志,然后找到这些状态,提取的关键词就是上面提到的 mforeground(前台通话状态) 和 mbackground (后台通话状态)(可能不一样的设备生成的不一样,根据自己具体设备设置,这里只提取前台的),如果读取的这一行日志中 包含 mforground ,再看看是否包含上面的状态的 单词。既然说的如此,那么看看读取系统日志的代码吧
 

 
package com.sdvdxl.phonerecorder;    import java.io.BufferedReader;  import java.io.IOException;  import java.io.InputStream;  import java.io.InputStreamReader;    import com.sdvdxl.outgoingcall.OutgoingCallState;    import android.content.Context;  import android.content.Intent;  import android.util.Log;    /**   *    * @author sdvdxl   *  找到 日志中的   *  onPhoneStateChanged: mForegroundCall.getState() 这个是前台呼叫状态   *  mBackgroundCall.getState() 后台电话   *  若 是 DIALING 则是正在拨号,等待建立连接,但对方还没有响铃,   *  ALERTING 呼叫成功,即对方正在响铃,   *  若是 ACTIVE 则已经接通   *  若是 DISCONNECTED 则本号码呼叫已经挂断   *  若是 IDLE 则是处于 空闲状态   *     */  public class ReadLog extends Thread {      private Context ctx;      private int logCount;            private static final String TAG = "LogInfo OutGoing Call";            /**       *  前后台电话       * @author sdvdxl       *         */      private static class CallViewState {          public static final String FORE_GROUND_CALL_STATE = "mForeground";      }            /**       * 呼叫状态       * @author sdvdxl       *       */      private static class CallState {          public static final String DIALING = "DIALING";          public static final String ALERTING = "ALERTING";          public static final String ACTIVE = "ACTIVE";          public static final String IDLE = "IDLE";          public static final String DISCONNECTED = "DISCONNECTED";      }            public ReadLog(Context ctx) {          this.ctx = ctx;      }            /**       * 读取Log流       * 取得呼出状态的log       * 从而得到转换状态       */      @Override      public void run() {          Log.d(TAG, "开始读取日志记录");                    String[] catchParams = {
"logcat", "InCallScreen *:s"};          String[] clearParams = {
"logcat", "-c"};                    try {              Process process=Runtime.getRuntime().exec(catchParams);              InputStream is = process.getInputStream();              BufferedReader reader = new BufferedReader(new InputStreamReader(is));                            String line = null;              while ((line=reader.readLine())!=null) {                  logCount++;                  //输出所有              Log.v(TAG, line);                                    //日志超过512条就清理                  if (logCount>512) {                      //清理日志                      Runtime.getRuntime().exec(clearParams)                          .destroy();//销毁进程,释放资源                      logCount = 0;                      Log.v(TAG, "-----------清理日志---------------");                  }                                       /*---------------------------------前台呼叫-----------------------*/                  //空闲                  if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)                          && line.contains(ReadLog.CallState.IDLE)) {                      Log.d(TAG, ReadLog.CallState.IDLE);                  }                                    //正在拨号,等待建立连接,即已拨号,但对方还没有响铃,                  if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)                          && line.contains(ReadLog.CallState.DIALING)) {                      Log.d(TAG, ReadLog.CallState.DIALING);                  }                                    //呼叫对方 正在响铃                  if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)                          && line.contains(ReadLog.CallState.ALERTING)) {                      Log.d(TAG, ReadLog.CallState.ALERTING);                  }                                    //已接通,通话建立                  if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)                          && line.contains(ReadLog.CallState.ACTIVE)) {                      Log.d(TAG, ReadLog.CallState.ACTIVE);                  }                                    //断开连接,即挂机                  if (line.contains(ReadLog.CallViewState.FORE_GROUND_CALL_STATE)                          && line.contains(ReadLog.CallState.DISCONNECTED)) {                      Log.d(TAG, ReadLog.CallState.DISCONNECTED);                  }                                } //END while                        } catch (IOException e) {              e.printStackTrace();          } //END try-catch      } //END run  } //END class ReadLog 

         以上代码中,之所以用线程,是为了防止读取日志过程中阻滞主方法的其他方法的执行,影响到程序捕捉对应的电话状态。

       未完  

另附

本文出自 “” 博客,请务必保留此出处

转载于:https://my.oschina.net/pass/blog/777812

你可能感兴趣的文章
ACCESS模糊查询出现"内存溢出"原因是日文片假名
查看>>
Error setting expression 'XXX' with value 设置表达式“XXX”时出错 解决方法
查看>>
javascript获取url参数和script标签中获取url参数
查看>>
CF359D:Pair of Numbers(数论)
查看>>
进制转换展示
查看>>
张泉灵:做投资这半年哭过的时间比前十年都多
查看>>
c++将bool变量以文字形式打印
查看>>
洛谷P1111 修复公路 并查集 图论 最小生成树
查看>>
微名汇-微信公众平台功能开发(微信聊天机器人)
查看>>
A2W和W2A :很好的多字节和宽字节字符串的转换宏
查看>>
_T和_L的区别
查看>>
我个人的javascript和css命名规范
查看>>
android ANR产生原因和解决办法
查看>>
kylin的安装与配置
查看>>
我的java学习之路--Reflect专题
查看>>
Android Intent的setClass和setClassName的区别
查看>>
php-fpm nginx 使用 curl 请求 https 出现 502 错误
查看>>
西宁海关首次对外展示截获500余件有害生物标本
查看>>
泸州移动能源产业园首片薄膜电池组件成功下线
查看>>
韩国瑜会见陆委会主委陈明通:别给高雄念紧箍咒
查看>>