onCompletionListener() 不是每次都调用并且随机播放和重复效果不佳

onCompeletionListener() not called every time and shuffle and repeat not working well

public class SongPlayerActivity extends AppCompatActivity implements MediaPlayer.OnCompletionListener {
static MediaPlayer mediaPlayer;
TextView songName, artistName, albumName, durationPlayed, totalDuration;
ImageView next, previous, songImage, shuffle, repeat;
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
SeekBar seekBar;
FloatingActionButton floatingActionButton;
List<Song> songList = new ArrayList<>();
Handler handler = new Handler();
Thread playPauseThread, nextThread, previousThread;
private Uri uri;
private int position;
boolean shuffleBoolean, repeatBoolean;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_song_player);

    sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

    songList = getIntent().getParcelableArrayListExtra("songsList");
    position = getIntent().getIntExtra("position", 0);

    songImage = findViewById(R.id.album_cover);
    songName = findViewById(R.id.music_name);
    albumName = findViewById(R.id.album_name);
    artistName = findViewById(R.id.artist_name);
    seekBar = findViewById(R.id.seek_bar);
    durationPlayed = findViewById(R.id.played_duration);
    totalDuration = findViewById(R.id.music_duration);
    repeat = findViewById(R.id.repeat);
    shuffle = findViewById(R.id.shuffle);
    floatingActionButton = findViewById(R.id.play_pause);
    next = findViewById(R.id.next);
    previous = findViewById(R.id.previous);
    playMusic();

    mediaPlayer.setOnCompletionListener(this);

    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (mediaPlayer != null && fromUser) {
                mediaPlayer.seekTo(progress * 1000);
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });
    SongPlayerActivity.this.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (mediaPlayer != null) {
                int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
                seekBar.setProgress(currentPosition);
                durationPlayed.setText(durationConversion(currentPosition));
            }
            handler.postDelayed(this, 200);
        }
    });

    if (sharedPreferences.getBoolean("playerShuffle", false)) {
        shuffle.setImageResource(R.drawable.ic_baseline_shuffle_24);
        shuffleBoolean = true;
    }
    else {
        shuffle.setImageResource(R.drawable.ic_baseline_shuffle_off_24);
        shuffleBoolean = false;
    }
    if (sharedPreferences.getBoolean("playerRepeat", false)) {
        repeat.setImageResource(R.drawable.ic_baseline_repeat_24);
        repeatBoolean = true;
    }
    else {
        repeat.setImageResource(R.drawable.ic_baseline_repeat_24_off);
        repeatBoolean = false;
    }

    shuffle.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (sharedPreferences.getBoolean("playerShuffle", false)) {
                editor = sharedPreferences.edit();
                editor.putBoolean("playerShuffle", false);
                editor.commit();
                shuffleBoolean = false;
                shuffle.setImageResource(R.drawable.ic_baseline_shuffle_off_24);
                Toast.makeText(getApplicationContext(), R.string.shuffle_off, Toast.LENGTH_SHORT).show();
            } else {
                editor = sharedPreferences.edit();
                editor.putBoolean("playerShuffle", true);
                editor.commit();
                shuffleBoolean = true;
                shuffle.setImageResource(R.drawable.ic_baseline_shuffle_24);
                Toast.makeText(getApplicationContext(), R.string.shuffle_on, Toast.LENGTH_SHORT).show();
            }
        }
    });
    repeat.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (sharedPreferences.getBoolean("playerRepeat", false)) {
                editor = sharedPreferences.edit();
                editor.putBoolean("playerRepeat", false);
                editor.commit();
                repeatBoolean = false;
                repeat.setImageResource(R.drawable.ic_baseline_repeat_24_off);
                Toast.makeText(getApplicationContext(), R.string.repeat_off, Toast.LENGTH_LONG).show();
            } else {
                editor = sharedPreferences.edit();
                editor.putBoolean("playerRepeat", true);
                editor.commit();
                repeatBoolean = true;
                repeat.setImageResource(R.drawable.ic_baseline_repeat_24);
                Toast.makeText(getApplicationContext(), R.string.repeat_on, Toast.LENGTH_LONG).show();
            }
        }
    });
}

public String durationConversion(int songDuration) {
    long s = songDuration % 60;
    long m = (songDuration / 60) % 60;
    long h = (songDuration / (60 * 60)) % 24;
    return String.format("%02d:%02d:%02d", h, m, s);
}

