简体   繁体   English

片段破坏时服务内部的mediaPlayer停止

[英]mediaPlayer inside service stops when fragment destory

I have a service for play music in background. 我有一项在后台播放音乐的服务。 when I close the app, music player pauses. 当我关闭应用程序时,音乐播放器会暂停。 I check all codes and i don't understand where media player pauses. 我检查了所有代码,但我不知道媒体播放器在哪里暂停。 Also when media player pauses, notification icon doesn't change and doesn't work well. 另外,当媒体播放器暂停时,通知图标不会更改并且不能正常工作。 I have to press pause icon in notification several time that it works. 我必须按几下通知中的暂停图标才能正常工作。

This is my service: 这是我的服务:

public class MusicPlayerService extends Service {
    private MediaPlayer mediaPlayer;
    private MusicPlayerBinder musicPlayerBinder = new MusicPlayerBinder();
    private NotificationManager notificationManager;
    private Notification.Builder builderForPlaySate;
    private Notification.Builder builderForPauseSate;
    private Intent showMusicPlayerActivityIntent;
    private PendingIntent playPendingIntent;
    private PendingIntent forwardPendingIntent;
    private PendingIntent rewindPendingIntent;

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

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(intent == null){
            return START_NOT_STICKY;
        }
        if(intent.getAction() == null){
            intent.setAction("");
        }
        switch (intent.getAction()){
            case ACTION_PLAY:
                if (mediaPlayer.isPlaying()){
                    mediaPlayer.pause();
                    notificationManager.notify(1, builderForPlaySate.build());
                }else {
                    mediaPlayer.start();
                    notificationManager.notify(1, builderForPauseSate.build());
                }
                break;
            case ACTION_FORWARD:
                mediaPlayer.seekTo(mediaPlayer.getCurrentPosition()+5000);
                break;
            case ACTION_REWIND:
                mediaPlayer.seekTo(mediaPlayer.getCurrentPosition()-5000);
                break;
            default:
                if(mediaPlayer.isPlaying())
                    notificationManager.notify(1, builderForPauseSate.build());
                else
                    notificationManager.notify(1, builderForPlaySate.build());
                break;
        }
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        mediaPlayer.release();
        super.onDestroy();
    }

    private void setupMediaPlayer() {
        notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        builderForPlaySate = new Notification.Builder(getApplicationContext());
        builderForPauseSate = new Notification.Builder(getApplicationContext());
        showMusicPlayerActivityIntent = new Intent(this, MainActivity.class);
        showMusicPlayerActivityIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

        Intent playIntent=new Intent(this,MusicPlayerService.class);
        playIntent.setAction(ACTION_PLAY);
        playPendingIntent = PendingIntent.getService(this,0,playIntent,0);

        Intent forwardIntent=new Intent(this,MusicPlayerService.class);
        forwardIntent.setAction(ACTION_FORWARD);
        forwardPendingIntent =PendingIntent.getService(this,0,forwardIntent,0);

        Intent rewindIntent=new Intent(this,MusicPlayerService.class);
        rewindIntent.setAction(ACTION_REWIND);
        rewindPendingIntent = PendingIntent.getService(this,0,rewindIntent,0);

        builderForPlaySate
                .setSmallIcon(R.drawable.ic_music_note_black_36dp)
                .setContentTitle("Academy Of Music")
                .setContentText("Rooze Sard(Shadmehr Aghili).mp3")
                .setOngoing(false)
                .setContentIntent(PendingIntent.getActivity(this,0,showMusicPlayerActivityIntent,0))
                .addAction(R.drawable.ic_fast_rewind_black_48dp,"",rewindPendingIntent)
                .addAction(R.drawable.ic_action_play_black_48dp,"",playPendingIntent)
                .addAction(R.drawable.ic_fast_forward_black_48dp,"",forwardPendingIntent);

        builderForPauseSate
                .setSmallIcon(R.drawable.ic_music_note_black_36dp)
                .setContentTitle("Academy Of Music")
                .setContentText("Rooze Sard(Shadmehr Aghili).mp3")
                .setOngoing(true)
                .setContentIntent(PendingIntent.getActivity(this,0,showMusicPlayerActivityIntent,0))
                .addAction(R.drawable.ic_fast_rewind_black_48dp,"",rewindPendingIntent)
                .addAction(R.drawable.ic_action_pause_black_48dp,"",playPendingIntent)
                .addAction(R.drawable.ic_fast_forward_black_48dp,"",forwardPendingIntent);

        mediaPlayer = new MediaPlayer();
        try {
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

            mediaPlayer.setDataSource(getApplicationContext(), Uri.parse("http://www.miusiko.com/upload/artist/Shadmehr_Aghili/tajrobehkon/Shadmehr-Aghili-Rooze-Sard-Miusiko.mp3"));

            mediaPlayer.prepare();
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mediaPlayer) {
                    stopForeground(true);
                    stopSelf();
                }
            });
        } catch (IOException e) {
            Log.e("academyofmusic",e.toString());
        }
    }

    public MediaPlayer getMediaPlayer(){
        return this.mediaPlayer;
    }

    public class MusicPlayerBinder extends Binder{
        public MusicPlayerService getService(){
            return MusicPlayerService.this;
        }
    }
}

