当应用程序与widow分离时,带有mediaplayer的Android服务被破坏

当应用程序与widow分离时,带有mediaplayer的Android服务被破坏,android,android-service,android-mediaplayer,Android,Android Service,Android Mediaplayer,我正在后台服务中播放音乐。除了我从最近的应用程序列表中删除该应用程序,服务被破坏外,一切正常。在没有mediaplayer的情况下,我用来让服务以粘性方式运行的方法很好。这是我的密码 public class StreamListenerService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionLis

我正在后台服务中播放音乐。除了我从最近的应用程序列表中删除该应用程序,服务被破坏外,一切正常。在没有mediaplayer的情况下,我用来让服务以粘性方式运行的方法很好。这是我的密码

public class StreamListenerService extends Service implements MediaPlayer.OnPreparedListener,
        MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {

    public static MediaPlayer mMediaPlayer;
    private String streamUrl;
    public static boolean isPlaying = false;


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        streamUrl = intent.getStringExtra("streamUrl");



        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.reset();
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);


        try {
            mMediaPlayer.setDataSource(streamUrl);
        } catch (IOException e) {
            e.printStackTrace();
        }


        mMediaPlayer.setOnPreparedListener(this);
        mMediaPlayer.setOnErrorListener(this);
        mMediaPlayer.prepareAsync();
        mMediaPlayer.setOnCompletionListener(this);

        isPlaying = true;

        return Service.START_STICKY_COMPATIBILITY;
    }

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

    @Override
    public void onDestroy() {
        Log.d("StreamListenerService", "onDestroy");
        if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
            mMediaPlayer.stop();
            mMediaPlayer.reset();
            isPlaying = false;
        }
        super.onDestroy();

    }


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

    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        mMediaPlayer.start();
        isPlaying = true;
    }

    @Override
    public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {

        Toast.makeText(this, R.string.text_problem_in_playing_audio_stream, Toast.LENGTH_SHORT).show();

        mMediaPlayer.stop();
        mMediaPlayer.reset();

        //Toast.makeText(this, R.string.text_problem_in_playing_stream,Toast.LENGTH_SHORT).show();

        this.onDestroy();
        return false;
    }


    @Override
    public void onCompletion(MediaPlayer mp) {
        Toast.makeText(this, R.string.text_stream_finished, Toast.LENGTH_SHORT).show();
        mMediaPlayer = mp;
        mMediaPlayer.stop();
        mMediaPlayer.reset();
        this.onDestroy();
    }
}

您需要通过将属性
android:process=“:where”
添加到服务标签中,指定服务在应用程序清单中自己的进程中运行。这将确保当您的应用程序的主进程正在运行时,即当应用程序从应用程序列表中删除时,服务不会被终止


如果要让服务运行到用户想要停止为止,请将其作为前台服务启动。您可以通过在某个点调用服务中的
startForeground
来完成此操作。您需要将通知id(您自己选择的整数)和通知传递给startForeground。通知将保留在任务栏中,直到用户停止服务。当然,您应该提供一个PendingEvent来停止通知或通知操作中的服务。

您需要在应用程序清单中指定服务在其自己的进程中运行,方法是在服务标记中添加属性
android:process=“:where”
。这将确保当您的应用程序的主进程正在运行时,即当应用程序从应用程序列表中删除时,服务不会被终止


如果要让服务运行到用户想要停止为止,请将其作为前台服务启动。您可以通过在某个点调用服务中的
startForeground
来完成此操作。您需要将通知id(您自己选择的整数)和通知传递给startForeground。通知将保留在任务栏中,直到用户停止服务。当然,您应该在通知中或通知的某个操作中提供一个PendingEvent来停止服务。

当您的应用程序被销毁时,您的任何服务也会停止。问题是,您可能只使用
startService
启动服务,然后使用
stopService
停止服务。您需要做的是在您的服务类中使用
onStartCommand
中的
startForeground
方法启动服务

@Override
    public int onStartCommand(Intent i, int flags, int startId) {

        Intent resultIntent = new Intent(SOME_INTENT_ACTION);
        PendingIntent resultPendingIntent = PendingIntent.getBroadcast(this, 0, resultIntent, 0);

        Notification noti = new Notification.Builder(getApplicationContext())
                .setContentTitle(TITLE)
                .setContentText(CONTENT_TEXT)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(resultPendingIntent)
                .build();

        startForeground(12345, noti);

        return Service.START_STICKY;
    }

然后,您的服务将在另一个线程上运行,即使您的应用程序被终止,它也会工作。您必须显示本地通知,以便用户指出某些后台服务正在运行。

当您的应用程序被破坏时,您的任何服务也会停止。问题是,您可能只使用
startService
启动服务,然后使用
stopService
停止服务。您需要做的是在您的服务类中使用
onStartCommand
中的
startForeground
方法启动服务

@Override
    public int onStartCommand(Intent i, int flags, int startId) {

        Intent resultIntent = new Intent(SOME_INTENT_ACTION);
        PendingIntent resultPendingIntent = PendingIntent.getBroadcast(this, 0, resultIntent, 0);

        Notification noti = new Notification.Builder(getApplicationContext())
                .setContentTitle(TITLE)
                .setContentText(CONTENT_TEXT)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(resultPendingIntent)
                .build();

        startForeground(12345, noti);

        return Service.START_STICKY;
    }

然后,您的服务将在另一个线程上运行,即使您的应用程序被终止,它也会工作。显示本地通知,让用户指出某些后台服务正在运行,这一点很重要。

据我所知,当你刷走最近列表中的某个应用程序时,它可能会杀死与你的应用程序相关的一切。这包括任何服务。请看这里:据我所知,当你刷走最近列表中的一个应用程序时,它会杀死与你的应用程序相关的一切。这包括任何服务。请看这里: