Playing BG Music Across Activities in Android
Asked Answered
A

7

32

Hello! First time to ask a question here at stackoverflow. Exciting! Haha.

We're developing an Android game and we play some background music for our intro (we have an Intro Activity) but we want it to continue playing to the next Activity, and perhaps be able to stop or play the music again from anywhere within the application.

What we're doing at the moment is play the bgm using MediaPlayer at our Intro Activity. However, we stop the music as soon as the user leaves that Activity. Do we have to use something like Services for this? Or is MediaPlayer/SoundPool enough? If anyone knows the answer, we'd gladly appreciate your sharing it with us. Thanks!

Advection answered 19/1, 2010 at 23:6 Comment(1)
I have just come across the same issue, and was wondering how you know when to stop the music? If you stop the service onDestroy then it will stop it between subactivities - how do you know when the last game activity is closed to stop the music?Propitiatory
F
10

You can also create a service which play music using mediaplayer as below.

Intent svc=new Intent(this, BackgroundSoundService.class);
startService(svc); //OR stopService(svc); 

public class BackgroundSoundService extends Service {
    private static final String TAG = null;
    MediaPlayer player;
    public IBinder onBind(Intent arg0) {

        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();


        player = MediaPlayer.create(this, R.raw.idil);
        player.setLooping(true); // Set looping
        player.setVolume(100,100);

    }
    public int onStartCommand(Intent intent, int flags, int startId) {


        player.start();

        return 1;
    }

    public void onStart(Intent intent, int startId) {
        // TODO



    }
    public IBinder onUnBind(Intent arg0) {
        // TODO Auto-generated method stub

        return null;
    }

    public void onStop() {

    }
    public void onPause() {

    }
    @Override
    public void onDestroy() {

        player.stop();
        player.release();
    }

    @Override
    public void onLowMemory() {

    }
}
Flatling answered 12/6, 2010 at 12:35 Comment(0)
K
6

Create a static SoundManager using either SoundPools or MediaPlayers.

Create a static flag called keepMusicGoing.

Start the music when the first activty is created.

When switching actvities set keepMusicGoing to true.

On the onStop event of your activities check if keepMusicGoing is true,if so leave the music on, then set keepMusicGoing to false.

If they press the home button the keepMusicGoing flag will be false so the music will stop when the activity loses focus.

Email me and I can send you a couple SoundManagers that I wrote one uses MediaPlayers and the other SoundPools

Chad

Knowledge answered 16/6, 2010 at 20:17 Comment(4)
Yes, this was also how we did it. vladikoff posted the link to where we got the idea of using a static manager for the music.Advection
hey chad can you send me those examples. My email id is [email protected].Proposition
I'm runnin into a problem with this approach. My app supports rotations and when the device is rotated onStop is called and it's also called when the user presses home. When rotating i don't want to stop music but when home is pressed i do, don't know how to differentiate the events, any ideas?Earthen
Perfect! A bit tricky to understand but works great! Thanks for sharing!Kilmarx
C
2

If I understand your situation correctly, then I have confronted the same problem a few times. I am using a different thread to play music in my applications. This implementation passes a static reference to a Context that I know will be alive for the time that the music will be playing.

public class AudioPlayer extends Thread {
private Context c;
private Thread blinker;
private File file;

public AudioPlayer (Context c, File file) {
    this.c = c;
    this.file = file;
}

public void go () {
    blinker = this;
    if(!blinker.isAlive()) {
        blinker.start();
    }
}

public void end () {
    Thread waiter = blinker;
    blinker = null;
    if (waiter != null)
        waiter.interrupt ();
}

public void run () {
    MediaPlayer ap = MediaPlayer.create(c, Uri.fromFile(file));
    int duration = ap.getDuration();
    long startTime = System.currentTimeMillis();
    ap.start();
    try {
        Thread thisThread = Thread.currentThread();
        while (this.blinker == thisThread && System.currentTimeMillis() - startTime < duration) {           
            Thread.sleep (500);  // interval between checks (in ms)
        }
        ap.stop ();
        ap.release ();
        ap = null;
    } catch (InterruptedException e) {
        Log.d("AUDIO-PLAYER", "INTERRUPTED EXCEPTION");
        ap.stop ();
        ap.release();
        ap = null;
    }
    }
}
Comestible answered 10/6, 2010 at 18:18 Comment(0)
W
2

First i used the method where to keep a "keepMusicPlaying" flag provided by Chad. I think its more elegant to just use the onStart and onStop methods of your activitys.

Create an own class "SoundManager" and call some onStart and onStop classes in it from all your activitys onStart and onStop (or use a base activity class). Keep track of the onStart and onStop with a startCounter(startCounter++ in onstart and startCounter-- in onstop). Because the start of a new activity is called before the onStop of the old activity you always know if the onStart is called for the first Time (startCounter == 1) or started from another of your activitys (startCounter == 2). Same with the onStope(startCounter == 0 means the App was closed, startCounter == 1 means its just the stop from an old activity but there is a new).

This way you encapsulate everything into your SoundManager instead of having to call some keepMusicPlaying method/flag on every activity start inside your app.

    public void OnStart()
    {
        startCounter++;
        if (startCounter == 1)
        {
            //start music here
        }

    public void OnStop()
    {
        startCounter--;
        if (startCounter == 0)
        {
            // stop music here
        }
    }
Wiring answered 20/7, 2015 at 10:24 Comment(0)
O
1

You can try using the AsyncPlayer but you should keep a reference to the class in order to stop the sound from playing.

You can create a Uri to a local resource using Uri uri = Uri.parse("android.resource://com.stackoverlof.android/raw/ beep.mp3");.

Hope this helps.

Ovoviviparous answered 10/6, 2010 at 20:48 Comment(0)
T
0

By combining Chad's and Kedu's answers and adding my own flavor, I created this working solution:

// Parent Activity which every Activity extends
public class ParentActivity extends AppCompatActivity {

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

    @Override
    protected void onStart() {
        super.onStart();
        Music.onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
        Music.onStop();
    }
}
// Controller class for handling background music
public abstract class Music {

    private static MediaPlayer mediaPlayer;
    private static int startCounter = 0;

    public static void onStart() {
        startCounter++;
        if (startCounter == 1) {
            mediaPlayer = MediaPlayer.create(InitializeActivity.getContext(), R.raw.background_music);
            mediaPlayer.setLooping(true);
            mediaPlayer.setVolume(1f, 1f);
            mediaPlayer.start();
        }
    }

    public static void onStop() {
        startCounter--;
        if (startCounter == 0) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }
    }
}

And that's it, super simple!

Thomajan answered 3/4, 2020 at 9:35 Comment(0)
V
0

create a class with one static MediaPlayer so the instance will be the same every time you call it ( because it is static)

Variety answered 29/1, 2024 at 19:49 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.