This is my fragment class: 这是我的片段类:

public class TodayMusicFragment extends Fragment implements View.OnClickListener, ServiceConnection {
    private View view;
    private Context context;
    private MediaPlayer mediaPlayer;
    private ImageView playImageView;
    private ImageView forwardImageView;
    private ImageView rewindImageView;
    private TextView currentDurationTextView;
    private TextView durationTextView;
    private SeekBar seekBar;
    private Timer timer;
    private MusicPlayerService musicPlayerService;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_today_music,container,false);
        context = getContext();
        context.bindService(new Intent(context, MusicPlayerService.class),this,Context.BIND_AUTO_CREATE);
        return view;
    }

    private void setupViews() {
        playImageView = view.findViewById(R.id.iv_today_music_play);
        currentDurationTextView = view.findViewById(R.id.tv_today_music_current_duration);
        durationTextView = view.findViewById(R.id.tv_today_music_duration);
        forwardImageView = view.findViewById(R.id.iv_today_music_forward);
        rewindImageView = view.findViewById(R.id.iv_today_music_rewind);
        seekBar = view.findViewById(R.id.sb_today_music_seekbar);

        durationTextView.setText(formatDuration(mediaPlayer.getDuration()));
        currentDurationTextView.setText(formatDuration(0));
        seekBar.setMax(mediaPlayer.getDuration());
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if(fromUser)
                    mediaPlayer.seekTo(progress);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                seekBar.setProgress(0);
                mediaPlayer.seekTo(0);
            }
        });
        timer = new Timer();
        timer.schedule(new MainTimer(),0,1000);

        setOnClickListener();
    }

    private void setOnClickListener(){
        playImageView.setOnClickListener(this);
        forwardImageView.setOnClickListener(this);
        rewindImageView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if(v == playImageView){
            context.startService(new Intent(context,MusicPlayerService.class));
            if(mediaPlayer.isPlaying()){
                mediaPlayer.pause();
                playImageView.setImageDrawable(ResourcesCompat.getDrawable(getResources(),R.drawable.ic_play_circle_filled_white_80dp,null));
            }
            else{
                mediaPlayer.start();
                playImageView.setImageDrawable(ResourcesCompat.getDrawable(getResources(),R.drawable.ic_pause_circle_filled_white_80dp,null));
            }
        }
        else if(v == forwardImageView){
            mediaPlayer.seekTo(mediaPlayer.getCurrentPosition() + 5000);
        }
        else if(v == rewindImageView){
            mediaPlayer.seekTo(mediaPlayer.getCurrentPosition() - 5000);
        }
    }

    private String formatDuration(long duration) {
        int seconds = (int) (duration / 1000);
        int minutes = seconds / 60;
        seconds %= 60;
        return String.format(Locale.ENGLISH, "%02d", minutes) + ":" + String.format(Locale.ENGLISH, "%02d", seconds);
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder iBinder) {
        MusicPlayerService.MusicPlayerBinder musicPlayerBinder = (MusicPlayerService.MusicPlayerBinder) iBinder;
        musicPlayerService = musicPlayerBinder.getService();
        mediaPlayer = musicPlayerService.getMediaPlayer();
        setupViews();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }

    private class MainTimer extends TimerTask {

        @Override
        public void run() {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if(mediaPlayer.isPlaying()){
                        playImageView.setImageDrawable(ResourcesCompat.getDrawable(getResources(),R.drawable.ic_pause_circle_filled_white_80dp,null));
                    }else{
                        playImageView.setImageDrawable(ResourcesCompat.getDrawable(getResources(),R.drawable.ic_play_circle_filled_white_80dp,null));
                    }
                    seekBar.setProgress(mediaPlayer.getCurrentPosition());
                    currentDurationTextView.setText(formatDuration(mediaPlayer.getCurrentPosition()));
                }
            });
        }
    }

    @Override
    public void onDestroy() {
        //mediaPlayer.release();
        timer.purge();
        timer.cancel();
        context.unbindService(this);
        super.onDestroy();
    }
}

Remove this context.unbindService(this); 删除此context.unbindService(this); from onDestroy() method of the fragment class 来自片段类的onDestroy()方法

@Override
public void onDestroy() {
    //mediaPlayer.release();
    timer.purge();
    timer.cancel();
    super.onDestroy();
}

Also do not start the service again and again on button click 也不要在单击按钮时一次又一次地启动服务

context.startService(new Intent(context,MusicPlayerService.class));

You should check if the service is already running or not , if not then start the service else it will another instance of service class 您应该检查服务是否已在运行,如果尚未运行,请启动该服务,否则它将另一个服务类实例

use this method before start the method which returns true or false 在启动返回true或false的方法之前使用此方法

 private boolean isMyServiceRunning(Class<?> serviceClass, Context context) {
    ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM