16

I'm new to Android and I have to create MediaPlayer for playing the audio music. When start my activity song starts playing. But when I change the orientation on my emulator screen MediaPlayer is reinitialized and another audio starts playing. How can I avoid it?

Here is my code:

public class Audio_Activity extends Activity {


MediaPlayer mp = null;


    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        if(isLaunched)
        {
            setContentView(R.layout.audio);
        }

        SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
        length = settings.getInt("TheOffset", 0);
        init();
        prefs = PreferenceManager.getDefaultSharedPreferences(this);
        mp = MediaPlayer.create(getApplicationContext(), R.raw.subhanallah);
        playMusic();


        mp.setOnCompletionListener(new OnCompletionListener() 
        {

            @Override
            public void onCompletion(MediaPlayer arg0) 
            {
                // TODO Auto-generated method stub

            }
        });


    }

    private void playMusic() 
    {
        httpGetAsynchTask httpGetAsyncTask = new httpGetAsynchTask();
        httpGetAsyncTask.execute();
    }



    class httpGetAsynchTask extends AsyncTask<String,Integer, Void>
    {

        protected void onPreExdcute()
        {

        }

        @Override
        protected Void doInBackground(String... arg0)
        {
            // TODO Auto-generated method stub

            final SharedPreferences.Editor prefsEdit = prefs.edit();

            Log.e("Song is playing", "in  Mediya Player ");

            mp.setLooping(false);
            mp.start();
            int millisecond=mp.getDuration();
            Log.e("Song is playing", "in  Mediya Player " + millisecond);

            prefsEdit.putBoolean("mediaplaying", true);
            prefsEdit.commit();
            //btnChapter.setEnabled(false);

            return null;

        }

        protected void onPostExecute(Void result)
        {
            super.onPostExecute(result);
            btnChapter.setEnabled(false);
        }

    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        Configuration config=getResources().getConfiguration();
        if(config.orientation == Configuration.ORIENTATION_PORTRAIT)
        {
            setContentView(R.layout.audio);
        }
        else if(config.orientation == Configuration.ORIENTATION_LANDSCAPE)
        {
            setContentView(R.layout.audio);
        }
    }

    @Override
    public void onPause() {
        super.onPause();


        SharedPreferences.Editor prefsEdit = prefs.edit();
        boolean isPlaying = prefs.getBoolean("mediaplaying", false);
        if (isPlaying)
        {
            mp.pause();
            int position = mp.getCurrentPosition();
            Log.e("Current ", "Position -> " + position);
            prefsEdit.putInt("mediaPosition", position);
            prefsEdit.commit();
        }
    }

    @Override
    protected void onResume() {

        super.onResume();

        mp.start();

        boolean isPlaying = prefs.getBoolean("mediaplaying", false);
        if (isPlaying) {
            int position = prefs.getInt("mediaPosition", 0);
            mp.seekTo(position);
            // mp.start();


        }
    } 

}

And I have done some changes in Manifest.xml file.

< android:configChanges="orientation|screenSize|keyboard" >

and create layout-land folder .

Why is the music playing twice?

halfer
  • 19,824
  • 17
  • 99
  • 186
tazeenmulani
  • 600
  • 5
  • 18
  • 43

11 Answers11

9

Simplest Answer for this question.

@Override
protected void onSaveInstanceState(Bundle outState) 
{
    outState.putInt("possition", mpbg.getCurrentPosition());
    mpbg.pause();
    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) 
{
    int pos = savedInstanceState.getInt("possition");
    mpbg.seekTo(pos);
    super.onRestoreInstanceState(savedInstanceState);
}
Shabbir Dhangot
  • 8,954
  • 10
  • 58
  • 80
4

When we declare mediaplayer as a static variable then only one instance of mp will exist. Suppose our Activity orientation changes now, Everything will be recreated on orientation change but Mp variable will not be recreated because of static property. In this way we just make a condition

if(mp!=null && !mp.isPlaying()){ 
    mp = MediaPlayer.create(getApplicationContext(), R.raw.subhanallah);
    playMusic(); 
} 

in our onCreate() method, this will check whether music is already playing or not, if its playing then if condition will not allow application to start music player again. and if Music is not playing then if condition will allow the application to restart the music.


Here is your update code:

public class Audio_Activity extends Activity {


static MediaPlayer mp = null;


    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        if(isLaunched)
        {
            setContentView(R.layout.audio);
        }

        SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
        length = settings.getInt("TheOffset", 0);
        init();
        prefs = PreferenceManager.getDefaultSharedPreferences(this);
        if(mp == null) 
        {
            initializeMP();
        }
        if(!mp.isPlaying())
        {
             playMusic();
        }

