在我的应用中,媒体播放器应继续在后台播放。但是在某些设备上,当Mediaplayer启动时,应用会冻结。
应用程序和相应的服务被杀后,媒体播放器继续播放和循环。它将不会停止,直到设备重新启动,并且在运行应用程序中没有媒体播放器服务的跟踪。
再次启动应用程序并明确请求停止服务无效。
如何在这种情况下完成播放?
我的服务看起来像
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Surface;
import android.widget.RemoteViews;
import android.widget.Toast;
import com.squareup.otto.Subscribe;
import java.io.IOException;
import bigdig.yarh.ellotv.GsonModels.VideoDataGSON;
import bigdig.yarh.ellotv.activitytry.R;
import bigdig.yarh.ellotv.activitytry.ui.activity.NavigationDrawerActivity;
import bigdig.yarh.ellotv.broadcastrecievers.CancelPlayBackBroadcast;
import bigdig.yarh.ellotv.broadcastrecievers.NextSongBroadcast;
import bigdig.yarh.ellotv.broadcastrecievers.PlaySongBroadcast;
import bigdig.yarh.ellotv.broadcastrecievers.PreviousSongBroadcast;
import bigdig.yarh.ellotv.bus.BusProvider;
import bigdig.yarh.ellotv.bus.MediaPlayerReset;
import bigdig.yarh.ellotv.bus.NotiControllCancel;
import bigdig.yarh.ellotv.bus.NotiControllPlay;
import bigdig.yarh.ellotv.bus.ProceedViews;
import bigdig.yarh.ellotv.bus.RestartSurface;
import bigdig.yarh.ellotv.bus.SeekBarProgress;
import bigdig.yarh.ellotv.bus.VideoISFinished;
public class MediaPlayerService
extends Service
{
private NotificationManager mNotificationManager;
private static final String TAG = "MediaService";
private static final int NOTIFICATION_ID = 234221;
private VideoDataGSON videoObject;
private MediaPlayer player=null;
@Override
public void onCreate() {
super.onCreate();
BusProvider.getInstance()
.register(this);
mNotificationManager = (NotificationManager) getSystemService(
NOTIFICATION_SERVICE
);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
createMediaPlayerIfNeeded();
Bundle extras = intent.getExtras();
if (extras == null) Toast.makeText(this, "Media Player Error", Toast.LENGTH_LONG)
.show();
else {
videoObject = (VideoDataGSON) extras.getSerializable("videoObject");
try {
player.setDataSource(videoObject.source);
player.prepareAsync();
} catch (IOException e) {
Log.e("Mediaplayer IO", e.getMessage());
}
}
// Toast.makeText(this, "mediaplayer started", Toast.LENGTH_SHORT)
// .show();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
BusProvider.getInstance()
.unregister(this);
mNotificationManager.cancel(NOTIFICATION_ID);
player.release();
player = null;
super.onDestroy();
}
@Subscribe
public void restartSurface(RestartSurface event) {
if(player!=null)
BusProvider.getInstance()
.post(player);
}
@Subscribe
public void notiCancel(NotiControllCancel event) {
stopSelf();
}
@Subscribe
public void notiPlay(NotiControllPlay event) {
try{
if (player != null) {
if (player.isPlaying()) {
player.pause();
} else player.start();
createNotification();
}}
catch(Exception e){}
}
@Subscribe
public void resetPlayer(MediaPlayerReset event) {
if (player != null) {
player.reset();
}
}
@Subscribe
public void setProgress(SeekBarProgress event) {
double progress = event.getProgress();
if (player != null) {
player.seekTo((int) (player.getDuration() * (progress / 100)));
}
}
@Subscribe
public void atachSurface(Surface event) {
if(player!=null) player.setSurface(event);
}
public void createNotification() {
int icon = R.drawable.ic_stat_notify_video;
long when = System.currentTimeMillis();
String notiTitle = videoObject.title + " - " + videoObject.getName();
Notification notification = new Notification(icon, notiTitle, when);
Intent cancelIntent = new Intent(this, CancelPlayBackBroadcast.class);
PendingIntent pendingIntentCancel = PendingIntent.getBroadcast(
this, 9991, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT
);
Intent previousSongIntent = new Intent(this, PreviousSongBroadcast.class);
PendingIntent pendingIntentPrevious = PendingIntent.getBroadcast(
this, 9992, previousSongIntent, PendingIntent.FLAG_UPDATE_CURRENT
);
Intent playSongIntent = new Intent(this, PlaySongBroadcast.class);
PendingIntent pendingIntentPlay = PendingIntent.getBroadcast(
this, 9993, playSongIntent, PendingIntent.FLAG_UPDATE_CURRENT
);
Intent nextSongIntent = new Intent(this, NextSongBroadcast.class);
PendingIntent pendingIntentNext = PendingIntent.getBroadcast(
this, 9994, nextSongIntent, PendingIntent.FLAG_UPDATE_CURRENT
);
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.noti_player_controlls);
contentView.setImageViewResource(R.id.image, R.drawable.ic_launcher);
if (player != null) {
if (player.isPlaying()) contentView.setImageViewResource(
R.id.noti_play, R.drawable.ic_action_pause
);
else contentView.setImageViewResource(
R.id.noti_play, R.drawable.ic_action_play
);
}
contentView.setTextViewText(R.id.title, notiTitle);
contentView.setOnClickPendingIntent(R.id.noti_previous, pendingIntentPrevious);
contentView.setOnClickPendingIntent(R.id.noti_play, pendingIntentPlay);
contentView.setOnClickPendingIntent(R.id.noti_next, pendingIntentNext);
contentView.setOnClickPendingIntent(R.id.noti_cancel, pendingIntentCancel);
Intent videoIntent = new Intent(MediaPlayerService.this, NavigationDrawerActivity.class);
videoIntent.addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP
);
notification.contentIntent = PendingIntent.getActivity(
MediaPlayerService.this, 0, videoIntent, PendingIntent.FLAG_UPDATE_CURRENT
);
notification.contentView = contentView;
notification.flags |=
Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT; //Do not clear the notification
mNotificationManager.notify(NOTIFICATION_ID, notification);
}
void createMediaPlayerIfNeeded() {
if (player == null) {
player = new MediaPlayer();
player.setOnPreparedListener(
new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if (!player.isPlaying()) {
player.start();
BusProvider.getInstance()
.post(new ProceedViews(1));
createNotification();
BusProvider.getInstance()
.post(player);
}
}
}
);
player.setOnCompletionListener(
new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
player.reset();
createMediaPlayerIfNeeded();
BusProvider.getInstance()
.post(new VideoISFinished());
stopSelf();
}
}
);
player.setOnSeekCompleteListener(
new MediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mp) {
}
}
);
player.setScreenOnWhilePlaying(true);
player.setOnErrorListener(
new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(
MediaPlayer mp, int what, int extra
) {
Toast.makeText(
getApplicationContext(),
"Media player error! What: " + what + "extra :" + extra,
Toast.LENGTH_SHORT
)
.show();
return false;
}
}
);
}
}
}
答案 0 :(得分:0)
您需要在STAR_NOT_STICKY
的{{1}}内返回 onStartCommand()
。这将停止服务一旦中断(即服务被终止或内存不足),并且不会再次自动启动。
写
service
而不是
return START_NOT_STICKY;
答案 1 :(得分:0)
在返回语句中使用START_NOT_STICKY