完成后播放下一首歌曲
Play next song oncompletion
所以我遇到的问题是,当我将我的搜索栏拖到歌曲的末尾时,它可以从一些歌曲开始工作,然后我转到下一首,但有时它会跳过一首歌曲并停止播放。
示例;
我正在播放歌曲 "position 1",当点击一首显示在回收站视图中的歌曲时,它会从我的主要活动传递到我的歌曲活动。
当我将我的搜索栏拖到最后时,它转到 2,然后是 3 和 4,但随后它跳到 6,所以它没有播放位置 5 的歌曲。
只有当我将我的搜索栏拖到一首歌曲的末尾时才会出现这种情况,而我的下一首和上一首按钮可以正常工作。
这是我的歌曲活动中的代码
mCurrentIndex = (int) b.get("songIndex");
if (mediaPlayer.isPlaying()){
mBtnPlayPause.setImageResource(R.drawable.ic_action_pause_white);
updateProgressBar();
}
tvSongListSize.setText((songIndex + 1) + "/" + songList.size());
mBtnShuffle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isShuffle){
isShuffle = false;
Toast.makeText(getApplicationContext(), "Shuffle is off", Toast.LENGTH_SHORT ).show();
mBtnShuffle.setImageResource(R.drawable.ic_action_shuffle);
}else{
isShuffle = true;
Toast.makeText(getApplicationContext(), "Shuffle is on", Toast.LENGTH_SHORT).show();
mBtnShuffle.setImageResource(R.drawable.ic_shuffle_on);
isRepeat = false;
mBtnRepeat.setImageResource(R.drawable.ic_action_repeat);
}
}
});
mBtnRepeat.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isRepeat){
isRepeat = false;
Toast.makeText(getApplicationContext(), "Repeat is off", Toast.LENGTH_SHORT).show();
mBtnRepeat.setImageResource(R.drawable.ic_action_repeat);
}else{
isRepeat = true;
Toast.makeText(getApplicationContext(), "Repeat is on", Toast.LENGTH_SHORT).show();
mBtnRepeat.setImageResource(R.drawable.ic_repeat_on);
isShuffle = false;
mBtnShuffle.setImageResource(R.drawable.ic_action_shuffle);
}
}
});
mBtnPlayPause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
mBtnPlayPause.setImageResource(R.drawable.ic_action_play);
} else {
mediaPlayer.start();
mBtnPlayPause.setImageResource(R.drawable.ic_action_pause_white);
}
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mBtnPlayPause.setImageResource(R.drawable.ic_action_play);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
mBtnNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
nextSong();
}
});
mBtnPrev.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
prevSong();
}
});
}
private void playSongNumber(int index) {
try{
mediaPlayer.reset();
mediaPlayer.setDataSource(songList.get(index).getData());
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
seekBar.setProgress(0);
seekBar.setMax(100);
updateProgressBar();
}catch (Exception e){
e.printStackTrace();
}
}
private void nextSong(){
mCurrentIndex++;
mCurrentIndex %= songList.size();
playSongNumber(mCurrentIndex);
mBtnPlayPause.setImageResource(R.drawable.ic_action_pause_white);
tvSongListSize.setText((mCurrentIndex + 1) + "/" + songList.size());
Toast.makeText(getApplicationContext(), "You Clicked position: " + mCurrentIndex + " " + songList.get(mCurrentIndex).getData(), Toast.LENGTH_SHORT).show();
}
private void prevSong(){
mCurrentIndex = mCurrentIndex > 0 ? mCurrentIndex - 1 : songList.size() - 1;
playSongNumber(mCurrentIndex);
mBtnPlayPause.setImageResource(R.drawable.ic_action_pause_white);
tvSongListSize.setText((mCurrentIndex + 1) + "/" + songList.size());
Toast.makeText(getApplicationContext(), "You Clicked position: " + mCurrentIndex + " " + songList.get(mCurrentIndex).getData(), Toast.LENGTH_SHORT).show();
}
@Override
public void onCompletion(MediaPlayer mp) {
if (isRepeat){
playSongNumber(mCurrentIndex);
}else if(isShuffle){
Random random = new Random();
mCurrentIndex = random.nextInt((songList.size() - 1) + 1);
tvSongListSize.setText((mCurrentIndex + 1) + "/" + songList.size());
playSongNumber(mCurrentIndex);
}else if (mCurrentIndex < songList.size()-1){
nextSong();
tvSongListSize.setText((mCurrentIndex + 1) + "/" + songList.size());
}else{
playSongNumber(0);
tvSongListSize.setText((1) + "/" + songList.size());
}
}
public void updateProgressBar(){
mHandler.postDelayed(mUpdateTime, 100);
}
private Runnable mUpdateTime = new Runnable() {
@Override
public void run() {
long songCurrentTime = mediaPlayer.getCurrentPosition();
long songTotalTime = mediaPlayer.getDuration();
tvSongCurrentTime.setText(""+utilities.msToTimer(songCurrentTime));
tvSongTotalTime.setText(""+utilities.msToTimer(songTotalTime));
int progress = (int)(utilities.getProgressPercentage(songCurrentTime, songTotalTime));
seekBar.setProgress(progress);
mHandler.postDelayed(this, 100);
}
};
一个toast也显示跳过一首歌(toast显示2次)
第二个问题 已解决
当我点击一首歌曲时,它会转到 songActivity 并在调用 onCompletion 时播放下一首歌曲,但是当我按下暂停按钮,然后再次播放时,歌曲播放完毕后它会卡住并且不会'播放下一首歌曲。
第三题
当我转到列表中的最后一首歌曲并让它播放以便调用 OnCompletion 时,它会返回到列表中的第一首歌曲,这很好,但是当我单击上一首按钮继续播放时回到最后一首歌曲,它会跳过最后一首歌曲。
示例:最后一首歌曲位于位置 [25],完成后它会返回到位置 [0] 的歌曲(我的第一首歌曲),但是当我单击后退按钮时它会转到 [24] 并跳过 [25](最后一首歌)。
这仅在调用 oncompletion 时发生。
发生这种情况是因为在运行时发生了一些错误并且您尚未实施 OnErrorListener
。
在 android 文档中提到,如果您不在 MediaPlayer
对象上实现 OnErrorListener
,那么在发生任何错误时都会导致 OnCompletionListener
待调用。
所以实现一个 'OnErrorListener' 和 return 如果错误已被处理则为真,否则为假。返回 false 将再次调用 OnCompletionListener
.
您可以在此处参考 android 文档:https://developer.android.com/reference/android/media/MediaPlayer.OnErrorListener.html
编辑:我在您的代码中发现的一个主要问题是您在 playSongNumber()
方法中调用了 updateProgressBar()
,但它将在调用 onPrepared
之前执行。这就是导致你出现问题的原因。将您的 updateProgressBar()
调用移至 onPrepared
内和 mp.start()
之后
所以我遇到的问题是,当我将我的搜索栏拖到歌曲的末尾时,它可以从一些歌曲开始工作,然后我转到下一首,但有时它会跳过一首歌曲并停止播放。 示例;
我正在播放歌曲 "position 1",当点击一首显示在回收站视图中的歌曲时,它会从我的主要活动传递到我的歌曲活动。
当我将我的搜索栏拖到最后时,它转到 2,然后是 3 和 4,但随后它跳到 6,所以它没有播放位置 5 的歌曲。
只有当我将我的搜索栏拖到一首歌曲的末尾时才会出现这种情况,而我的下一首和上一首按钮可以正常工作。
这是我的歌曲活动中的代码
mCurrentIndex = (int) b.get("songIndex");
if (mediaPlayer.isPlaying()){
mBtnPlayPause.setImageResource(R.drawable.ic_action_pause_white);
updateProgressBar();
}
tvSongListSize.setText((songIndex + 1) + "/" + songList.size());
mBtnShuffle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isShuffle){
isShuffle = false;
Toast.makeText(getApplicationContext(), "Shuffle is off", Toast.LENGTH_SHORT ).show();
mBtnShuffle.setImageResource(R.drawable.ic_action_shuffle);
}else{
isShuffle = true;
Toast.makeText(getApplicationContext(), "Shuffle is on", Toast.LENGTH_SHORT).show();
mBtnShuffle.setImageResource(R.drawable.ic_shuffle_on);
isRepeat = false;
mBtnRepeat.setImageResource(R.drawable.ic_action_repeat);
}
}
});
mBtnRepeat.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isRepeat){
isRepeat = false;
Toast.makeText(getApplicationContext(), "Repeat is off", Toast.LENGTH_SHORT).show();
mBtnRepeat.setImageResource(R.drawable.ic_action_repeat);
}else{
isRepeat = true;
Toast.makeText(getApplicationContext(), "Repeat is on", Toast.LENGTH_SHORT).show();
mBtnRepeat.setImageResource(R.drawable.ic_repeat_on);
isShuffle = false;
mBtnShuffle.setImageResource(R.drawable.ic_action_shuffle);
}
}
});
mBtnPlayPause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
mBtnPlayPause.setImageResource(R.drawable.ic_action_play);
} else {
mediaPlayer.start();
mBtnPlayPause.setImageResource(R.drawable.ic_action_pause_white);
}
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mBtnPlayPause.setImageResource(R.drawable.ic_action_play);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
mBtnNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
nextSong();
}
});
mBtnPrev.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
prevSong();
}
});
}
private void playSongNumber(int index) {
try{
mediaPlayer.reset();
mediaPlayer.setDataSource(songList.get(index).getData());
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
seekBar.setProgress(0);
seekBar.setMax(100);
updateProgressBar();
}catch (Exception e){
e.printStackTrace();
}
}
private void nextSong(){
mCurrentIndex++;
mCurrentIndex %= songList.size();
playSongNumber(mCurrentIndex);
mBtnPlayPause.setImageResource(R.drawable.ic_action_pause_white);
tvSongListSize.setText((mCurrentIndex + 1) + "/" + songList.size());
Toast.makeText(getApplicationContext(), "You Clicked position: " + mCurrentIndex + " " + songList.get(mCurrentIndex).getData(), Toast.LENGTH_SHORT).show();
}
private void prevSong(){
mCurrentIndex = mCurrentIndex > 0 ? mCurrentIndex - 1 : songList.size() - 1;
playSongNumber(mCurrentIndex);
mBtnPlayPause.setImageResource(R.drawable.ic_action_pause_white);
tvSongListSize.setText((mCurrentIndex + 1) + "/" + songList.size());
Toast.makeText(getApplicationContext(), "You Clicked position: " + mCurrentIndex + " " + songList.get(mCurrentIndex).getData(), Toast.LENGTH_SHORT).show();
}
@Override
public void onCompletion(MediaPlayer mp) {
if (isRepeat){
playSongNumber(mCurrentIndex);
}else if(isShuffle){
Random random = new Random();
mCurrentIndex = random.nextInt((songList.size() - 1) + 1);
tvSongListSize.setText((mCurrentIndex + 1) + "/" + songList.size());
playSongNumber(mCurrentIndex);
}else if (mCurrentIndex < songList.size()-1){
nextSong();
tvSongListSize.setText((mCurrentIndex + 1) + "/" + songList.size());
}else{
playSongNumber(0);
tvSongListSize.setText((1) + "/" + songList.size());
}
}
public void updateProgressBar(){
mHandler.postDelayed(mUpdateTime, 100);
}
private Runnable mUpdateTime = new Runnable() {
@Override
public void run() {
long songCurrentTime = mediaPlayer.getCurrentPosition();
long songTotalTime = mediaPlayer.getDuration();
tvSongCurrentTime.setText(""+utilities.msToTimer(songCurrentTime));
tvSongTotalTime.setText(""+utilities.msToTimer(songTotalTime));
int progress = (int)(utilities.getProgressPercentage(songCurrentTime, songTotalTime));
seekBar.setProgress(progress);
mHandler.postDelayed(this, 100);
}
};
一个toast也显示跳过一首歌(toast显示2次)
第二个问题 已解决
当我点击一首歌曲时,它会转到 songActivity 并在调用 onCompletion 时播放下一首歌曲,但是当我按下暂停按钮,然后再次播放时,歌曲播放完毕后它会卡住并且不会'播放下一首歌曲。
第三题
当我转到列表中的最后一首歌曲并让它播放以便调用 OnCompletion 时,它会返回到列表中的第一首歌曲,这很好,但是当我单击上一首按钮继续播放时回到最后一首歌曲,它会跳过最后一首歌曲。 示例:最后一首歌曲位于位置 [25],完成后它会返回到位置 [0] 的歌曲(我的第一首歌曲),但是当我单击后退按钮时它会转到 [24] 并跳过 [25](最后一首歌)。
这仅在调用 oncompletion 时发生。
发生这种情况是因为在运行时发生了一些错误并且您尚未实施 OnErrorListener
。
在 android 文档中提到,如果您不在 MediaPlayer
对象上实现 OnErrorListener
,那么在发生任何错误时都会导致 OnCompletionListener
待调用。
所以实现一个 'OnErrorListener' 和 return 如果错误已被处理则为真,否则为假。返回 false 将再次调用 OnCompletionListener
.
您可以在此处参考 android 文档:https://developer.android.com/reference/android/media/MediaPlayer.OnErrorListener.html
编辑:我在您的代码中发现的一个主要问题是您在 playSongNumber()
方法中调用了 updateProgressBar()
,但它将在调用 onPrepared
之前执行。这就是导致你出现问题的原因。将您的 updateProgressBar()
调用移至 onPrepared
内和 mp.start()