Запись голосового вызова с использованием MediaRecorder, дающая java.lang.RuntimeException: запуск не удался

Я пытаюсь записать голос с помощью 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: запуск не выполнен

Когда код работает, он иногда дает безразличный результат, например, иногда, если вызов 1:13, записанный звук составляет 44 секунды. Я пробовал использовать VOICE_CALL вместо MIC, тоже самое.


person Saty    schedule 21.04.2014    source источник


Ответы (1)


Широковещательный приемник имеет определенное время выполнения

Как только вы вернетесь из 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;
}

}
person Auto-Droid ツ    schedule 21.04.2014
comment
Однако в большинстве случаев это запись. Я могу понять беспокойство, вы хотите сказать, что я потеряю ссылку на объект Media Recorder после изменения состояния, однако этого не происходит. Должен ли я попробовать использовать объект как статический тип? - person Saty; 21.04.2014
comment
нет, не используйте статический объект для медиа-рекордера, как я уже сказал в своем ответе, попробуйте свой код записи в сервисе, и он будет работать - person Auto-Droid ツ; 21.04.2014
comment
Проверьте мое редактирование, в нем есть пример кода для проверки состояния вызова в службе. - person Auto-Droid ツ; 21.04.2014
comment
при снятии трубки напишите свой код начала записи, а в состоянии ожидания напишите код остановки записи, все остальное будет работать нормально - person Auto-Droid ツ; 21.04.2014
comment
а с приемника boadcast запустить службу это подход записи? - person Saty; 21.04.2014
comment
Однако если я сделаю так, что при каждом вызове из широковещательного приемника будет создаваться другой экземпляр службы? - person Saty; 21.04.2014
comment
не обязательно, если вы дадите надлежащее условие перед запуском службы, тогда я не думаю, что должны быть какие-то проблемы - person Auto-Droid ツ; 21.04.2014
comment
тем временем я попробовал ваш код и позвонил в службу с приемника вещания, однако он не записывает голос и не включает громкую связь из службы. ошибки тоже нет? Я позабочусь об этом. Не могли бы вы уточнить о надлежащем состоянии, о котором вы говорили? - person Saty; 21.04.2014