好了,捕捉到了去电过程中各个状态的转变,那么,如何通知给程序呢,我采用的方法是捕获后立马给系统发送广播,然后程序进行广播接受,接受后在处理录音事件。要发送广播,就要发送一个唯一的广播,为此,建立如下类,

 

1. package
2.  
3. import
4.  
5. import
6. import
7.  
8. public class
9.     Context ctx; 
10. public
11. this.ctx = ctx; 
12.     } 
13.      
14. /**
15.      * 前台呼叫状态
16.      * @author sdvdxl
17.      *
18.      */
19. public static final class
20. public static final
21. "com.sdvdxl.phonerecorder.FORE_GROUND_DIALING"; 
22. public static final
23. "com.sdvdxl.phonerecorder.FORE_GROUND_ALERTING"; 
24. public static final
25. "com.sdvdxl.phonerecorder.FORE_GROUND_ACTIVE"; 
26. public static final
27. "com.sdvdxl.phonerecorder.FORE_GROUND_IDLE"; 
28. public static final
29. "com.sdvdxl.phonerecorder.FORE_GROUND_DISCONNECTED"; 
30.     } 
31.      
32. /**
33.      * 开始监听呼出状态的转变,
34.      * 并在对应状态发送广播
35.      */
36. public void
37. new
38. "Recorder", "开始监听呼出状态的转变,并在对应状态发送广播"); 
39.     } 
40.      
41. }

程序需要读取系统日志权限

1. <uses-permission android:name="android.permission.READ_LOGS"/>

然后,在读取日志的类中检测到去电各个状态的地方发送一个广播,那么,读取日志的完整代码如下 
 

1. package
2.  
3. import
4. import
5. import
6. import
7.  
8. import
9.  
10. import
11. import
12. import
13.  
14. /**
15.  * 
16.  * @author mrloong
17.  *  找到 日志中的
18.  *  onPhoneStateChanged: mForegroundCall.getState() 这个是前台呼叫状态
19.  *  mBackgroundCall.getState() 后台电话
20.  *  若 是 DIALING 则是正在拨号,等待建立连接,但对方还没有响铃,
21.  *  ALERTING 呼叫成功,即对方正在响铃,
22.  *  若是 ACTIVE 则已经接通
23.  *  若是 DISCONNECTED 则本号码呼叫已经挂断
24.  *  若是 IDLE 则是处于 空闲状态
25.  *  
26.  */
27. public class ReadLog extends
28. private
29. private int
30.      
31. private static final String TAG = "LogInfo OutGoing Call"; 
32.      
33. /**
34.      *  前后台电话
35.      * @author sdvdxl
36.      *  
37.      */
38. private static class
39. public static final String FORE_GROUND_CALL_STATE = "mForeground"; 
40.     } 
41.      
42. /**
43.      * 呼叫状态
44.      * @author sdvdxl
45.      *
46.      */
47. private static class
48. public static final String DIALING = "DIALING"; 
49. public static final String ALERTING = "ALERTING"; 
50. public static final String ACTIVE = "ACTIVE"; 
51. public static final String IDLE = "IDLE"; 
52. public static final String DISCONNECTED = "DISCONNECTED"; 
53.     } 
54.      
55. public
56. this.ctx = ctx; 
57.     } 
58.      
59. /**
60.      * 读取Log流
61.      * 取得呼出状态的log
62.      * 从而得到转换状态
63.      */
64. @Override
65. public void
66. "开始读取日志记录"); 
67.          
68. "logcat", "InCallScreen *:s"}; 
69. "logcat", "-c"}; 
70.          
71. try
72.             Process process=Runtime.getRuntime().exec(catchParams); 
73.             InputStream is = process.getInputStream(); 
74. new BufferedReader(new
75.              
76. null; 
77. while ((line=reader.readLine())!=null) { 
78.                 logCount++; 
79. //输出所有
80.             Log.v(TAG, line); 
81.                  
82. //日志超过512条就清理
83. if (logCount>512) { 
84. //清理日志
85.                     Runtime.getRuntime().exec(clearParams) 
86. //销毁进程,释放资源
87. 0; 
88. "-----------清理日志---------------"); 
89.                 }    
90.                  
91. /*---------------------------------前台呼叫-----------------------*/
92. //空闲
93. if
94.                         && line.contains(ReadLog.CallState.IDLE)) { 
95.                     Log.d(TAG, ReadLog.CallState.IDLE); 
96.                 } 
97.                  
98. //正在拨号,等待建立连接,即已拨号,但对方还没有响铃,
99. if
100.                         && line.contains(ReadLog.CallState.DIALING)) { 
101. //发送广播
102. new
103.                     dialingIntent.setAction(OutgoingCallState.ForeGroundCallState.DIALING); 
104.                     ctx.sendBroadcast(dialingIntent); 
105.                      
106.                     Log.d(TAG, ReadLog.CallState.DIALING); 
107.                 } 
108.                  
109. //呼叫对方 正在响铃
110. if
111.                         && line.contains(ReadLog.CallState.ALERTING)) { 
112. //发送广播
113. new
114.                     dialingIntent.setAction(OutgoingCallState.ForeGroundCallState.ALERTING); 
115.                     ctx.sendBroadcast(dialingIntent); 
116.                      
117.                     Log.d(TAG, ReadLog.CallState.ALERTING); 
118.                 } 
119.                  
120. //已接通,通话建立
121. if
122.                         && line.contains(ReadLog.CallState.ACTIVE)) { 
123. //发送广播
124. new
125.                     dialingIntent.setAction(OutgoingCallState.ForeGroundCallState.ACTIVE); 
126.                     ctx.sendBroadcast(dialingIntent); 
127.                      
128.                     Log.d(TAG, ReadLog.CallState.ACTIVE); 
129.                 } 
130.                  
131. //断开连接,即挂机
132. if
133.                         && line.contains(ReadLog.CallState.DISCONNECTED)) { 
134. //发送广播
135. new
136.                     dialingIntent.setAction(OutgoingCallState.ForeGroundCallState.DISCONNECTED); 
137.                     ctx.sendBroadcast(dialingIntent); 
138.                      
139.                     Log.d(TAG, ReadLog.CallState.DISCONNECTED); 
140.                 } 
141.                  
142. //END while
143.              
144. catch
145.             e.printStackTrace(); 
146. //END try-catch
147. //END run
148. } //END class ReadLog

