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