2

I'm developing an App and I'm using a service to play background music. The music shall only play when the app is in use, means in foreground. The music shall stop when I leave app using Home button or back button (App may stay in background but is not visible -> no music). When I reenter the app (using home button and switch back to the app) the music shall resume too.

My Service:

public class MusicService extends Service {

MediaPlayer myPlayer;
private final IBinder localBinder = new LocalBinder();

public class LocalBinder extends Binder {

    MusicService getService() {
        return MusicService.this;
    }
}

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

public boolean onUnbind(Intent intent) {
    return true;
    // called when the last Activity is unbound from this service
    // stop your timed operations here
}


@Override
public void onCreate() {
    Toast.makeText(this, "Music Service Created", Toast.LENGTH_LONG).show();
    myPlayer = MediaPlayer.create(this, R.raw.ost);
    myPlayer.setLooping(true); // Set looping
}

@Override
public void onDestroy() {
    Toast.makeText(this, "Music Service Stopped", Toast.LENGTH_LONG).show();
    myPlayer.stop();
}

@Override
public void onStart(Intent intent, int startid) {
    Toast.makeText(this, "Music Service Started", Toast.LENGTH_LONG).show();
    if(!myPlayer.isPlaying())
        myPlayer.start();
}

}

I'm also using a parent class for all activites. In that parent class I want to stop the Service on the Methods onPause() and onStop():

ComponentName topActivity = taskInfo.get(0).topActivity; 
      if(!topActivity.getPackageName().equals(getApplicationContext().getPackageName())) {
          stopService(new Intent(this, MusicService.class));

I start the service on my launcher activity

startService(new Intent(this, MusicService.class));
        Intent intent = new Intent(this, MusicService.class);
        bindService(intent, this, 0);

Now to my problem: The service does not stop when I press the home button, the service does not stop when I leave the app (back button). When I kill the task of the app, the Service starts after a few seconds again and the music will run till I force the app in settings to stop the service or uninstall the app.

So how to shut down the service completely, when the app is in not visible background or closed? I've been through several threads here, youtube videos, tutorials and tried a lot. I also tried non-service solutions but I could not solve the problem.

Thank you!

AlcuPala
  • 21
  • 2
  • 1
    Service is used only when you want to do some background task, since you do not require a background task, you should not use Service, rather take the MediaPlayer controls on Application level – Bhavik Mehta Jan 17 '15 at 07:57
  • Then I would have to stop the mediaplayer when I start a new Activity and start the player again on the new activity. – AlcuPala Jan 17 '15 at 08:00
  • No, When create a MediaPlayer object at Application Level, you can navigate in any screen to any screen , the player will remain playing until you stop / pause it – Bhavik Mehta Jan 17 '15 at 08:12
  • Are you playing only one song? or changing the songs on some events? – Bhavik Mehta Jan 17 '15 at 08:14
  • It is just one song of 20 secs, repeating forever. – AlcuPala Jan 17 '15 at 08:17

1 Answers1

0

The Alternate way of implementing this functionality is here, however implementing using Service is the standard way

Make a class ApplicationContextHolder like below

public class ApplicationContextHolder extends Application {

    public static ApplicationContextHolder instance;

    public MediaPlayer mediaPlayerHome = new MediaPlayer();

    public static ApplicationContextHolder getAppInstance() {

        return instance;
    }

    public ApplicationContextHolder() {
        instance = this;
    }

    public void saveLastPlayingSongPath(String filePath) {
        songHolder = this.getSharedPreferences("songPath", 0);
        Editor editor = songHolder.edit();
        editor.putString("path", filePath);
        editor.commit();
    }


    public MediaPlayer getMediaPlayerForHome(Context ctx, int id) {
        return mediaPlayerHome = MediaPlayer.create(ctx, id);
    }

    public void stopMediaPlayerHome()

    {
        if (mediaPlayerHome != null && mediaPlayerHome.isPlaying()) {
            mediaPlayerHome.stop();
            mediaPlayerHome.reset();

        }
    }

    public void pauseMediaPlayerHome() {
        if (mediaPlayerHome != null && mediaPlayerHome.isPlaying()) {
            mediaPlayerHome.pause();

        }
    }

    public void startMediaPlayerHome() {
        if (mediaPlayerHome != null)
            mediaPlayerHome.start();
    }


}

Now, How to use this class 1) make an Object of this class and a MediaPlayer local object inside the Activity/Fragment in which you are having the media player or you can make it in MainActivity

