应用程序和服务终止后,Mediaplayer继续播放

时间:2015-03-19 15:16:20

标签: android android-mediaplayer

在我的应用中,媒体播放器应继续在后台播放。但是在某些设备上,当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;
                        }
                    }
            );

        }
    }



}

2 个答案:

答案 0 :(得分:0)

您需要在STAR_NOT_STICKY的{​​{1}}内返回 onStartCommand()。这将停止服务一旦中断(即服务被终止或内存不足),并且不会再次自动启动

service

而不是

return START_NOT_STICKY;

答案 1 :(得分:0)

在返回语句中使用START_NOT_STICKY