在状态 8 中调用 MediaPlayer 暂停

MediaPlayer pause called in state 8

我正在尝试使用音频消息实现 RecyclerView 并播放这些音频文件。以前我在 ImageButton 上更改播放和暂停图像时遇到问题,但现在我面临另一个问题。每当我播放音频时,图像都会暂停,当我再次单击此按钮时,它会给我一个错误:pause called in state 8。我知道是什么导致了问题,但无法找出解决方案。 这是我的 onBindViewHolder :

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            ((MyChatMediaViewHolder) holder).bindData(mChats.get(position), position);
}

这是我的 MyChatMediaViewHolder class :

private class MyChatMediaViewHolder extends RecyclerView.ViewHolder {
    private TextView txtUserAlphabet, timer;
    private ImageView play;
    private SeekBar seekBar;
    ProgressBar progressBar;
    RelativeLayout media_chat;
    Chat chat = null;

    public MyChatMediaViewHolder(View itemView) {
        super(itemView);
        play = (ImageView) itemView.findViewById(R.id.play);
        seekBar = (SeekBar) itemView.findViewById(R.id.seekbar);
        txtUserAlphabet = (TextView) itemView.findViewById(R.id.text_view_user_alphabet);
        progressBar = (ProgressBar) itemView.findViewById(R.id.progressUpdate);
        media_chat = (RelativeLayout) itemView.findViewById(R.id.chat_media);
        timer = (TextView) itemView.findViewById(R.id.timer);
        Log.e("TAG111", "bindData: ");

        play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                isPlay = !isPlay;
                //Handling for background selection state changed
                int previousSelectState=mSelectedItemPosition;
                mSelectedItemPosition = getAdapterPosition();
                //notify previous selected item
                notifyItemChanged(previousSelectState);
                //notify new selected Item
                notifyItemChanged(mSelectedItemPosition);
            }
        });
    }

    public void bindData(Chat chat, int currentPosition) {
        this.chat = chat;
        MediaPlayer mediaPlayer = new MediaPlayer();
        MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();

        try {
            mediaPlayer.setDataSource(chat.mediaUrlLocal);
            metaRetriever.setDataSource(chat.mediaUrlLocal);
            mediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }

        String duration =
                metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
        long dur = Long.parseLong(duration);
        String seconds = String.valueOf((dur % 60000) / 1000);

        String minutes = String.valueOf(dur / 60000);
        String out = minutes + ":" + seconds;

        timer.setText(out);

        if(currentPosition == mSelectedItemPosition) {
            Log.e("pause", "bindData: " + mediaPlayer.isPlaying());
            if(isPlay) {
                mediaPlayer.start();
                play.setImageResource(android.R.drawable.ic_media_pause);
            } else {
                mediaPlayer.pause();
                play.setImageResource(android.R.drawable.ic_media_play);
            }

        } else {
            play.setImageResource(android.R.drawable.ic_media_play);
        }
    }
}

我认为这里的问题是:每次都会创建新的 MediaPlayer 实例 单击播放按钮,因此当我尝试暂停时,会再次创建一个从未启动过的新媒体播放器。

所以问题是:我应该在哪里创建新的 MediaPlayer 实例?

我认为最好的解决方案(如果您一次只需要播放一个音频)是在 RecyclerView.Adapter 中只保留一个 MediaPlayer 实例,您还可以在那里保留一张地图,其中的关键是position 和 value 很简单 class 包含:flag - isPlaying,duration(当你播放你的歌曲并暂停它时,你不想从头开始而是从你暂停的地方开始),等等。所以当您正在上下滚动,您将能够保留 played/paused.

的视图状态

首先你RecyclerView.Adapter的目的是膨胀你的观点,你不应该在这里写你的业务逻辑。

其次,您应该只使用一个媒体播放器实例。您应该在 ActivityFragment.

中初始化您的媒体播放器

在您的 ActivityFragment 中创建一个接口实现并将其引用传递给您的适配器。每当您想播放音频时,您将使用您的界面将您的音频文件路径或流委托给 ActivityFragment,重置或释放您的媒体播放器并播放您的音频。