Search code examples
androidandroid-intentandroid-serviceandroid-mediaplayerandroid-service-binding

How to stop multiple android services in a List of services that use MediaPlayer to play many songs simultaneously?


Hey guys sorry if this has been asked before but I have been reading other answers and documentation for more than 3 hours with no success, I really can't find how to solve this problem.

Description

So I have this List:

private List<MusicService> songList;

And adding to it all my needed services:

private Intent rainIntent;
private Intent stormIntent;
private Intent oceanIntent;

Then I initialize them:

    rainIntent = new Intent(this, MusicService.class);
    stormIntent = new Intent(this, MusicService.class);
    oceanIntent = new Intent(this, MusicService.class);

Then I pass them the ID of songs I want to play onStartCommand()

    rainIntent.putExtra(MusicService.SONG_ID, R.raw.rain);
    songsIntentsList.add(rainIntent);
    stormIntent.putExtra(MusicService.SONG_ID, R.raw.thunder);
    songsIntentsList.add(stormIntent);
    oceanIntent.putExtra(MusicService.SONG_ID, R.raw.ocean);
    songsIntentsList.add(oceanIntent);

When I use the list to start all services there's no problem, this works fine:

private void startSongsServices() {

    for (Intent intent : songsIntentsList) {
        context.startService(intent);
    }

}

My problem:

But when trying to use stopService() it doesn't work what can I do? Just like the following:

private void stopSongsServices() {

    for (Intent intent : songsIntentsList) {
        context.stopService(intent);
    }

}

This is the class for MusicService:

public class MusicService extends Service {


    private MediaPlayer mMediaPlayer = null;

    public static String SONG_ID = null;


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

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        int id = intent.getExtras().getInt(SONG_ID);

        mMediaPlayer = MediaPlayer.create(this,id);


        if (!mMediaPlayer.isPlaying()) {
            mMediaPlayer.start();

        }

        return START_STICKY; //START_STICKY makes service run until we call onDestroy() service to stop it
    }

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

        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}

How can I stop all this services when needed?


Solution

  • onDestroy will be called only once.

    You need to keep track of media player objects you are creating and stop them in a loop.Right now you are creating 3 mediaplayer objects(onStartCommand is getting called 3 times) but releasing only one.

    Something like below

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
        int id = intent.getExtras().getInt(SONG_ID);
    
        mMediaPlayer = MediaPlayer.create(this,id);
        mediaPlayerObjectsList.add(mMediaPlayer);
    }
    

    Then in onDestroy() do something like this:

      for (MediaPlayer player : mediaPlayerObjectsList) {
            player.release();
        }