Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android SeekBar setProgress is causing my MediaPlayer to skip

I'm trying to use a SeekBar to display both the length of a track played by a MediaPlayer class and to enable seeking within the track.

Seeking within the track works well. However, updating the progress value using setProgress while the track is playing seems to cause a slight skip.

In the onCreate method I create a Thread with a loop which updates the SeekBar's progress value for the current track. This loop resets when the track is changed.

private void createProgressThread() {

    _progressUpdater = new Runnable() {
        @Override
        public void run() {
            //Exitting is set on destroy
            while(!_exitting) {
                _resetProgress = false;
                if(_player.isPlaying()) {
                    try
                    {
                        int current = 0;
                        int total = _player.getDuration();
                        progressBar.setMax(total);
                        progressBar.setIndeterminate(false);

                        while(_player!=null && current<total && !_resetProgress){
                            try {
                                Thread.sleep(1000); //Update once per second
                                current = _player.getCurrentPosition();
                                 //Removing this line, the track plays normally.
                                progressBar.setProgress(current); 
                            } catch (InterruptedException e) {

                            } catch (Exception e){

                            }            
                        }
                    }
                    catch(Exception e)
                    {
                        //Don't want this thread to intefere with the rest of the app.
                    }
                }
            }
        }
    };
    Thread thread = new Thread(_progressUpdater);
    thread.start();
}

Ideally I would rather not use a thread as I understand that this has disadvantages. Also please excuse the exception swallowing - it is difficult to keep checking for all MediaPlayer states in response to UI events. However, my real problem is that the music is skipping.

Could anyone suggest an alternative way to update the progress and explain why the call to setProgress is causing the track to skip even with the use of a seperate thread?

Thanks in advance.

like image 800
Rob Stevenson-Leggett Avatar asked Jan 09 '11 19:01

Rob Stevenson-Leggett


People also ask

How to handle SeekBar in Android?

A SeekBar is an extension of ProgressBar that adds a draggable thumb. The user can touch the thumb and drag left or right to set the current progress level or use the arrow keys. Placing focusable widgets to the left or right of a SeekBar is discouraged. Clients of the SeekBar can attach a SeekBar.


1 Answers

I think the problem is that when you call the setProgress(), the onProgressChanged event is fired.

The listener (OnSeekBarChangeListener) have a method public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser). Here you should test if the listener was fired by a user action or from code. In your case, the fromUser variable should be false.

public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
    if(fromUser){
           player.seekTo(x);
        }
        else{
         // the event was fired from code and you shouldn't call player.seekTo()
        }
}
like image 138
Ungureanu Liviu Avatar answered Sep 27 '22 19:09

Ungureanu Liviu