我在后台服务中流式传输音乐。一切正常,除了当我从最近的应用程序列表中删除该应用程序时,服务被破坏了.当没有媒体播放器时,我用来使服务作为粘性运行的方法可以正常工作。这是我的代码
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=":whatever"
添加到服务标记,在应用清单中指定服务在其自己的进程中运行。这将确保在应用的主进程(即从应用列表中删除应用时)不会终止服务。
如果要使服务运行到用户想要停止,请将其作为前台服务启动。您可以通过在某个时候调用服务中的startForeground
来执行此操作。您需要将通知 ID(您自己选择的整数)和通知传递给 startForeground。通知将保留在任务栏中,直到用户停止服务。当然,您应该在通知或通知的某个操作中提供"挂起"以停止服务。
当您的应用程序被销毁时,您的任何服务也会停止。问题是您可能只用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;
}
然后,您的服务将在另一个线程上运行,即使您的应用程序被终止,您的服务也将正常工作。请务必向用户显示本地通知,以指出某些后台服务正在运行。