private void handleVoiceMsg( final Message msg, final ViewHolder holder, final int position, OnLongClickListener longClickListener) { final VoiceContent content = (VoiceContent) msg.getContent(); final MessageDirect msgDirect = msg.getDirect(); int length = content.getDuration(); String voiceLength = length + mContext.getString(R.string.symbol_second); holder.voiceLength.setText(voiceLength); // 控制语音长度显示,长度增幅随语音长度逐渐缩小 int width = (int) (-0.04 * length * length + 4.526 * length + 75.214); holder.txtContent.setWidth((int) (width * mDensity)); holder.txtContent.setOnLongClickListener(longClickListener); if (msgDirect == MessageDirect.send) { holder.voice.setImageResource(R.drawable.jmui_send_3); final Animation sendingAnim = AnimationUtils.loadAnimation(mContext, R.anim.jmui_rotate); LinearInterpolator lin = new LinearInterpolator(); sendingAnim.setInterpolator(lin); switch (msg.getStatus()) { case send_success: holder.sendingIv.clearAnimation(); holder.sendingIv.setVisibility(View.GONE); holder.resend.setVisibility(View.GONE); break; case send_fail: holder.sendingIv.clearAnimation(); holder.sendingIv.setVisibility(View.GONE); holder.resend.setVisibility(View.VISIBLE); break; case send_going: sendingTextOrVoice(holder, sendingAnim, msg); break; default: } holder.resend.setOnClickListener( new OnClickListener() { @Override public void onClick(View arg0) { if (msg.getContent() != null) { showResendDialog(holder, sendingAnim, msg); } else { Toast.makeText( mContext, mContext.getString(R.string.sdcard_not_exist_toast), Toast.LENGTH_SHORT) .show(); } } }); } else switch (msg.getStatus()) { case receive_success: if (mIsGroup) { holder.displayName.setVisibility(View.VISIBLE); if (TextUtils.isEmpty(msg.getFromUser().getNickname())) { holder.displayName.setText(msg.getFromUser().getUserName()); } else { holder.displayName.setText(msg.getFromUser().getNickname()); } } holder.voice.setImageResource(R.drawable.jmui_receive_3); // 收到语音,设置未读 if (msg.getContent().getBooleanExtra("isReaded") == null || !msg.getContent().getBooleanExtra("isReaded")) { mConv.updateMessageExtra(msg, "isReaded", false); holder.readStatus.setVisibility(View.VISIBLE); if (mIndexList.size() > 0) { if (!mIndexList.contains(position)) { addTolistAndSort(position); } } else { addTolistAndSort(position); } if (nextPlayPosition == position && autoPlay) { playVoice(position, holder, false); } } else if (msg.getContent().getBooleanExtra("isReaded").equals(true)) { holder.readStatus.setVisibility(View.GONE); } break; case receive_fail: holder.voice.setImageResource(R.drawable.jmui_receive_3); // 接收失败,从服务器上下载 content.downloadVoiceFile( msg, new DownloadCompletionCallback() { @Override public void onComplete(int status, String desc, File file) { if (status != 0) { Toast.makeText( mContext, mContext.getString(R.string.voice_fetch_failed_toast), Toast.LENGTH_SHORT) .show(); } else { Log.i("VoiceMessage", "reload success"); } } }); break; case receive_going: break; default: } holder.txtContent.setOnClickListener( new OnClickListener() { @Override public void onClick(View arg0) { if (!FileHelper.isSdCardExist() && msg.getDirect() == MessageDirect.send) { Toast.makeText( mContext, mContext.getString(R.string.sdcard_not_exist_toast), Toast.LENGTH_SHORT) .show(); return; } // 如果之前存在播放动画,无论这次点击触发的是暂停还是播放,停止上次播放的动画 if (mVoiceAnimation != null) { mVoiceAnimation.stop(); } // 播放中点击了正在播放的Item 则暂停播放 if (mp.isPlaying() && mPosition == position) { if (msgDirect == MessageDirect.send) { holder.voice.setImageResource(R.anim.jmui_voice_send); } else { holder.voice.setImageResource(R.anim.jmui_voice_receive); } mVoiceAnimation = (AnimationDrawable) holder.voice.getDrawable(); pauseVoice(); mVoiceAnimation.stop(); // 开始播放录音 } else if (msgDirect == MessageDirect.send) { holder.voice.setImageResource(R.anim.jmui_voice_send); mVoiceAnimation = (AnimationDrawable) holder.voice.getDrawable(); // 继续播放之前暂停的录音 if (mSetData && mPosition == position) { mVoiceAnimation.start(); mp.start(); // 否则重新播放该录音或者其他录音 } else { playVoice(position, holder, true); } // 语音接收方特殊处理,自动连续播放未读语音 } else { try { // 继续播放之前暂停的录音 if (mSetData && mPosition == position) { if (mVoiceAnimation != null) { mVoiceAnimation.start(); } mp.start(); // 否则开始播放另一条录音 } else { // 选中的录音是否已经播放过,如果未播放,自动连续播放这条语音之后未播放的语音 if (msg.getContent().getBooleanExtra("isReaded") == null || !msg.getContent().getBooleanExtra("isReaded")) { autoPlay = true; playVoice(position, holder, false); // 否则直接播放选中的语音 } else { holder.voice.setImageResource(R.anim.jmui_voice_receive); mVoiceAnimation = (AnimationDrawable) holder.voice.getDrawable(); playVoice(position, holder, false); } } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } } } }); }
private void playVoice(final int position, final ViewHolder holder, final boolean isSender) { // 记录播放录音的位置 mPosition = position; Message msg = mMsgList.get(position); if (autoPlay) { mConv.updateMessageExtra(msg, "isReaded", true); holder.readStatus.setVisibility(View.GONE); if (mVoiceAnimation != null) { mVoiceAnimation.stop(); mVoiceAnimation = null; } holder.voice.setImageResource(R.anim.jmui_voice_receive); mVoiceAnimation = (AnimationDrawable) holder.voice.getDrawable(); } try { mp.reset(); VoiceContent vc = (VoiceContent) msg.getContent(); Log.i(TAG, "content.getLocalPath:" + vc.getLocalPath()); mFIS = new FileInputStream(vc.getLocalPath()); mFD = mFIS.getFD(); mp.setDataSource(mFD); if (mIsEarPhoneOn) { mp.setAudioStreamType(AudioManager.STREAM_VOICE_CALL); } else { mp.setAudioStreamType(AudioManager.STREAM_MUSIC); } mp.prepare(); mp.setOnPreparedListener( new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mVoiceAnimation.start(); mp.start(); } }); mp.setOnCompletionListener( new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mVoiceAnimation.stop(); mp.reset(); mSetData = false; if (isSender) { holder.voice.setImageResource(R.drawable.jmui_send_3); } else { holder.voice.setImageResource(R.drawable.jmui_receive_3); } if (autoPlay) { int curCount = mIndexList.indexOf(position); Log.d(TAG, "curCount = " + curCount); if (curCount + 1 >= mIndexList.size()) { nextPlayPosition = -1; autoPlay = false; } else { nextPlayPosition = mIndexList.get(curCount + 1); notifyDataSetChanged(); } mIndexList.remove(curCount); } } }); } catch (FileNotFoundException e) { Toast.makeText( mContext, mContext.getString(R.string.file_not_found_toast), Toast.LENGTH_SHORT) .show(); } catch (IOException e) { Toast.makeText( mActivity, mContext.getString(R.string.file_not_found_toast), Toast.LENGTH_SHORT) .show(); } finally { try { if (mFIS != null) { mFIS.close(); } } catch (IOException e) { e.printStackTrace(); } } }