Остановить службу MediaPlayer, когда приложение переходит в фоновый режим - PullRequest
0 голосов
/ 13 июня 2018

У меня есть медиаплеер, который воспроизводит музыку в фоновом режиме моего приложения во время таких действий, как:

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();
}

Проблема заключается в том, что когда пользователь меняет приложение или переходит на домашний экран телефона (приложение выходитна заднем плане) музыка все еще играет.

Я пытался остановить ее в методах onStop и onDestroy, но это останавливает музыку, когда я меняю действия, что мне не нужно (Я хочу, чтобы музыка продолжала воспроизводиться, когда пользователь перемещается по действиям).

Обновление

Я пытался с трансляцией:

Я добавил

LocalBroadcastManager.getInstance(this).registerReceiver(StateReceiver, new IntentFilter("status"));

в onCreate of Music Service и способ получения событий:

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();}

    }
};

А в классе приложения я сделал это:

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) {

}   

Номузыка не возобновится

Ответы [ 4 ]

0 голосов
/ 12 декабря 2018

Помимо использования вещательного приемника, как ответил RoyalGriffin, проблему с небольшим прерыванием музыки можно решить с помощью интерфейса LifecycleObserver.Вы можете знать, когда приложение находится на переднем плане или в фоне, и таким образом нет необходимости обрабатывать состояния каждого действия.

Реализация Application.ActivityLifecycleCallbacks в вашем приложении с помощью его методов @OnLifecycleEvent(Lifecycle.Event.ON_STOP) и @OnLifecycleEvent(Lifecycle.Event.ON_START)

затем добавьте эту строку в onCreate ()

ProcessLifecycleOwner.get().getLifecycle().addObserver(this);

Ваш app_class будет выглядеть примерно так:

    public class app_class extends Application implements LifecycleObserver, 
    Application.ActivityLifecycleCallbacks{
    private static int resumed;
    private static int paused;

    private static String currentActivity;

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(this);
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }

   @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    private void onAppBackgrounded() {
        Log.d(TAG, "App in background");
        send_status(0, this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    private void onAppForegrounded() {
        Log.d(TAG, "App in foreground");
        send_status(1, this);
    }

    @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) {

    }
}
0 голосов
/ 13 июня 2018

Вы можете добавить это в свой класс приложения, чтобы проверить, находится ли ваше приложение на переднем плане или нет.

public class MyLifecycleHandler implements Application.ActivityLifecycleCallbacks {
    private static int resumed;
    private static int paused;
    private static int started;
    private static int stopped;

    private static String currentActivity;

    public static String getCurrentActivity() {
        return currentActivity;
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        currentActivity = activity.getClass().getSimpleName();
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
    }

    @Override
    public void onActivityResumed(Activity activity) {
        ++resumed;
    }

    @Override
    public void onActivityPaused(Activity activity) {
        ++paused;
        android.util.Log.w("test", "application is in foreground: " + (resumed > paused));

        // send broadcast from here to the service
        sendBroadcast()
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
    }

    @Override
    public void onActivityStarted(Activity activity) {
        ++started;
    }

    @Override
    public void onActivityStopped(Activity activity) {
        ++stopped;
        android.util.Log.w("test", "application is visible: " + (started > stopped));
    }

    public static boolean isApplicationVisible() {
        return started > stopped;
    }

    public static boolean isApplicationInForeground() {
        return resumed > paused;
    }
}

Добавьте это в свое приложение следующим образом:

public class MyApplication extends Application {

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

        registerActivityLifecycleCallbacks(new MyLifecycleHandler());
    }
}

При получении трансляции в сервисе вы можете остановить медиаплеер.

Редактировать

Вам необходимо изменить класс приложения на следующий:

public class app_class extends Application implements Application.ActivityLifecycleCallbacks {
    private static int resumed;
    private static int paused;

    private static String currentActivity;

    @Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(this);
    }

    @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) {

    }
}
0 голосов
/ 27 июня 2018

Вы должны подготовить игрока снова после его остановки.Если вы хотите остановить воспроизведение, когда ваше приложение переходит в фоновый режим, и запускать мультимедиа с самого начала, когда ваше приложение выходит на передний план.Просто измените свой код BroadcastReceiver следующим образом:

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 = MediaPlayer.create(this, R.raw.music);
                player.setLooping(true);
                player.start();
            }

        }
    };

Однако, если вы хотите приостановить воспроизведение и возобновить его с того места, где вы его оставили, внесите следующие изменения: В классе Application в onActivityDestroyed ():

@Override
public void onActivityDestroyed(Activity activity) {
    send_status(2);
}

и в BroadcastReceiver:

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.pause();  //When app is in background and not killed, we just want to pause the player and not want to lose the current state.
            } else if (parseInt(String.valueOf(status)) == 1) {
                if (player != null)
                    player.start();  // If the player was created and wasn't stopped, it won't be null, and the playback will be resumed from where we left of.
                else {
                    // If the player was stopped, we need to prepare it once again.
                    player = MediaPlayer.create(this, R.raw.music);
                    player.setLooping(true);
                    player.start();
                }
            } else if(player != null){
                player.stop();
                player.release();
            }

        }
    };

Также обратите внимание на состояния MediaPlayer .

0 голосов
/ 13 июня 2018

Вы реализовали onDestroy ()?Если нет, то я считаю, что это может быть решением - и вы останавливаете свой проигрыватель или все, что используете для запуска службы в onDestroy ().

Службу можно остановить, вызвав ее stopSelf () или вызовом Context.stopService ().

...