Reputation: 141
I want to repeat - - -... so on. The recording (for seconds) stops when its energy reaches at some threshold value and playbacked. After playback, new recording begins. So I have to monitor the energy using buffers and begin new recording after playback time computation. My pseudocode (most simplified form) looks like this :
...
public class MainActivity extends Activity {
private Handler myHandler = new Handler();
....
private Runnable timedTask = new Runnable() {
public void run() {
audiorecorder = new AudioRecord(... initializes
audiorecorder.startRecording();
isRecording = true;
ElapsedTime = 0.0;
while(true) {
ReadByte = audiorecorder.read(buffer, 0, buffersize);
// Write ReadByte onto file (temp.pcm)
EnergyBuffer = <some averaged energy over a period (1 sec or so)>
if(EnergyBuffer > Threshold)
break;
ElapsedTime = ...
}
// audiorecorder.release, stop, and null
// play temp.pcm using AudioTrack
myHandler.postDelayed(timedTask, Elapsedtime);
};
}
and this is triggered by a start and a stop button as follows,
StartButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
myHandler.post(timedTask);
}
});
StopButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
myHandler.removeCallbacks(timedTask);
}
});
The problem is when audio is recording or playback, no button is working, I have to wait until it finishes the recording. How can I prevent freezing from recording? Is it just because of whileloop? Please help..!
If I run as follows, there is no error.
Thread t = new Thread(timedTask);
t.start();
This is only one-time ok, but after then when handler does in delayed time, it also freezes the UI.
Upvotes: 3
Views: 3508
Reputation: 141
You are the genius, works like a charm and it is exactly what I worked for days, thank you so much!! Here is the answer from my problem :
public class MainActivity extends Activity {
private Handler myHandler;
....
private Runnable timedTask = new Runnable() {
public void run() {
audiorecorder = new AudioRecord(... initializes
audiorecorder.startRecording();
isRecording = true;
ElapsedTime = 0.0;
while(true) {
ReadByte = audiorecorder.read(buffer, 0, buffersize);
// Write ReadByte onto file (temp.pcm)
EnergyBuffer = <some averaged energy over a period (1 sec or so)>
if(EnergyBuffer > Threshold)
break;
ElapsedTime = ...
}
// audiorecorder.release, stop, and null
// play temp.pcm using AudioTrack
myHandler.postDelayed(timedTask, Elapsedtime);
};
....
protected void OnCreate(Bundle savedInstanceState) {
...
HandlerThread readThread = new HandlerThread("");
readThread.start();
myHandler = new Handler(readThread.getLooper());
...
}
}
Upvotes: 1
Reputation: 3076
A handler posts runnable tasks into a looper in a thread. It doesn't on it self create a new thread on which to run the runnables on asynchronously.
When you create a handler by calling the constructor new Handler()
, the handler will get the looper of the current thread from which the constructor was called on by default. Since you called new Handler()
on the UI thread, any runnable given to the handler's post command will just be added to the UI thread.
You need to create a new thread and get it's looper, by doing
HandlerThread readThread = new HandlerThread("");
readThread.start();
myHandler = new Handler(readThread.getLooper());
HandlerThread is a thread that automatically sets up a looper for you to use.
Of course, you will also need to quit the thread once you don't need it
readThread.quit();
Upvotes: 6