Java 当应用程序进入后台时停止MediaPlayer服务

Java 当应用程序进入后台时停止MediaPlayer服务,java,android,service,android-mediaplayer,Java,Android,Service,Android Mediaplayer,我有一个媒体播放器服务,可以在我的应用程序的后台播放音乐,例如: 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.se

我有一个媒体播放器服务,可以在我的应用程序的后台播放音乐,例如:

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

}   

但是音乐不会继续

您实现了onDestroy()吗?如果不是,我相信这可能是解决方案——您可以停止您的播放器或在onDestroy()中运行服务的任何东西

可以通过调用其stopSelf()方法或 正在调用Context.stopService()


您可以将其添加到应用程序类中,以检查应用程序是否位于前台

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());
    }
}
在服务中接收广播时,您可以停止mediaplayer

编辑

您需要将应用程序类更改为:

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

    }
}

停止播放后,您需要再次准备播放。如果要在应用程序进入后台时停止播放,并在应用程序进入前台时从头开始播放媒体。只需将您的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();
            }

        }
    };
但是,如果要暂停播放并从离开的位置继续播放,请进行以下更改: 在应用程序类中的onActivityDestroyed()中:

在广播接收机中:

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

        }
    };

另外,请查看。

除了使用广播接收器作为RoyalGriffin的答案外,通过实现
LifecycleObserver
接口可以解决音乐中断小的问题。您可以知道应用程序何时处于前台或后台,这样就不需要处理每个活动的状态

使用他的方法在应用程序中实现
Application.ActivityLifecycleCallbacks
@OnLifecycleEvent(Lifecycle.Event.ON\u STOP)
@OnLifecycleEvent(Lifecycle.Event.ON\u START)

然后将这一行添加到onCreate()中

你的app_类应该是这样的:

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

    }
}

可以少用样板,包括:

添加到build.gradle(应用程序)


请您再解释一下“在服务中接收广播时,您可以停止mediaplayer”。您可以从MyLifecycleHandler发送广播,并在服务类中接收广播。您可以在这里看到这个实现:我无法理解这一点。它不会工作(音乐不会停止),但应用程序不会崩溃。您需要在应用程序的oncreate by
registerActivityLifecycleCallbacks(this)
中注册ActivityLifeCycleCallbacks。您能在服务中接收广播吗?它只处理一个问题,这个问题不太重要,但如果您知道任何修复方法,将不胜感激。当我在活动中导航时,音乐会立即暂停和恢复,导致音乐在瞬间失真。不管怎样,我要标记为已纠正,因为一周来我一直在寻找解决方案……非常感谢
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    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) {

    }
}
class App : Application(), LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onAppInBackground() {
        sendStatus(0)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onAppInForeground() {
        sendStatus(1)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onAppDestroyed() {
        sendStatus(2)
    }

    private fun sendStatus(statusCounter: Int) {
        val intent = Intent("status")
        intent.putExtra("status", statusCounter)
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
    }

    override fun onCreate() {
        super.onCreate()
        ProcessLifecycleOwner.get().lifecycle.addObserver(this)
    }
}
implementation "androidx.lifecycle:lifecycle-runtime:2.1.0"
implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:2.1.0"