Reputation: 33901
I'm making an app that records uncompressed (wav format) audio. I'm using this class to actually record the audio. Currently, my application records fine (I can play the file), however when I click the button to stop the recording, the app hangs for 10 seconds or so, with no log output or any signs of life. Finally it comes round, dumps a load of errors into the log, updates the UI etc. I'm using AsyncTasks to try and avoid this kind of thing but it's not working. Here's my code:
//Called on clicks of the record button. rar is the instance of RehearsalAudioRecorder
private OnClickListener RecordListener = new OnClickListener(){
@Override
public void onClick(View v) {
Log.d("Record","Click");
if (recording){
new stopRecordingTask().execute(rar,null,null);
startStop.setText("Record");
statusBar.setText("Recording Finished, ready to Encode");
}else{
recording = true;
new startRecordingTask().execute(rar,null,null);
startStop.setText("Stop");
statusBar.setText("Recording Started");
}
}
};
private class startRecordingTask extends AsyncTask<RehearsalAudioRecorder,Void,Void>{
@Override
protected Void doInBackground(RehearsalAudioRecorder... rs) {
RehearsalAudioRecorder r = rs[0];
r.setOutputFile("/sdcard/rarOut.wav");
r.prepare();
r.start();
return null;
}
}
private class stopRecordingTask extends AsyncTask<RehearsalAudioRecorder,Void,Void>{
@Override
protected Void doInBackground(RehearsalAudioRecorder... rs) {
RehearsalAudioRecorder r = rs[0];
r.stop();
r.reset();
return null;
}
}
In Logcat, I always get output like this, which has me stumped. I have no idea what's causing it (I'm logging the RehearsalAudioRecorder class, and it's being started/stopped correctly by the button clicks. This output occurs after the log output for the button click and correct stop() method call)
12-19 11:59:11.172: ERROR/AudioRecord-JNI(22662): Unable to retrieve AudioRecord object, can't record
12-19 11:59:11.172: ERROR/uk.ac.cam.tfmw2.steg.RehearsalAudioRecorder(22662): Error occured in updateListener, recording is aborted
12-19 11:59:11.172: ERROR/uk.ac.cam.tfmw2.steg.RehearsalAudioRecorder(22662): stop() called on illegal state: STOPPED
12-19 11:59:11.172: ERROR/AudioRecord-JNI(22662): Unable to retrieve AudioRecord object, can't record
12-19 11:59:11.172: ERROR/uk.ac.cam.tfmw2.steg.RehearsalAudioRecorder(22662): Error occured in updateListener, recording is aborted
12-19 11:59:11.172: ERROR/uk.ac.cam.tfmw2.steg.RehearsalAudioRecorder(22662): stop() called on illegal state: ERROR
12-19 11:59:11.172: ERROR/AudioRecord-JNI(22662): Unable to retrieve AudioRecord object, can't record
12-19 11:59:11.172: ERROR/uk.ac.cam.tfmw2.steg.RehearsalAudioRecorder(22662): Error occured in updateListener, recording is aborted
12-19 11:59:11.172: ERROR/uk.ac.cam.tfmw2.steg.RehearsalAudioRecorder(22662): stop() called on illegal state: ERROR
... 10 or more times
I've been fiddling with this all day and I'm not getting anywhere, any input would be greatly appreciated.
Update I've replace the AsyncTasks with Threads, still doesn't work, the app completely hangs when I click record, despite the fact the Log indicates there's nothing going on in the main thread. Still completely stumped.
Upvotes: 1
Views: 2993
Reputation: 33901
Putting it in a Service works, gets rid of the UI lockup completely. I used a heavily stripped down version of the RecordService class in the RehearsalAudio project, stripping out all the session stuff that's not required.
Upvotes: 0
Reputation: 13015
Fredley,
The simplest way to fix this is to check the state of the aRecorder IN your onPeriodicotification. You can do this with by nesting everything in the following if statement:
if (aRecord.getRecordingState() != RECORDSTATE_STOPPED)
{
// Your onPeriodicNotification code here...
}
Note: This is necessary because the AudioRecord object is necessarily threaded in addition to your other AsyncTasks. Your state is simply not enough because it is not accessible by the AudioRecord object.
Fuzzical Logic
P.S. You might also verify your aRecord object against your recorder argument. They aren't insured to be talking to the same object. Not important for this particular code, but good to know for the future.
Upvotes: 0
Reputation: 12601
You've given the application RECORD_AUDIO permission?
You should also change the catch-block in RehearsalAudioRecorder to log the real exception instead of just "Error occured in updateListener, recording is aborted" as it logs now.
Upvotes: 2