播放下一首歌曲oncompletion

时间:2017-12-10 15:25:11

标签: android listener android-mediaplayer

所以我遇到的问题是当我将我的搜索栏拖到歌曲的末尾时,它会从一些歌曲开始,然后我会转到下一首歌曲,但有时会跳过一首歌并停止播放。 例子;

我在歌曲“位置1”,当我点击一首歌曲时,从我的主动作传递到我的歌曲活动,并在回收者视图中显示。

当我将我的搜索栏拖到最后时,它会转到2然后是3和4,但是它会跳到6,所以它不会在第5位播放该歌曲。

只有当我将搜索栏拖到歌曲的末尾时,才会出现这种情况,我的下一个和上一个按钮可以正常工作。

这是我的songActivity的代码

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);
    }
};

吐司也表示它会跳过一首歌曲(吐司显示2次)。

第二个问题 已解决

当我点击一首歌时,它会进入songActivity并且当onCompletion被调用时播放下一首歌曲,但是当我按下暂停按钮,然后再次播放并且在歌曲完成后它会卡住并且不会播放下一首歌。

第三个问题

当我去我列表中的最后一首歌并让它播出以便调用OnCompletion时,它会回到我列表中的第一首歌,这很好,但是当我点击上一个按钮返回最后一首歌,它跳过了最后一首歌。 示例:最后一首歌曲位于[25]位置,完成后返回位置[0](我的第一首歌曲)的歌曲,但是当我单击后退按钮时,它会转到[24]并跳过[25](最后一首歌。)

只有在调用oncompletion时才会发生这种情况。

1 个答案:

答案 0 :(得分:1)

这种情况正在发生,因为运行时发生了一些错误,而您尚未实现OnErrorListener

在android文档中提到如果你没有在OnErrorListener对象上实现MediaPlayer,那么在发生任何错误时它会导致OnCompletionListener被调用。< / p>

因此实现'OnErrorListener'并在处理错误时返回true,否则返回false。返回false将再次调用OnCompletionListener

您可以在此处参考Android文档:https://developer.android.com/reference/android/media/MediaPlayer.OnErrorListener.html

编辑:我在您的代码中发现的一个主要问题是您在updateProgressBar()方法中调用了playSongNumber(),但它会在调用onPrepared之前执行。这就是导致你出问题的原因。将您的updateProgressBar()来电转移到onPreparedmp.start()

之后