在状态8

时间:2017-02-07 14:07:01

标签: android audio android-mediaplayer

我正在尝试使用音频消息实现RecyclerView并播放这些音频文件。以前我在ImageButtonso I found this solution and changed my code accordingly.改变播放和暂停图像时遇到了问题但现在我面临另一个问题。每当我播放音频时,图像会变为暂停,当我再次单击此按钮时,它会给我一个错误:pause called in state 8。我知道是什么导致了这个问题,但无法弄清楚解决方案。 这是我的onBindViewHolder:

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

这是我的MyChatMediaViewHolder课程:

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实例?

2 个答案:

答案 0 :(得分:1)

我认为最好的解决方案(如果你一次只需要播放一个音频)就是在RecyclerView.Adapter中只保留一个MediaPlayer实例,你也可以保留一个地图,其中键是位置和值是一个简单的类包含:flag - isPlaying,持续时间(当你播放你的歌曲并暂停它时,你不想从头开始但是从你暂停的地方开始),等等。所以当你上下滚动时你会能够保留播放/暂停的观看状态。

答案 1 :(得分:1)

首先,RecyclerView.Adapter的目的是为了扩大您的观点,不应该在此处编写您的业务逻辑。

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

中初始化您的媒体播放器

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