Запис на гласово повикване с помощта на 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)


Broadcast приемникът има определено време на изпълнение

След като се върнете от 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
не, не използвайте статичен обект за медиен рекордер, както казах в моя ans, опитайте вашия код за запис в услугата и той ще работи - person Auto-Droid ツ; 21.04.2014
comment
Проверете моята редакция, има примерен код за проверка на състоянието на обаждането в услуга - person Auto-Droid ツ; 21.04.2014
comment
в offhook напишете своя код за начало на запис и в състояние на неактивност напишете код за спиране на запис, всичко останало ще работи добре - person Auto-Droid ツ; 21.04.2014
comment
и от boadcast приемника стартирайте услугата подходът за запис ли е? - person Saty; 21.04.2014
comment
Ако обаче направя това различно копие на услугата ще се създава с всяко повикване от broadcastreceiver? - person Saty; 21.04.2014
comment
не е необходимо, ако дадете правилното състояние, преди да започнете услугата, тогава не мисля, че трябва да има някакъв проблем - person Auto-Droid ツ; 21.04.2014
comment
междувременно опитах вашия код и се обадих на услугата от приемника за излъчване, но той не записва гласа, нито включва високоговорителя от услугата. И грешка ли няма? Ще се погрижа за това. Бихте ли уточнили за правилното състояние, за което говорите? - person Saty; 21.04.2014