Android 使用MediaRecorder录制语音呼叫,给出java.lang.RuntimeException:启动失败

Android 使用MediaRecorder录制语音呼叫,给出java.lang.RuntimeException:启动失败,android,broadcastreceiver,android-mediarecorder,android-audiomanager,Android,Broadcastreceiver,Android Mediarecorder,Android Audiomanager,我正在尝试使用MediaRecorder记录电话进出时的声音。我实现了一个BroadcastReceiver来了解状态,当状态变为OFF-HOOK时,它开始录制,并在进入空闲状态时停止录制 我正在使用以下代码录制文件并将其保存到SD卡 private static final String AUDIO_RECORDER_FILE_EXT_3GP = ".3gp"; private static final String AUDIO_RECORDER_FILE_EXT_MP4 = ".mp4";

我正在尝试使用MediaRecorder记录电话进出时的声音。我实现了一个BroadcastReceiver来了解状态,当状态变为OFF-HOOK时,它开始录制,并在进入空闲状态时停止录制

我正在使用以下代码录制文件并将其保存到SD卡

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){

            }
代码有时工作得很好,但有时不行。它给出:

无法启动receiver com.afixi.callmanagement.IncomingCallInterceptor:java.lang.RuntimeException:启动失败

当代码工作时,它有时会给出无关紧要的结果,就像有时,如果呼叫是1:13,记录的声音是44秒。
我试过用语音呼叫代替麦克风,效果也一样。

广播接收器有特定的执行时间

从onReceive()返回后,BroadcastReceiver不再是 活动,并且它的宿主进程只与其他进程一样重要 在其中运行的应用程序组件。这尤其重要 重要的是,如果该进程仅承载 BroadcastReceiver(用户拥有的应用程序的常见情况 从未或最近未与之互动),然后从 系统将考虑它的进程是空的和 积极地杀死它,以便为其他更多的人提供资源 重要过程

当您检测到广播接收机的呼入和呼出呼叫以及在用检测电话状态并开始录音时,您需要启动服务

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;
}

}

然而,在大多数情况下,它是记录的。我可以理解这种担心,您想说的是,一旦状态发生变化,我将失去对Media Recorder对象的引用,但是,它不会发生。我可以试一下用这个对象作为静态类型吗?不,不要用静态对象作为媒体记录器,正如我在我的ans中所说,在服务中尝试您的录音代码,它将工作检查我的编辑它有一个示例代码来检查服务中的呼叫状态在摘机时写入您的开始录音代码,在空闲状态下写入停止录音代码,其他一切都将正常工作,从boadcast接收器开始服务是写入方法吗?