我正在尝试使用MediaRecorder录制语音,当有来电并从手机发出时。我已经实现了一个BroadcastReceiver来了解状态,当状态进入OFF-HOOK时,它开始记录并在进入IDLE状态时停止记录。
我使用以下代码录制并将文件保存到SDCARD
private static final String AUDIO_RECORDER_FILE_EXT_3GP = ".3gp";
private static final String AUDIO_RECORDER_FILE_EXT_MP4 = ".mp4";
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
private static boolean recordStarted;
private MediaRecorder recorder;
private int currentFormat = 1;
private int output_formats[] = { MediaRecorder.OutputFormat.MPEG_4,
MediaRecorder.OutputFormat.THREE_GPP };
private String file_exts[] = { AUDIO_RECORDER_FILE_EXT_MP4,
AUDIO_RECORDER_FILE_EXT_3GP };
**When the state change to OFFHOOK**
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
recorder = new MediaRecorder();
//recorder.setMaxDuration(12000);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(output_formats[currentFormat]);
//recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(getFilename());
recorder.setOnErrorListener(errorListener);
recorder.setOnInfoListener(infoListener);
try {
recorder.prepare();
recorder.start();
recordStarted = true;
} catch (IllegalStateException e) {
Log.e("REDORDING :: ",e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Log.e("REDORDING :: ",e.getMessage());
e.printStackTrace();
}
**when the state change to IDLE**
audioManager.setSpeakerphoneOn(false);
try{
if (recordStarted) {
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
recordStarted = false;
}
}catch(RuntimeException stopException){
}
代码有时效果很好但有时却没有。它给出了:
无法启动接收器com.afixi.callmanagement.IncomingCallInterceptor:java.lang.RuntimeException:start failed
当代码工作时,它有时会给出无关紧要的结果,有时,如果呼叫是1:13,录制的声音是44秒。 我尝试使用VOICE_CALL而不是MIC,它也是如此。
答案 0 :(得分:0)
广播接收器具有特定的执行时间
从onReceive()返回后,BroadcastReceiver不再存在 活跃,其托管过程与其他任何一样重要 在其中运行的应用程序组件。这是特别的 重要的是因为如果那个过程只是托管的那个 BroadcastReceiver(用户拥有的应用程序的常见情况) 从来没有或最近没有与之互动过,然后从...返回 onReceive()系统会认为它的进程是空的 积极地杀死它,以便资源可用于其他更多 重要的过程。
当您检测到来电和拨出广播接收器以及在线检测电话状态并开始录制时,您将需要启动服务
public class TestService extends Service {
public class CustomPhoneStateListener extends PhoneStateListener {
private static final String TAG = "CustomPhoneStateListener";
@Override
public void onCallStateChanged(int state, String phonenumber){
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "CALL_STATE_RINGING");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(TAG, "CALL_STATE_OFFHOOK");
break;
case TelephonyManager.CALL_STATE_IDLE:
Log.d(TAG, "CALL_STATE_IDLE");
break;
} //switch close
}
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onDestroy() {
Log.d("service", "destroy");
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
final String terminate = intent.getStringExtra("terminate");
TelephonyManager telephony = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); //TelephonyManager object
CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener();
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
if(terminate != null) {
stopSelf();
}
return START_STICKY;
}
}