Reputation: 3373
This is my code, I tried ti build simple application that plays a song whenever I click one button (clicking twice will play the song a new from the beginning) & stop playing when another button is pushed. I wanted that when the user put the activity in the background the media player will "save its state" - continue playing/not playing - and when the activity returns to the foreground the interaction will remain the same. Instead it works fine until I put the activity in the background (then it keeps playing/not playing) but when I return it back it seems like "a new media player object was created" and if I click play while the song is played, it starts to play the song from the beginning simultaneously with the previous one, and clicking stop - stopping only the new "instance" of the song. Like I loose connection with the media player after the activity is in the background. what could be the problem?
public class MainActivity extends ActionBarActivity {
private MediaPlayer mediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonStart = new Button(this);
Button buttonStop = new Button(this);
buttonStart.setText(R.string.button_start_text);
buttonStop.setText(R.string.button_stop_text);
buttonStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startPlaying();
}
});
buttonStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopPlaying();
}
});
ViewGroup layout = (ViewGroup) findViewById(R.id.mainLayout);
layout.addView(buttonStart);
layout.addView(buttonStop);
}
void startPlaying(){
stopPlaying();
mediaPlayer = MediaPlayer.create(this,R.raw.dreams);
mediaPlayer.start();
}
void stopPlaying(){
if (mediaPlayer != null){
try {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
I changed the code also, like this (now there are 3 buttons: play, stop, pause:
void startPlaying(){
if (mediaPlayer == null) {
mediaPlayer = MediaPlayer.create(this, R.raw.dreams);
}
mediaPlayer.start();
}
void stopPlaying(){
if (mediaPlayer != null){
try {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.prepare();
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
void pausePlaying(){
if (mediaPlayer != null) mediaPlayer.pause();
}
but still same behaviour.
Some insight I got:
before the user place the activity in the background the member mediaPlayer
is some constructed android object.
when the activity returns to the foregound mediaPlayer
is null.
Why is this?
Maybe I got wrong the idea of activity but I thought it keeps its members with their values during its life cycle.
Upvotes: 1
Views: 143
Reputation: 3373
http://developer.android.com/guide/components/activities.html
Saving activity state gives a detailed information that could explain what happened.
In short when activity is in the background it might be killed and created again by OS when user navigate it back to foreground.
onSaveInstanceState()
should be implemented unless only UI objects are restored
but not class members
Upvotes: 0
Reputation: 133
Your are creating and destroying your mediaplayer everytime. Try to create two methods for pause and resume/start like that.
below you can find the code that is working fine for me. I am developing a game that starts a main theme when the activity loads. Each time the activity resumes, the media player continue to play the song at the paused position. I override onDestroy() to stop, onResume to start/resume and onPause() to pause when the activity goes Background.
public MediaPlayer mp=null;
@Override
protected void onDestroy() {
if (mp!=null)
mp.stop();
super.onStop();
}
@Override
protected void onResume() {
super.onResume();
if (mp==null){
self=this;
Thread thMusic= new Thread(new Runnable(){
public void run(){
mp= MediaPlayer.create(self,R.raw.dizzy );
mp.start();
}
});
thMusic.start();
}
else
mp.start();
}
@Override
protected void onPause() {
if (mp!=null)
mp.pause();
super.onPause();
}
i hope this will help you.
Upvotes: 1