发送了广播,那么就要有接受者,定义接收者如下
(关于录音机的代码可以先忽略)


1. package
2.  
3. import
4. import
5. import
6. import
7.  
8. import
9.  
10. public class OutgoingCallReciver extends
11. static final String TAG = "Recorder"; 
12. private
13.      
14. public
15. new
16.     } 
17.      
18. public
19. this.recorder = recorder; 
20.     } 
21.      
22. @Override
23. public void
24.         String phoneState = intent.getAction(); 
25.          
26. if
27. //拨出号码
28.             recorder.setPhoneNumber(phoneNum); 
29. false); 
30. "设置为去电状态"); 
31. "去电状态 呼叫:"
32.         } 
33.          
34. if
35. "正在拨号..."); 
36.         } 
37.          
38. if
39. "正在呼叫..."); 
40.         } 
41.          
42. if
43. if
44. "去电已接通 启动录音机"); 
45.                 recorder.start(); 
46.                  
47.             } 
48.         } 
49.          
50. if
51. if
52. "已挂断 关闭录音机"); 
53.                 recorder.stop(); 
54.             } 
55.         } 
56.     } 
57.  
58. }

其中有这么一段代码

1. String phoneState = intent.getAction();  
2.           
3. if
4. //拨出号码 
5.             recorder.setPhoneNumber(phoneNum);  
6. false);  
7. "设置为去电状态");  
8. "去电状态 呼叫:"
9.         }

这里是接收系统发出的广播,用于接收去电广播。这样,就获得了去电状态。

3、有了以上主要代码,可以说,来去电监听功能算是完成了,下面创建一个service来运行监听
 