void playPauseButton() {
    playPauseThread = new Thread() {
        @Override
        public void run() {
            super.run();
            floatingActionButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mediaPlayer.isPlaying()) {
                        mediaPlayer.pause();
                        floatingActionButton.setImageResource(R.drawable.ic_baseline_play_arrow_24);
                        seekBar.setMax(mediaPlayer.getDuration() / 1000);
                        SongPlayerActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (mediaPlayer != null) {
                                    int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
                                    seekBar.setProgress(currentPosition);
                                }
                                handler.postDelayed(this, 200);
                            }
                        });
                    } else {
                        mediaPlayer.start();
                        floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
                        seekBar.setMax(mediaPlayer.getDuration() / 1000);
                        SongPlayerActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (mediaPlayer != null) {
                                    int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
                                    seekBar.setProgress(currentPosition);
                                }
                                handler.postDelayed(this, 200);
                            }
                        });
                    }
                }
            });
            mediaPlayer.setOnCompletionListener(SongPlayerActivity.this);
        }
    };
    playPauseThread.start();
}

private void nextButton() {
    nextThread = new Thread() {
        @Override
        public void run() {
            super.run();
            next.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mediaPlayer.isPlaying()) {
                        mediaPlayer.stop();
                        mediaPlayer.release();
                        if(shuffleBoolean && !repeatBoolean)
                            position = random(songList.size()-1);
                        else if (!shuffleBoolean && !repeatBoolean)
                            position++;
                        if (position == songList.size())
                            position = 0;
                        mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(songList.get(position).path));
                        metaDataRetriever(Uri.parse(songList.get(position).path));
                        seekBar.setMax(mediaPlayer.getDuration() / 1000);
                        SongPlayerActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (mediaPlayer != null) {
                                    int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
                                    seekBar.setProgress(currentPosition);
                                }
                                handler.postDelayed(this, 200);
                            }
                        });
                        floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
                        mediaPlayer.setOnCompletionListener(SongPlayerActivity.this);
                    } else {
                        mediaPlayer.stop();
                        mediaPlayer.release();
                        if(shuffleBoolean && !repeatBoolean)
                            position = random(songList.size()-1);
                        else if (!shuffleBoolean && !repeatBoolean)
                            position++;
                        if (position == songList.size())
                            position = 0;
                        mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(songList.get(position).path));
                        metaDataRetriever(Uri.parse(songList.get(position).path));
                        seekBar.setMax(mediaPlayer.getDuration() / 1000);
                        SongPlayerActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (mediaPlayer != null) {
                                    int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
                                    seekBar.setProgress(currentPosition);
                                }
                                handler.postDelayed(this, 200);
                            }
                        });
                        floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
                        mediaPlayer.setOnCompletionListener(SongPlayerActivity.this);
                    }
                    mediaPlayer.start();
                }
            });
        }
    };
    nextThread.start();
}

private void previousButton() {
    previousThread = new Thread() {
        @Override
        public void run() {
            super.run();
            previous.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mediaPlayer.isPlaying()) {
                        mediaPlayer.stop();
                        mediaPlayer.release();
                        if(shuffleBoolean && !repeatBoolean)
                            position = random(songList.size()-1);
                        else if (!shuffleBoolean && !repeatBoolean)
                            position--;
                        if (position < 0)
                            position = 0;
                        mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(songList.get(position).path));
                        metaDataRetriever(Uri.parse(songList.get(position).path));
                        seekBar.setMax(mediaPlayer.getDuration() / 1000);
                        SongPlayerActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (mediaPlayer != null) {
                                    int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
                                    seekBar.setProgress(currentPosition);
                                }
                                handler.postDelayed(this, 200);
                            }
                        });
                        mediaPlayer.setOnCompletionListener(SongPlayerActivity.this);
                        floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
                    } else {
                        mediaPlayer.stop();
                        mediaPlayer.release();
                        if(shuffleBoolean && !repeatBoolean)
                            position = random(songList.size()-1);
                        else if (!shuffleBoolean && !repeatBoolean)
                            position--;
                        if (position < 0)
                            position = 0;
                        mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(songList.get(position).path));
                        metaDataRetriever(Uri.parse(songList.get(position).path));
                        seekBar.setMax(mediaPlayer.getDuration() / 1000);
                        SongPlayerActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (mediaPlayer != null) {
                                    int currentPosition = mediaPlayer.getCurrentPosition() / 1000;
                                    seekBar.setProgress(currentPosition);
                                }
                                handler.postDelayed(this, 200);
                            }
                        });
                        mediaPlayer.setOnCompletionListener(SongPlayerActivity.this);
                        floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
                    }
                    mediaPlayer.start();
                }
            });
        }
    };
    previousThread.start();
}

private int random(int i) {
    Random random = new Random();
    return random.nextInt(i+1);
}

