Android Mediaplayer Service

2

I have a service that runs with mediaplayer the thing is that when you close it stops playing the song and the service restarts, I want to keep the song playing normally even if the application is closed as it is a service

    public class ForegroundService extends Service{

    MediaPlayer player;

    @Override
    public void onCreate(){
        super.onCreate();
        player=MediaPlayer.create(this,R.raw.chu);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        player.start();



        return Service.START_STICKY;
    }
    @Override
    public void onDestroy(){
        super.onDestroy();
        if(player!=null){
            player.pause();
            player.release();
        }

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
    
asked by Felipe Peña 12.09.2017 в 08:03
source

1 answer

1

Regarding what you are saying:

  

when closing it stops playing the song and the service restarts

This is because you are defining Service.START_STICKY , when you close the application the service is recreated and replay from 0:

  

Service.START_STICKY : Recreate the service if the application is   destroy.:

There is no property to continue playing the MediaPlayer when the application is destroyed. But you can do this by saving the playback position and when the service is restarted, if there is a saved position greater than 0 (starting position), then playback continues.

public class Preferences {

    private static final String PREFS = "SoundPreferences";

    public static void setMediaPosition(Context ctx, int position) {
        SharedPreferences prefs = ctx.getSharedPreferences(PREFS, Context.MODE_PRIVATE);
        prefs.edit().putInt("position", position).apply();
    }

    public static int getMediaPosition(Context ctx) {
        SharedPreferences prefs = ctx.getSharedPreferences(PREFS, Context.MODE_PRIVATE);
        return prefs.getInt("position", 0);
    }

}

First configure your service within the AndroidManifest.xml file, it is important to add the android:stopWithTask="false" property:

this so that when the destruction of the application is done call the onTaskRemoved() method, where the last playback position will be saved:

@Override
    public void onTaskRemoved(Intent rootIntent) {
        Log.i(TAG, "onTaskRemoved(), save current position: " + player.getCurrentPosition());
        //instead of stop service, save the current position.
        //stopSelf();
        Preferences.setMediaPosition(getApplicationContext(), player.getCurrentPosition());
    }

When you start the service (since you have configured Service.START_STICKY , it will play) from the saved position.

public int onStartCommand(Intent intent, int flags, int startId) {
    Log.i(TAG, "onStartCommand()");
    if(Preferences.getMediaPosition(getApplicationContext())>0){
        Log.i(TAG, "onStartCommand(), position stored, continue from position : " + Preferences.getMediaPosition(getApplicationContext()));
        player.start();
        player.seekTo(Preferences.getMediaPosition(getApplicationContext()));
    }else {
        Log.i(TAG, "onStartCommand() Start!...");
        player.start();
    }
    //re-create the service if it is killed.
    return Service.START_STICKY;
}

This is an example code of a service that performs the above described:

public class BackgroundSoundService extends Service {

    private static final String TAG = "BackgroundSoundService";
    MediaPlayer player;

    public IBinder onBind(Intent arg0) {
        Log.i(TAG, "onBind()" );
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate()");
        player = MediaPlayer.create(this, R.raw.jorgesys_song);
        player.setLooping(true); // Set looping
        player.setVolume(100,100);
        Toast.makeText(this, "Service started...", Toast.LENGTH_SHORT).show();
    }
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand()");
        if(Preferences.getMediaPosition(getApplicationContext())>0){
            Log.i(TAG, "onStartCommand(), position stored, continue from position : " + Preferences.getMediaPosition(getApplicationContext()));
            player.start();
            player.seekTo(Preferences.getMediaPosition(getApplicationContext()));
        }else {
            Log.i(TAG, "onStartCommand() Start!...");
            player.start();
        }
        //re-create the service if it is killed.
        return Service.START_STICKY;
    }

    public IBinder onUnBind(Intent arg0) {
        Log.i(TAG, "onUnBind()");
        return null;
    }

    public void onStop() {
        Log.i(TAG, "onStop()");
        Preferences.setMediaPosition(getApplicationContext(), player.getCurrentPosition());
    }

    public void onPause() {
        Log.i(TAG, "onPause()");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy() , service stopped! Media position: " + player.getCurrentPosition());
        //Save current position before destruction.
        Preferences.setMediaPosition(getApplicationContext(), player.getCurrentPosition());
        player.pause();
        player.release();
    }

    @Override
    public void onLowMemory() {
        Log.i(TAG, "onLowMemory()");
        Preferences.setMediaPosition(getApplicationContext(), player.getCurrentPosition());
    }

    //Inside AndroidManifest.xml add android:stopWithTask="false" to the Service definition.
    @Override
    public void onTaskRemoved(Intent rootIntent) {
        Log.i(TAG, "onTaskRemoved(), save current position: " + player.getCurrentPosition());
        //instead of stop service, save the current position.
        //stopSelf();
        Preferences.setMediaPosition(getApplicationContext(), player.getCurrentPosition());
    }

}
    
answered by 12.09.2017 / 16:22
source