        mp.setOnCompletionListener(new OnCompletionListener() 
        {

            @Override
            public void onCompletion(MediaPlayer arg0) 
            {
                // TODO Auto-generated method stub

            }
        });


    }

    private void playMusic() 
    {
        httpGetAsynchTask httpGetAsyncTask = new httpGetAsynchTask();
        httpGetAsyncTask.execute();
    }

    public void initializeMP()
    {
          mp = MediaPlayer.create(getApplicationContext(), R.raw.subhanallah);

    }

    class httpGetAsynchTask extends AsyncTask<String,Integer, Void>
    {

        protected void onPreExdcute()
        {

        }

        @Override
        protected Void doInBackground(String... arg0)
        {
            // TODO Auto-generated method stub

            final SharedPreferences.Editor prefsEdit = prefs.edit();

            Log.e("Song is playing", "in  Mediya Player ");

            if(mp == null)
            {
                initializeMP()
            }
            mp.setLooping(false);
            mp.start();
            int millisecond=mp.getDuration();
            Log.e("Song is playing", "in  Mediya Player " + millisecond);

            prefsEdit.putBoolean("mediaplaying", true);
            prefsEdit.commit();
            //btnChapter.setEnabled(false);

            return null;

        }

        protected void onPostExecute(Void result)
        {
            super.onPostExecute(result);
            btnChapter.setEnabled(false);
        }

    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        Configuration config=getResources().getConfiguration();
        if(config.orientation == Configuration.ORIENTATION_PORTRAIT)
        {
            setContentView(R.layout.audio);
        }
        else if(config.orientation == Configuration.ORIENTATION_LANDSCAPE)
        {
            setContentView(R.layout.audio);
        }
    }

    @Override
    public void onPause() {
        super.onPause();


        SharedPreferences.Editor prefsEdit = prefs.edit();
        boolean isPlaying = prefs.getBoolean("mediaplaying", false);
        if (isPlaying)
        {
            if(mp!=null)
            {
                 mp.pause();
            }
            int position = mp.getCurrentPosition();
            Log.e("Current ", "Position -> " + position);
            prefsEdit.putInt("mediaPosition", position);
            prefsEdit.commit();
        }
    }

    @Override
    protected void onResume() {

        super.onResume();
        if(mp == null)
        {
            initializeMP();
        }
        mp.start();

        boolean isPlaying = prefs.getBoolean("mediaplaying", false);
        if (isPlaying) {
            int position = prefs.getInt("mediaPosition", 0);
            mp.seekTo(position);
            // mp.start();


        }
    } 

}
animuson
  • 53,861
  • 28
  • 137
  • 147