private ApplicationContextHolder App;
private MediaPlayer mMediaPlayer;

2)Initialize objects in OnCreate

App = ApplicationContextHolder.getAppInstance();
mMediaPlayer = App.getMediaPlayerForHome(getActivity(),
                R.raw.new_introduction);

3) and at last in the event you want to play music player

App.startMediaPlayerHome();

4) And override the OnDestory() of the last Activity from which if Back Button is Pressed, The application will close

public void onDestroy() {

        try {
            App.stopMediaPlayerHome();

        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }

This are just the basic fundamentals, however you can use setLooping() / Pause(); and all the methods if you want

The Final Step is to register this class in your Manifest.xml in the first line of Application Tag as below

  <application
        android:name="yourpackagename.ApplicationContextHolder"

This is a working code of a live app, so please give it a try

For Home Button Event, You must use the following code in your each activity EDIT: This code now Pause the mediaplayer when you press Home,

@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_HOME)) {
            System.out.println("KEYCODE_HOME");
             try {
        App.pauseMediaPlayerHome();

    } catch (IllegalStateException e) {
        e.printStackTrace();
    }
            return true;
        }
    return false;
}

Suppose if you want to resume the music when the the app is resumed, you must check a boolean in the particular activity that

if (mediaplayerPaused)
App.startMediaPlayerHome();
Bhavik Mehta
  • 573
  • 8
  • 21
  • 1
    Thanks a lot for your efford. I will try it as soon as possible. – AlcuPala Jan 17 '15 at 08:44
  • Ok, I tested it and got the following problems. Music keeps playing when pressing home button. Music keeps playing when I switch to another activity and press back-button till the App closes (but I used the onDestroy method like you on the last Activity). – AlcuPala Jan 17 '15 at 08:58
  • @AlcuPala , Updated my answer, Didnt get your second point..! – Bhavik Mehta Jan 17 '15 at 09:12
  • Tried the onKeyDown. Did not change anything. Music still plays when leaving app via Home Button on device. Activity_1=Launcher activity: here I start the music player and the music plays. I switch to Activity_2. Music is still playing. Then I press Back-Button on device. Music is still playing (like it should). Then I press another time the Back-Button. App closes and music keeps playing. – AlcuPala Jan 17 '15 at 09:16
  • @AlcuPala Updated my answer again, When you press back button in last Activity, you are currently overriding the OnDestory() , it works in almost all devices , but do the same code in OnBackPressed of last Activity too – Bhavik Mehta Jan 17 '15 at 09:29
  • I really appreciate your help. But the onKeyDown method is not even fired. Testing with Emulatur a nexus 5 and Galaxy s4 here. Also on Debug the method doesn't get called on Home Button press. – AlcuPala Jan 17 '15 at 09:34
  • @AlcuPala, i understand what you are trying to telll me, have a look [Here](http://stackoverflow.com/questions/4783960/call-method-when-home-button-pressed-on-android)! – Bhavik Mehta Jan 17 '15 at 09:51
  • 1
    Thank you. I will try using isFinished at onPause(). Thanks a lot for your time! – AlcuPala Jan 17 '15 at 09:53
  • @AlcuPala , you are welcome, my friend! Also try to implement it using Service when you get free time – Bhavik Mehta Jan 17 '15 at 09:55