1. package
2.  
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10. import
11. import
12.  
13. import
14. import
15. import
16. import
17.  
18. public class PhoneCallStateService extends
19. private
20. private
21. private
22.      
23. @Override
24. public void
25. super.onCreate(); 
26.          
27. //------以下应放在onStartCommand中,但2.3.5以下版本不会因service重新启动而重新调用--------
28. //监听电话状态,如果是打入且接听 或者 打出 则开始自动录音
29. //通话结束,保存文件到外部存储器上
30. "Recorder", "正在监听中..."); 
31. new
32. new OutgoingCallState(this); 
33. new
34.         outgoingCallState.startListen(); 
35. this, "服务已启动", Toast.LENGTH_LONG).show(); 
36.          
37. //去电
38. new
39.         outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.IDLE); 
40.         outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.DIALING); 
41.         outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.ALERTING); 
42.         outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.ACTIVE); 
43.         outgoingCallFilter.addAction(OutgoingCallState.ForeGroundCallState.DISCONNECTED); 
44.          
45. "android.intent.action.PHONE_STATE"); 
46. "android.intent.action.NEW_OUTGOING_CALL"); 
47.          
48. //注册接收者
49.         registerReceiver(outgoingCallReciver, outgoingCallFilter); 
50.          
51. //来电
52.         TelephonyManager telmgr = (TelephonyManager)getSystemService( 
53.                 Context.TELEPHONY_SERVICE); 
54. new
55.          
56.          
57.     } 
58.      
59. @Override
60. public
61. // TODO Auto-generated method stub
62. return null; 
63.     } 
64.  
65. @Override
66. public void
67. super.onDestroy(); 
68.         unregisterReceiver(outgoingCallReciver); 
69.         Toast.makeText( 
70. this, "已关闭电话监听服务", Toast.LENGTH_LONG) 
71.                 .show(); 
72. "Recorder", "已关闭电话监听服务"); 
73.     } 
74.  
75. @Override
76. public int onStartCommand(Intent intent, int flags, int
77.          
78. return
79.     } 
80.  
81. }

注册以下service
 

1. <service android:name="com.sdvdxl.service.PhoneCallStateService" />

到此为止,来去电状态的监听功能算是完成了,剩下一个录音机,附上录音机代码如下
 


1. package
2.  
3. import
4. import
5. import
6. import
7.  
8. import
9. import
10. import
11.  
12. public class
13. private
14. private
15. private boolean started = false; //录音机是否已经启动
16. private boolean isCommingNumber = false;//是否是来电
17. private String TAG = "Recorder"; 
18.      
19.      
20. public
21. this.setPhoneNumber(phoneNumber); 
22.     } 
23.      
24. public
25.     } 
26.  
27. public void
28. true; 
29. new
30.          
31. new
32.                 Environment.getExternalStorageDirectory() 
33. "/My record");  
34. if
35.             recordPath.mkdirs(); 
36. "recorder", "创建目录"); 
37.         } 
38.          
39. "呼出"; 
40. if
41. "呼入"; 
42.         } 
43. "-" + phoneNumber + "-"
44. new SimpleDateFormat("yy-MM-dd_HH-mm-ss") 
45. new Date(System.currentTimeMillis())) + ".mp3";//实际是3gp
46. new
47.          
48. try
49.             recordName.createNewFile(); 
50. "recorder", "创建文件"
51. catch
52.             e.printStackTrace(); 
53.         } 
54.          
55.         mrecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); 
56.         mrecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); 
57.         mrecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); 
58.          
59.         mrecorder.setOutputFile(recordName.getAbsolutePath()); 
60.          
61. try
62.             mrecorder.prepare(); 
63. catch
64.             e.printStackTrace(); 
65. catch
66.             e.printStackTrace(); 
67.         } 
68.         mrecorder.start(); 
69. true; 
70. "录音开始"); 
71.     } 
72.      
73. public void
74. try
75. if (mrecorder!=null) { 
76.                 mrecorder.stop(); 
77.                 mrecorder.release(); 
78. null; 
79.             } 
80. false; 
81. catch
82.             e.printStackTrace(); 
83.         } 
84.          
85.          
86. "录音结束"); 
87.     } 
88.      
89. public void
90.          
91.     } 
92.  
93. public
94. return
95.     } 
96.  
97. public void
98. this.phoneNumber = phoneNumber; 
99.     } 
100.  
101. public boolean
102. return
103.     } 
104.  
105. public void setStarted(boolean
106. this.started = hasStarted; 
107.     } 
108.  
109. public boolean
110. return
111.     } 
112.  
113. public void setIsCommingNumber(boolean
114. this.isCommingNumber = isCommingNumber; 
115.     } 
116.  
117. }

写到这儿,算是完成了来去电自动录音的所有功能,如有不懂,或者更好的建议欢迎评论。

另附 工程源代码 


转载于:https://blog.51cto.com/sdvdxl/1109860