Ahmad Raza
  • 2,850
  • 1
  • 21
  • 37
  • My Application is crash. – tazeenmulani Jul 29 '13 at 11:14
  • please post your log here. Thanks, – Ahmad Raza Jul 29 '13 at 11:53
  • D/AndroidRuntime(718): Shutting down VM , E/AndroidRuntime(718): FATAL EXCEPTION: main , E/AndroidRuntime(718): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.tutorialmediaplayer/com.audio_demo.Audio_Activity}: java.lang.ClassNotFoundException: com.audio_demo.Audio_Activity in loader dalvik.system.PathClassLoader[/data/app/com.tutorialmediaplayer-2.apk] , java.lang.ClassNotFoundException: com.audio_demo.Audio_Activity in loader dalvik.system.PathClassLoader[/data/app/com.tutorialmediaplayer – tazeenmulani Jul 29 '13 at 11:56
  • 1
    Its class not found exception, please check that is Audio_Activity spelled correctly in src folder. and also check it manifest.xml. – Ahmad Raza Jul 29 '13 at 11:58
  • 1
    also check the package name. please confirm that your package name with similar with the name you define in manifest.xml – Ahmad Raza Jul 29 '13 at 12:00
  • 1
    please post you menifest.xml file here. Thanks, – Ahmad Raza Jul 29 '13 at 12:01
  • Can u tell me Ahmad this Menifest.xml file is this right . – tazeenmulani Jul 29 '13 at 12:57
  • 1
    yeah, this is right, now Please check your package name. You Package name should be "com.tutorialmediaplayer", In this package place this activity "Audio_Activity". – Ahmad Raza Jul 29 '13 at 13:17
  • Thanks Ahmad for the help. Thank u so much for your great idea . I have solved my problem for orientation.But something is wrong in my app on back-press key and home-key for pause.I w'll try. – tazeenmulani Jul 29 '13 at 13:26
  • I have checked package name and class name also both are right in menifest.xml file. But i don't know where is the problem.I fade up this demo. – tazeenmulani Jul 29 '13 at 13:42
  • 1
    you should create a new project. While creating new project. Set Activity name "Audio_Activity", put your layout in layout file. and simply put my code in Audio_Activity.java. – Ahmad Raza Jul 29 '13 at 14:47
  • Can i create layout-land one more folder for landscape. – tazeenmulani Jul 30 '13 at 09:58
  • I'm facing some issues are there can you help me one more . Please!! – tazeenmulani Jul 30 '13 at 11:32
  • When i press home button or back button its pause and resume properly.When song get over and i restart again my Activity only play the first word and finish immediate. This does not restart proper.Why so it ? – tazeenmulani Jul 30 '13 at 11:48
  • 1
    That's fairly bad practice for Android. – afollestad Dec 09 '15 at 19:57
3

For tasks like this you should use a Service since it won't be re-initialized when the orientation changes.

Aballano
  • 1,037
  • 12
  • 19
3

So I wrestled with this for quite a time, but I finally figured it out. What you want to do is make your Mediaplayer a static member variable of the class, similar to the top answer here. However, the pitfall you want to avoid is using the "convenient" create() method. This actually creates a new instance of the mediaplayer every time it is called, even if it is static. What you want to do instead is something like this:

static MediaPlayer m = new MediaPlayer();

Now wherever in your code you want to create the player, do something like this:

m.reset();

try{
        m.setDataSource(getApplicationContext(),Uri.parse("android.resource://com.example.app/" + R.raw.soundId));
        m.prepare();

}catch(java.io.IOException e){ }

m.seekTo(pos);
m.start();

The point of this is that create(), while convenient, is really only nice when you are not changing orientation ever, because it will keep creating new instances and quickly use up memory. Creating one static member and re-using it each time onCreate() is called is much cleaner and simpler. Reset() puts the player in the correct state for it to be re-used.

2
public void onSaveInstanceState(Bundle savedInstanceState) {

    super.onSaveInstanceState(savedInstanceState);

    savedInstanceState.putInt("Position", mediaPlayer.getCurrentPosition());
    savedInstanceState.putBoolean("isplaying", mediaPlayer.isPlaying());

     if (mediaPlayer.isPlaying())
          mediaPlayer.pause();

}


@Override

public void onRestoreInstanceState(Bundle savedInstanceState) {

    super.onRestoreInstanceState(savedInstanceState);

    position = savedInstanceState.getInt("Position");
    mediaPlayer.seekTo(position);
     if (savedInstanceState.getBoolean("isplaying"))
         mediaPlayer.start();



}
anfd
  • 121
  • 2
  • 11
1

A media player also should play music if the activity is not on top. So you better a use a service, which is then independent from screen orientation and other things:

Start reading http://developer.android.com/guide/components/services.html carefully. Especially START_STICKY is important for a media player service.

Philipp
  • 11,549
  • 8
  • 66
  • 126
1

Are you sure that you put

< android:configChanges="orientation|screenSize|keyboard" >

at the right place? you have to put it in the activity of your player not any other activity or outside the activity.. As an example I used it like this in my manifest:

<activity android:name=".PlayerActivity" android:label="@string/title_activity_player" android:noHistory="true" android:configChanges="orientation|screenSize"> </activity>

and it works.. hope it helps..

Burcak Kam
  • 251
  • 2
  • 5
1

You need to use this code an dont forget to android:configChanges="orientation|screenSize"add this in your manifest activity

@Override
public void onConfigurationChanged(Configuration newConfig) {
   super.onConfigurationChanged(
   if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
     //if you are using mediaplayer than u need to mp.getCurrentPosition();
       int currentPosition = vv.getCurrentPosition();
       vv.seekTo(currentPosition);
   }
    else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        int currentPosition = vv.getCurrentPosition();
        vv.seekTo(currentPosition);  
    }
}
Angel F Syrus
  • 1,984
  • 8
  • 23
  • 43
Herry patel
  • 39
  • 1
  • 3
  • android:configChanges="orientation|screenSize" = I have added this code to the relevant activity in the manifest file. And the sound continued to flow even as the screen changed direction while the sound was playing. – serif Apr 14 '22 at 16:52
0

When you change orientation activity is destroyed and recreated.

You can save the actual progress of the video in onSaveInstanceState() and get the saved data in onRestoreInstanceState() from the Bundle, after that you can start the playing with either the progress data, or from the beginning if there was no data saved.

Mark McK
  • 84
  • 2
  • 2
  • 12
  • how can i know in portriat mode either i have to play video or not ...bcause if user has pause video in landscape then it should remain pause while if video was playing then it should play .... – Erum Sep 17 '15 at 06:17
0

Besides using 'Service', one more solution would be to implement the 'onOrientationChange' method in your activity. Same has to be applied to manifest file of the activity as ' android:configChanges="orientation|keyboardHidden" '; which you have already done.

In 'onOrientationChange' method. get the current playing position and give that to media player object and play again.

By doing this, it will not create new object of media player and uses the same with current position.

Jayesh Elamgodil
  • 1,467
  • 11
  • 15
0

Because I've also struggled with this problem many times, I've decided to create a POC to be used as a reference. This example uses configChanges flag and handles the resizing manually. It works quite well IMHO

https://github.com/caspercba/POCMediaPlayerRotation

Gaspar de Elias
  • 244
  • 3
  • 12