手把手教你Android来去电通话自动录音的方法

2019-04-13 15:32发布

http://www.jizhuomi.com/android/example/354.html 我们在使用Android手机打电话时,有时可能会需要对来去电通话自动录音,本文就详细讲解实现Android来去电通话自动录音的方法,大家按照文中的方法编写程序就可以完成此功能。        来去电自动录音的关键在于如何监听手机电话状态的转变:        1)来电的状态的转换如下(红 {MOD}标记是我们要用到的状态)        空闲(IDEL)——> 响铃(RINGING)——> 接听(ACTIVE)——> 挂断(经历DISCONNECTING——DISCONNECTED)——> 空闲(IDEL)         或者  空闲(IDEL)——> 响铃(RINGING)——> 拒接 ——> 空闲(IDEL)        2)去电状态的转换如下        空闲(IDEL)——> 拨号 (DIALING)——> (对方)响铃(ALERTING) ——> 建立连接(ACTIVE)—— 挂断(经历DISCONNECTING——DISCONNECTED)——> 空闲(IDEL)         或者 空闲(IDEL)——> 拨号 (DIALING)——> (对方)响铃(ALERTING)——> 挂断/对方拒接 ——> 空闲(IDEL)        下面就分别就来电和去电这两种状态分析并实现。        1、先进行来电的分析和实现。        相对去电来说,来电状态的转换检测要简单些。android api 中的PhoneStateListener 类提供了相应的方法,但我们需要覆盖其中的 onCallStateChanged(int state, String incomingNumber) 方法即可实现来电状态的检测,并在此基础上添加录音功能即可。其中 state 参数就是各种电话状态,到时我们将它跟下面我们要用到的状态进行比较,若是电话处在我们想要的状态上,则进行一系列操作,否则就不管他。想要获取这些状态,还需要另一个电话相关类,那就是 TelephonyManager, 该类 提供了一些电话状态,其中我们要用到的是:TelephonyManager.CALL_STATE_IDLE(空闲)、TelephonyManager.CALL_STATE_OFFHOOK(摘机)和 TelephonyManager.CALL_STATE_RINGING(来电响铃)这三个状态。判别这三种状态,可以继承 android.telephony.PhoneStateListener 类,实现上面提到的 onCallStateChanged(int state, String incomingNumber) 方法,请看如下代码: Java代码
  1. public class TelListener extends PhoneStateListener {     
  2.      
  3.     @Override     
  4.     public void onCallStateChanged(int state, String incomingNumber) {     
  5.         super.onCallStateChanged(state, incomingNumber);     
  6.      
  7.         switch (state) {     
  8.         case TelephonyManager.CALL_STATE_IDLE: // 空闲状态,即无来电也无去电     
  9.             Log.i("TelephoneState""IDLE");     
  10.             //此处添加一系列功能代码    
  11.             break;     
  12.         case TelephonyManager.CALL_STATE_RINGING: // 来电响铃     
  13.             Log.i("TelephoneState""RINGING");     
  14.             //此处添加一系列功能代码    
  15.             break;     
  16.         case TelephonyManager.CALL_STATE_OFFHOOK: // 摘机,即接通    
  17.             Log.i("TelephoneState""OFFHOOK");     
  18.             //此处添加一系列功能代码    
  19.             break;     
  20.         }     
  21.      
  22.         Log.i("TelephoneState", String.valueOf(incomingNumber));     
  23.     }     
  24.      
  25. }  
       有了以上来电状态监听代码还不足以实现监听功能,还需要在我们的一个Activity或者Service中实现监听,方法很简单,代码如下: Java代码
  1. /**   
  2. * 在activity 或者 service中加入如下代码,以实现来电状态监听   
  3. */    
  4. TelephonyManager telMgr = (TelephonyManager)context.getSystemService(    
  5.                 Context.TELEPHONY_SERVICE);    
  6.         telMgr.listen(new TelListener(), PhoneStateListener.LISTEN_CALL_STATE);   
       这样就实现了来电状态监听功能,但要能够在设备中跑起来,这还不够,它还需要两个获取手机电话状态的权限: XML/HTML代码
  1. <uses-permission android:name="android.permission.READ_PHONE_STATE" />    
  2. <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />   
       这样的话就可以跑起来了。        说到这,我想如果你可以实现录音功能的话,在此基础上实现来电自动录音就应该没什么问题了,不过请容我简单罗嗦几句。既然是来电,那么要想录音的话,那么应该就是在监听到 TelephonyManager.CALL_STATE_OFFHOOK 的状态时开启录音机开始录音, 在监听到TelephonyManager.CALL_STATE_IDLE 的状态时关闭录音机停止录音。这样,来电录音功能就完成了,不要忘记录音功能同样需要权限: XML/HTML代码
  1. <uses-permission android:name="android.permission.RECORD_AUDIO"/>     
  2.      
  3.      
  4. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>     
  5. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  
       2、介绍完了来电自动录音,下面就来介绍去电自动录音的实现方法。        上面说过,相比来电状态的监听,去电的要麻烦些,甚至这种方法不是通用的,这个主要是因为android api 中没有提供去电状态监听的相应类和方法(也许我刚接触,没有找到)。刚开始网上搜索了一通也没有找到对应的解决方法,大多是 来电监听的,也就是上面的方法。不过中途发现一篇博文(后来就搜不到了),记得是查询系统日志的方式,从中找到去电过程中的各个状态的关键词。无奈之中,最终妥协了此方法。        我的(联想A65上的)去电日志内容如下:        过滤关键词为 mforeground Java代码
  1. 01-06 16:29:54.225: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING    
  2. 01-06 16:29:54.245: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : DIALING    
  3. 01-06 16:29:54.631: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING    
  4. 01-06 16:29:54.645: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : DIALING    
  5. 01-06 16:29:54.742: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING    
  6. 01-06 16:29:54.766: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : DIALING    
  7. 01-06 16:29:54.873: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING    
  8. 01-06 16:29:54.877: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : DIALING    
  9. 01-06 16:29:55.108: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DIALING    
  10. 01-06 16:29:55.125: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : DIALING    
  11. 01-06 16:29:57.030: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE    
  12. 01-06 16:29:57.155: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE    
  13. 01-06 16:29:57.480: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE    
  14. 01-06 16:29:57.598: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : ACTIVE    
  15. 01-06 16:29:59.319: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : DISCONNECTING    
  16. 01-06 16:29:59.373: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : DISCONNECTING    
  17. 01-06 16:30:00.392: D/InCallScreen(251): - onDisconnect: currentlyIdle:true ; mForegroundCall.getState():DISCONNECTED    
  18. 01-06 16:30:00.399: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): - onDisconnect: currentlyIdle:true ; mForegroundCall.getState():DISCONNECTED    
  19. 01-06 16:30:01.042: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : IDLE    
  20. 01-06 16:30:01.070: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : IDLE    
  21. 01-06 16:30:01.558: D/InCallScreen(251): onPhoneStateChanged: mForegroundCall.getState() : IDLE    
  22. 01-06 16:30:01.572: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mForegroundCall.getState() : IDLE   
       过滤关键词  mbackground Java代码
  1. 01-06 16:29:54.226: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE    
  2. 01-06 16:29:54.256: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE    
  3. 01-06 16:29:54.638: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE    
  4. 01-06 16:29:54.652: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE    
  5. 01-06 16:29:54.743: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE    
  6. 01-06 16:29:54.770: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE    
  7. 01-06 16:29:54.875: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE    
  8. 01-06 16:29:54.882: V/LogInfo OutGoing Call(2492): D/InCallScreen(  251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE    
  9. 01-06 16:29:55.109: D/InCallScreen(251): onPhoneStateChanged: mBackgroundCall.getState() : IDLE    
  10. 01-06 16