I have a media player service that plays music in the background of my app throughout activities like :
public class Music extends Service {
MediaPlayer player;
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void onCreate() {
player = MediaPlayer.create(this, R.raw.music);
player.setLooping(true);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return Service.START_NOT_STICKY;
}
public void onDestroy() {
player.stop();
player.release();
stopSelf();
super.onDestroy();
}
The problem is that when the user changes app or goes to home screen of phone(app goes in the background) the music is still playing.
I have tried to stop it in onStop
and onDestroy
method but this stops the music when I change activities which is something that I don't want(I want the music to keep playing when user navigates through activities).
Update
I tried with broadcast:
I added
LocalBroadcastManager.getInstance(this).registerReceiver(StateReceiver, new IntentFilter("status"));
in onCreate of music Service and a method to receive events :
private BroadcastReceiver StateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String status = intent.getStringExtra("status");
if (parseInt(String.valueOf(status)) == 0) {
player.stop();
}else{player.start();}
}
};
And in Application class I did this:
public class app_class extends Application implements Application.ActivityLifecycleCallbacks {
private static int resumed;
private static int paused;
private static String currentActivity;
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
currentActivity = activity.getClass().getSimpleName();
}
public static String getCurrentActivity() {
return currentActivity;
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
send_status(1);
}
@Override
public void onActivityPaused(Activity activity) {
send_status(0);
}
private void send_status(int status_counter) {
Intent intent = new Intent("status");
intent.putExtra("status", String.valueOf(status_counter));
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
But the music wont resume
You need to prepare the player again after stopping it. If you want to stop the playback when your app goes in background, and start the media from the beginning when your app comes into foreground. Just modify your BroadcastReceiver code to this:
However, if you want to pause the playback and resume it from where you left, then make the following changes: In your Application class, in onActivityDestroyed():
and in the BroadcastReceiver:
Also, have a look at the MediaPlayer states.
You could add this in your application class to check whether your app is in the foreground or not.
Add this to your application like this :
On receiving the broadcast in service you can stop mediaplayer.
Edit
You need to change your application class to this :
Have you implemented onDestroy()? If not, I believe that might be the solution - and you stop your Player or whatever you're using to run the service within onDestroy().
Besides using the broadcast receiver as RoyalGriffin answered, the problem with the little interruption of the music can be solve by implementing
LifecycleObserver
interface. You can know when the app is in foreground or background, and that way, there is no need of handled the states of every activity.Implement
Application.ActivityLifecycleCallbacks
in your app with his methods@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
and@OnLifecycleEvent(Lifecycle.Event.ON_START)
then add this line to the onCreate()
Your app_class would be something like this: