I use this media player but when I rotate the emulator (Ctrl+F11) the startPlayProgressUpdater() doesn't work properly. How can I update seekbar after rotation?
Asked
Active
Viewed 2,605 times
2 Answers
1
Save the seekbar position in onSaveInstanceState()
callback in activity.
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("current_position", seekbarPosition);
}
In onCreate
of your activity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.......
if (savedInstanceState != null) {
// set seek bar position from `savedInstanceState`
}
}
Update
Move the notification runnable out of the start method.
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater();
}
};
public void startPlayProgressUpdater() {
seekBar.setProgress(mediaPlayer.getCurrentPosition());
if (mediaPlayer.isPlaying()) {
handler.postDelayed(notification,1000);
}else{
mediaPlayer.pause();
buttonPlayStop.setText(getString(R.string.play_str));
seekBar.setProgress(0);
}
}
Then in the onSaveInstanceState()
method remove all callbacks from the handler.
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("current_position", seekbarPosition);
handler.removeCallbacks(notification);
}

Ron
- 24,175
- 8
- 56
- 97
-
Your code works properly in the first second of rotation but after that, the seek position doesn't follow the mediaplayer! it seems after rotation, the startPlayProgressUpdater() method doesnt work properly. – Milad Khajavi Sep 18 '11 at 10:30
-
I have updated the answer. remove the callbacks and make `notification` the member. – Ron Sep 18 '11 at 14:30
-
after many many effort, I couldn't find the solution. I need your help. – Milad Khajavi Sep 19 '11 at 10:17
0
I have changed the program in this way, solution below.
package org.example.java;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.SeekBar;
public class Player extends Activity implements OnClickListener, OnTouchListener, OnCompletionListener, Runnable {
private Button buttonPlayStop;
private MediaPlayer mediaPlayer;
private SeekBar seekBar;
private final Handler handler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d("Player", "got to onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initViews();
if (savedInstanceState != null) {
Log.d("Player", "got to savedInstanceState id not null");
mediaPlayer.seekTo(savedInstanceState.getInt("current_position"));
seekBar.setProgress(savedInstanceState.getInt("current_position"));
handler.post(this);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
Log.d("Player", "got to onSaveInstanceState()");
super.onSaveInstanceState(outState);
outState.putInt("current_position", mediaPlayer.getCurrentPosition());
handler.removeCallbacks(this);
Log.d("Player", "got to End of onSaveInstanceState");
}
private void initViews() {
Log.d("Player", "got to initViews()");
buttonPlayStop = (Button) findViewById(R.id.ButtonPlayStop);
buttonPlayStop.setOnClickListener(this);
mediaPlayer = MediaPlayer.create(this, R.raw.testsong_20_sec);
mediaPlayer.setOnCompletionListener(this);
seekBar = (SeekBar) findViewById(R.id.SeekBar01);
seekBar.setMax(mediaPlayer.getDuration());
seekBar.setOnTouchListener(this);
Log.d("player", "got to End of initViews()");
}
@Override
public void onClick(View v) {
Log.d("Player", "got to onClick");
switch (v.getId()) {
case R.id.ButtonPlayStop:
buttonClick();
break;
default:
break;
}
Log.d("Player", "got to End of onClick");
}
private void buttonClick() {
Log.d("Player", "got to buttonClick");
if (buttonPlayStop.getText() == getString(R.string.play_str)) {
buttonPlayStop.setText(R.string.pause_str);
try {
mediaPlayer.start();
Log.d("Player", "got to before startPlayProgressUpdater in buttonClick");
startPlayProgressUpdater();
} catch (IllegalStateException e) {
mediaPlayer.pause();
}
} else {
buttonPlayStop.setText(getString(R.string.play_str));
mediaPlayer.pause();
seekBar.setProgress(mediaPlayer.getCurrentPosition());
}
Log.d("Player", "got to End of buttonClick");
}
public void startPlayProgressUpdater() {
Log.d("Player", "got to startPlayProgressUpdater()");
seekBar.setProgress(mediaPlayer.getCurrentPosition());
int pos = mediaPlayer.getCurrentPosition();
Log.d("Player", "Current position is " + Integer.toString(pos));
Log.d("Player", "got to After seekBar.setProgress");
if (mediaPlayer.isPlaying()) {
Log.d("Player", "got to before handler.postDelayed");
handler.postDelayed(this, 1000);
Log.d("Player", "got to after handler.postDelayed");
} else if (mediaPlayer.getCurrentPosition() < mediaPlayer.getDuration()) {
mediaPlayer.pause();
buttonPlayStop.setText(R.string.play_str);
}
Log.d("Player", "got to End of startPlayProgressUpdater()");
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("Player", "got to onTouch");
seekChange(v);
return false;
}
private void seekChange(View v) {
Log.d("Player", "got to seekChange");
if (mediaPlayer.isPlaying()) {
SeekBar sb = (SeekBar) v;
mediaPlayer.seekTo(sb.getProgress());
}
}
@Override
public void run() {
Log.d("Player", "got to run()");
startPlayProgressUpdater();
Log.d("Player", "got to after startPlayProgressUpdater in run()");
}
@Override
public void onCompletion(MediaPlayer mp) {
mp.seekTo(0);
}
}
Update
After all I find the solution, but it is very dirty :D
package org.example.java;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.SeekBar;
public class Player extends Activity implements OnClickListener, OnTouchListener, OnCompletionListener, Runnable {
private Button buttonPlayStop;
private MediaPlayer mediaPlayer;
private SeekBar seekBar;
private final Handler handler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d("Player", "got to onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initViews();
if (savedInstanceState != null) {
Log.d("Player", "got to savedInstanceState id not null");
mediaPlayer.seekTo(savedInstanceState.getInt("current_position"));
seekBar.setProgress(savedInstanceState.getInt("current_position"));
mediaPlayer.start();
handler.post(this);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
Log.d("Player", "got to onSaveInstanceState()");
super.onSaveInstanceState(outState);
outState.putInt("current_position", mediaPlayer.getCurrentPosition());
handler.removeCallbacks(this);
Log.d("Player", "got to End of onSaveInstanceState");
pauseMedia();
}
private void initViews() {
Log.d("Player", "got to initViews()");
buttonPlayStop = (Button) findViewById(R.id.ButtonPlayStop);
buttonPlayStop.setOnClickListener(this);
mediaPlayer = MediaPlayer.create(this, R.raw.testsong_20_sec);
mediaPlayer.setOnCompletionListener(this);
seekBar = (SeekBar) findViewById(R.id.SeekBar01);
seekBar.setMax(mediaPlayer.getDuration());
seekBar.setOnTouchListener(this);
Log.d("player", "got to End of initViews()");
}
@Override
public void onClick(View v) {
Log.d("Player", "got to onClick");
switch (v.getId()) {
case R.id.ButtonPlayStop:
buttonClick();
break;
default:
break;
}
Log.d("Player", "got to End of onClick");
}
private void buttonClick() {
Log.d("Player", "got to buttonClick");
if (buttonPlayStop.getText() == getString(R.string.play_str)) {
buttonPlayStop.setText(R.string.pause_str);
try {
mediaPlayer.start();
Log.d("Player", "got to before startPlayProgressUpdater in buttonClick");
startPlayProgressUpdater();
} catch (IllegalStateException e) {
mediaPlayer.pause();
}
} else {
buttonPlayStop.setText(getString(R.string.play_str));
mediaPlayer.pause();
seekBar.setProgress(mediaPlayer.getCurrentPosition());
}
Log.d("Player", "got to End of buttonClick");
}
public void startPlayProgressUpdater() {
Log.d("Player", "got to startPlayProgressUpdater()");
seekBar.setProgress(mediaPlayer.getCurrentPosition());
int pos = mediaPlayer.getCurrentPosition();
Log.d("Player", "Current position is " + Integer.toString(pos));
Log.d("Player", "got to After seekBar.setProgress");
if (mediaPlayer.isPlaying()) {
Log.d("Player", "got to before handler.postDelayed");
handler.postDelayed(this, 1000);
Log.d("Player", "got to after handler.postDelayed");
} else if (mediaPlayer.getCurrentPosition() < mediaPlayer.getDuration()) {
mediaPlayer.pause();
buttonPlayStop.setText(R.string.play_str);
}
Log.d("Player", "got to End of startPlayProgressUpdater()");
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("Player", "got to onTouch");
seekChange(v);
return false;
}
private void seekChange(View v) {
Log.d("Player", "got to seekChange");
if (mediaPlayer.isPlaying()) {
SeekBar sb = (SeekBar) v;
mediaPlayer.seekTo(sb.getProgress());
}
}
@Override
public void run() {
Log.d("Player", "got to run()");
startPlayProgressUpdater();
Log.d("Player", "got to after startPlayProgressUpdater in run()");
}
@Override
public void onCompletion(MediaPlayer mp) {
mp.seekTo(0);
}
public void pauseMedia() {
mediaPlayer.pause();
}
}
Update 2:
I have find another way: using getLastNonConfigurationInstance() method.

Brock Adams
- 90,639
- 22
- 233
- 295

Milad Khajavi
- 2,769
- 9
- 41
- 66