public void metaDataRetriever(Uri uri) {
    MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
    mediaMetadataRetriever.setDataSource(uri.getPath());
    byte[] bytes = mediaMetadataRetriever.getEmbeddedPicture();
    final LinearLayout linearLayout = findViewById(R.id.linear_layout);
    Bitmap bitmap;
    if (bytes != null) {
        bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        layoutAnimation(getApplicationContext(), songImage, bitmap);
        Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
            @Override
            public void onGenerated(@Nullable Palette palette) {
                Palette.Swatch swatch = Objects.requireNonNull(palette).getDominantSwatch();
                if (swatch != null) {
                    GradientDrawable gradientDrawable = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, new int[]{0xff000000, swatch.getRgb()});
                    linearLayout.setBackground(gradientDrawable);
                    songName.setTextColor(swatch.getTitleTextColor());
                    albumName.setTextColor(swatch.getTitleTextColor());
                    artistName.setTextColor(swatch.getTitleTextColor());
                    durationPlayed.setTextColor(Color.WHITE);
                    totalDuration.setTextColor(Color.WHITE);
                    floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
                    floatingActionButton.getBackground().setTint(Color.WHITE);
                    next.setImageResource(R.drawable.ic_baseline_skip_next_white_24);
                    previous.setImageResource(R.drawable.ic_baseline_skip_previous_white_24);
                    seekBar.getThumb().setTint(Color.WHITE);
                }
            }
        });
    } else {
        layoutAnimation(getApplicationContext(), songImage, null);
        linearLayout.setBackgroundResource(R.drawable.gradient_brown);
        songName.setTextColor(Color.DKGRAY);
        albumName.setTextColor(Color.DKGRAY);
        artistName.setTextColor(Color.DKGRAY);
        floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
        next.setImageResource(R.drawable.ic_baseline_skip_next_24);
        previous.setImageResource(R.drawable.ic_baseline_skip_previous_24);
        seekBar.getThumb().setTint(getResources().getColor(R.color.colorYellow));
        durationPlayed.setTextColor(getResources().getColor(R.color.colorYellow));
        totalDuration.setTextColor(getResources().getColor(R.color.colorYellow));
    }
    songName.setText(songList.get(position).songName);
    albumName.setText(songList.get(position).albumName);
    artistName.setText(songList.get(position).artistName);
    totalDuration.setText(Song.durationConversion(songList.get(position).songDuration));
}

public void playMusic() {
    if (songList != null) {
        floatingActionButton.setImageResource(R.drawable.ic_baseline_pause_24);
        uri = Uri.parse(songList.get(position).path);
    }
    if (mediaPlayer != null) {
        mediaPlayer.stop();
        mediaPlayer.release();
    }
    mediaPlayer = MediaPlayer.create(getApplicationContext(), uri);
    mediaPlayer.start();

    metaDataRetriever(uri);
    seekBar.setMax(mediaPlayer.getDuration() / 1000);
}

public void layoutAnimation(final Context context, final ImageView imageView, final Bitmap bitmap) {
    final Animation animationIn = AnimationUtils.loadAnimation(context, android.R.anim.fade_in);
    Animation animationOut = AnimationUtils.loadAnimation(context, android.R.anim.fade_out);
    if (bitmap != null)
        animationOut.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                Glide.with(context).load(bitmap).into(imageView);
                animationIn.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {

                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {

                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {

                    }
                });
                imageView.startAnimation(animationIn);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    else
        animationOut.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                Glide.with(context).load(R.drawable.album_cover).into(imageView);
                animationIn.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {

                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {

                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {

                    }
                });
                imageView.startAnimation(animationIn);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    imageView.startAnimation(animationOut);
}

@Override
protected void onResume() {
    super.onResume();
    playPauseButton();
    nextButton();
    previousButton();
}

@Override
public void onCompletion(MediaPlayer mp) {
    nextButton();
    position++;
    if(position >= songList.size())
        position = 0;
    if (mediaPlayer != null) {
        mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(songList.get(position).path));
        seekBar.setMax(mediaPlayer.getDuration() / 1000);
        metaDataRetriever(Uri.parse(songList.get(position).path));
        mediaPlayer.start();
        mediaPlayer.setOnCompletionListener(this);
    }
}
}

我这里有两个问题:

  1. 是当前播放音乐结束时调用onCompletionListener()也就是调用nextButton() 它检查 shuffleBoolean 和 repeatBoolean 状态是否为真,这里的问题是当 shuffleBoolean 和 repeatBoolean 为真时,无论 shuffleBoolean 和 repeatBoolean 状态如何,SongList 都会连续播放,但是如果我按下一个或一个按钮,它会检查 repeatBoolean 和 shuffleBoolean 状态并根据状态正确播放下一首歌曲。
  2. 有时当我将 seekBar 移动到栏中的任何位置(秒)时,歌曲列表会在当前播放歌曲结束时停止播放

对于第一个问题,我的描述可能太长了,但我想说清楚并提前致谢。

解决方案是在 onCompltition() 中调用 next.performClick() 并删除所有其他行。 我不知道第一种方法不起作用的原因,但我想到了它,因为我需要在不单击按钮的情况下调用 onClickListener()。