Search code examples
javaandroidseekbaraudio-playerandroid-music-player

Fixing a seekbar on my Android music player


I've created a simple music player in Android which has a seekbar which displays the current position in the song playing. The forward, rewind, play and pause functions work correctly. What I am trying to do is have the seekbar actually move the position within the song. (at present the seekbar does not change the position within the song. Heres my code

public class MusicPlayerA extends Activity {

private MediaPlayer mediaPlayer;
public TextView songName, duration;
private double timeElapsed = 0, finalTime = 0;
private int forwardTime = 2500, backwardTime = 2500;
private Handler durationHandler = new Handler();
private SeekBar seekbar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //set the layout of the Activity
    setContentView(R.layout.musicplayerview);
    //initialize views
    initializeViews();
}

@Override
protected void onPause() {
    super.onPause();
    if (mediaPlayer != null) {
        mediaPlayer.pause();
        if (isFinishing()) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }
    }
}

public void initializeViews(){
    songName = (TextView) findViewById(R.id.songName);
    mediaPlayer = MediaPlayer.create(this, R.raw.druidsad);
    finalTime = mediaPlayer.getDuration();
    duration = (TextView) findViewById(R.id.songDuration);
    seekbar = (SeekBar) findViewById(R.id.seekBar);
    songName.setText("Druids Ad");  
    seekbar.setMax((int) finalTime);
    seekbar.setClickable(true);
}

// play mp3 song
public void play(View view) {
    mediaPlayer.start();
    timeElapsed = mediaPlayer.getCurrentPosition();
    seekbar.setProgress((int) timeElapsed);
    durationHandler.postDelayed(updateSeekBarTime, 100);
}

//handler to change seekBarTime
private Runnable updateSeekBarTime = new Runnable() {
    public void run() {
        //get current position
        timeElapsed = mediaPlayer.getCurrentPosition();
        //set seekbar progress
        seekbar.setProgress((int) timeElapsed);
        //set time remaining
        double timeRemaining = finalTime - timeElapsed;
        duration.setText(String.format("%d min, %d sec", TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining), TimeUnit.MILLISECONDS.toSeconds((long) timeRemaining) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) timeRemaining))));

        //repeat yourself that again in 100 miliseconds
        durationHandler.postDelayed(this, 100);
    }
};

// pause mp3 song
public void pause(View view) {
    mediaPlayer.pause();
}

// go forward at forwardTime seconds
public void forward(View view) {
    //check if we can go forward at forwardTime seconds before song endes
    if ((timeElapsed + forwardTime) <= finalTime) {
        timeElapsed = timeElapsed + forwardTime;

        //seek to the exact second of the track
        mediaPlayer.seekTo((int) timeElapsed);
    }
}

// go backwards at backwardTime seconds
public void rewind(View view) {
    //check if we can go back at backwardTime seconds after song starts
    if ((timeElapsed - backwardTime) > 0) {
        timeElapsed = timeElapsed - backwardTime;

        //seek to the exact second of the track
        mediaPlayer.seekTo((int) timeElapsed);
    }
}

 // handler for back button used on music player screen
 public void BackButton2 (View view) {

    MediaPlayer mMediaPlayer = MediaPlayer.create(this, R.raw.soundbackbutton) ;
    mMediaPlayer.start();

    Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    vib.vibrate(200);

    Intent mus = new Intent (this, Music.class);
    startActivity(mus);
 }

// handler for home button used on all screens
public void BackButton (View view) {

    MediaPlayer mMediaPlayer = MediaPlayer.create(this, R.raw.soundbackbutton) ;
    mMediaPlayer.start();

    Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    vib.vibrate(200);

    Intent mn = new Intent (this, Music.class);
    startActivity(mn);
 }

}


Solution

  • Its easy. Follow these steps :-

    1. Add a seek bar change Listener.

      seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {         
          int seeked_progess;
      
          @Override
          public void onProgressChanged(final SeekBar seekBar, int progress, boolean fromUser) {
      
              seeked_progess = progress;
              seeked_progess = seeked_progess * 1000;
      
              if (fromUser) {                 
              }
          }
      
          @Override
          public void onStartTrackingTouch(SeekBar seekBar) {
      
          }
      
          @Override
          public void onStopTrackingTouch(SeekBar seekBar) {
      
          }
      });
      
    2. Now in if(fromUser), U need to add the implementation.

        if (fromUser) {
      
                  Runnable mRunnable = new Runnable() {
      
                      @Override
                      public void run() {
                          int min, sec;
      
                          if (mediaPlayer != null /*Checking if the
                             music player is null or not otherwise it
                             may throw an exception*/) {
                              int mCurrentPosition = seekBar.getProgress();
      
                              min = mCurrentPosition / 60;
                              sec = mCurrentPosition % 60;
      
                              Log.e("Music Player Activity", "Minutes : "+min +" Seconds : " + sec);
      
                              /*currentime_mm.setText("" + min);
                              currentime_ss.setText("" + sec);*/
                          }
                          mHandler.postDelayed(this, 1000);
                      }
                  };
                  mRunnable.run();}
      
    3. At last add this in onStopTrackingTouch()

      @Override
       public void onStopTrackingTouch(SeekBar seekBar) {
           mediaPlayer.seekTo(seeked_progess);
          }
      });
      

    Note :-

    mHandler in a global variable. Initialize it as follows.

    Handler mHandler = new Handler();
    

    Secondly currentime_mm and currentime_ss are text views which display the current seek time of the seek bar.

    and most Important, dont forgot to add these when a song starts

    seekBar.setProgress(0);// To set initial progress, i.e zero in starting of the song
    seekBar.setMax(mediaDuration);// To set the max progress, i.e duration of the song