package com.partynetwork.iparty.imessage; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import com.partynetwork.dataprovider.util.StringUtil; import com.partynetwork.iparty.R; import android.content.Context; import android.media.MediaPlayer; import android.os.Handler; import android.os.Vibrator; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; public class RecordStatus extends LinearLayout implements OnTouchListener { /** * 异步处理监听的钩子接口 * */ public interface RecordListener { // 异步请求完了 public void recordEnd(File amrFile,int voiceTime); } // 录制 private final static byte RECORDER_STATE_RECARDING = 0x0; // 录制时间太短 private final static byte RECORDER_STATE_SHORT = 0x01; // 发布中 private final static byte TWEET_PUBING = 0X02; // 取消发布 private final static byte RECORDER_STATE_CANALE = 0x03; // 语音最短时间(秒) private final static int RECORDER_TIME_MINTIME = 1; // 语音最长时间(秒) private final static int RECORDER_TIME_MAXTIME = 60; long startVoiceT = 0;// 开始时间 long endVoiceT = 0;// 结束世间 int startY = 0;// 开始的Y byte state = RECORDER_STATE_RECARDING; // 是否正在录音中 private boolean isRecording = false; // 是否超时 private boolean IS_OVERTIME = false; // 录音的路径 private String savePath; // 语音动弹文件名 private String fileName; private File amrFile;// 语音文件 private LinearLayout mRecardStatusShow; // 录制语音时涉及操作的控件 private FrameLayout mvFrame; private RelativeLayout mvAnimArea;// 录制声音大小布局 private ImageView mvVolume;// 录音音量 private RelativeLayout mvCancelArea;// 取消发布布局 private LinearLayout mvTooShort;// 录音太短 private TextView mvTimeMess;// 录音剩余时间提示 private AudioRecordUtils recordUtils;// 录音工具类 private int voiceTime;//录音时长 // 监听源 private TextView textView; private RecordListener listener; private Handler handler; public RecordStatus(Context context, TextView textView, RecordListener listener) { super(context); this.textView = textView; this.listener = listener; initView(); initDate(); } /** * 获取录音文件 * * @return */ public File getAmrFile() { return amrFile; } private void initDate() { recordUtils = new AudioRecordUtils(); handler = new Handler(); } private void initView() { View.inflate(getContext(), R.layout.record_status, this); mRecardStatusShow = (LinearLayout) this.findViewById(R.id.show); // 录制语音时涉及操作的控件 mvFrame = (FrameLayout) findViewById(R.id.rcding); mvAnimArea = (RelativeLayout) findViewById(R.id.anim_area);// 录制声音大小布局 mvVolume = (ImageView) findViewById(R.id.anim);// 录音状态动画 mvCancelArea = (RelativeLayout) findViewById(R.id.cancel_area);// 取消发布布局 mvTooShort = (LinearLayout) findViewById(R.id.tooshort);// 录音太短 mvTimeMess = (TextView) findViewById(R.id.time_mes); } @Override public boolean onTouch(View v, MotionEvent event) { // 超时 if (IS_OVERTIME) { mvTimeMess.setVisibility(View.INVISIBLE); stopRecorder(); textView.setBackgroundResource(R.color.lightblue); textView.setText("按住 说话"); // 状态为取消 if (state == RECORDER_STATE_CANALE || state == TWEET_PUBING) { deleteVoiceFile(); amrFile = null; if (state == RECORDER_STATE_CANALE) IS_OVERTIME = false; return false; } if (state != TWEET_PUBING) { state = TWEET_PUBING; // pubTweet(TWEET_TYPE_VOICE, "#语音分享#"); // Public_upOpenfireFilesRequest request = new // Public_upOpenfireFilesRequest(); // request.setFilePath(new String[] { amrFile.getPath() }); // T.showLong(ChatActivity.this, "路径:" + amrFile.getPath()); // BaseApplication.getInstance().getmDataProvider() // .getJsonFromNetwork(request, ChatActivity.this); if (listener != null) { listener.recordEnd(amrFile,voiceTime); voiceTime=0; } } return false; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: isRecording = true; voiceTime=0; savePath = getRecorderPath(); MediaPlayer md = MediaPlayer.create(getContext(), R.raw.notificationsound); md.start(); // 提示音播放完开始录音 md.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mp) { startRecorder(fileName); } }); IS_OVERTIME = false; textView.setBackgroundResource(R.color.lightblue); textView.setText("松开 结束"); // 按下时记录录音文件名 String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss") .format(new Date()); fileName = timeStamp + ".amr";// 语音动弹命名 startY = (int) event.getY(); startVoiceT = System.currentTimeMillis(); // 隐藏软键盘 mRecardStatusShow.setVisibility(View.VISIBLE); break; case MotionEvent.ACTION_MOVE: int tempY = (int) event.getY(); if (Math.abs(startY - tempY) > 800 / 3) { // 取消 state = RECORDER_STATE_CANALE; showRecarderStatus(RECORDER_STATE_CANALE); } else { // 录音 state = RECORDER_STATE_RECARDING; showRecarderStatus(RECORDER_STATE_RECARDING); } break; case MotionEvent.ACTION_UP: isRecording = false; textView.setBackgroundResource(R.color.gray_bg); textView.setText("按住 说话"); endVoiceT = System.currentTimeMillis(); long voiceT = endVoiceT - startVoiceT; // 停止录音 stopRecorder(); // 录音小于最小时间 if (voiceT < RECORDER_TIME_MINTIME * 1000 || state == RECORDER_STATE_CANALE) { deleteVoiceFile(); amrFile = null; if (voiceT < RECORDER_TIME_MINTIME * 1000) showRecarderStatus(RECORDER_STATE_SHORT); if (state == RECORDER_STATE_CANALE) mvTimeMess.setVisibility(View.INVISIBLE); return false; } // pubTweet(TWEET_TYPE_VOICE, "#语音分享#"); // Public_upOpenfireFilesRequest request = new // Public_upOpenfireFilesRequest(); // request.setFilePath(new String[] { amrFile.getPath() }); // T.showLong(ChatActivity.this, "路径:" + amrFile.getPath()); // BaseApplication.getInstance().getmDataProvider() // .getJsonFromNetwork(request, ChatActivity.this); if (listener != null) { listener.recordEnd(amrFile,voiceTime); voiceTime=0; } break; default: break; } return false; } // 显示录音状态 private void showRecarderStatus(byte type) { switch (type) { case RECORDER_STATE_RECARDING: mvAnimArea.setVisibility(View.VISIBLE); mvCancelArea.setVisibility(View.GONE); break; case RECORDER_STATE_CANALE: mvAnimArea.setVisibility(View.GONE); mvCancelArea.setVisibility(View.VISIBLE); break; case RECORDER_STATE_SHORT: mvFrame.setVisibility(View.GONE); mRecardStatusShow.setVisibility(View.VISIBLE); mvTooShort.setVisibility(View.VISIBLE); handler.postDelayed(new Runnable() { public void run() { mRecardStatusShow.setVisibility(View.GONE); mvTooShort.setVisibility(View.GONE); mvFrame.setVisibility(View.VISIBLE); } }, 1000); break; default: break; } } // 开始录制语音动弹 private void startRecorder(String name) { if (StringUtil.isEmpty(savePath)) return; recordUtils.start(savePath, name); handler.postDelayed(mPollTask, POLL_INTERVAL); handler.postDelayed(mTimerTask, 1000); } // 停止录音操作 private void stopRecorder() { mRecardStatusShow.setVisibility(View.GONE); handler.removeCallbacks(mPollTask); handler.removeCallbacks(mTimerTask); recordUtils.stop(); amrFile = new File(savePath, fileName); mvVolume.setImageResource(R.drawable.tweet_amp1); } // 删除录音文件 private void deleteVoiceFile() { File newPath = new File(savePath + fileName); boolean res = newPath.delete(); } // 获得语音保存的路径 private String getRecorderPath() { String savePath = getContext().getCacheDir().getAbsolutePath() + "/voice/"; File savedir = new File(savePath); if (!savedir.exists()) { savedir.mkdirs(); } return savePath; } // 定时任务间隔时间 private static final int POLL_INTERVAL = 300; // 录音音量状态展示 private Runnable mPollTask = new Runnable() { public void run() { double amp = recordUtils.getAmplitude(); updateDisplay(amp); handler.postDelayed(mPollTask, POLL_INTERVAL); } }; // 录音计时器 private Runnable mTimerTask = new Runnable() { public void run() { if (!isRecording) return; voiceTime++; if (voiceTime == RECORDER_TIME_MAXTIME) { IS_OVERTIME = true; voiceTime = 60; mvTimeMess.setVisibility(View.INVISIBLE); return; } if (voiceTime >= RECORDER_TIME_MAXTIME - 10) { if (voiceTime == RECORDER_TIME_MAXTIME - 10) { Vibrator vibrator = (Vibrator) getContext() .getSystemService(Context.VIBRATOR_SERVICE); vibrator.vibrate(300); } mvTimeMess.setVisibility(View.VISIBLE); mvTimeMess.setText("录音时间还剩下" + (RECORDER_TIME_MAXTIME - voiceTime) + "秒"); } handler.postDelayed(mTimerTask, 1000); } }; // 根据录制音量的大小定时更新状态图片 private void updateDisplay(double signalEMA) { switch ((int) signalEMA) { case 0: case 1: mvVolume.setImageResource(R.drawable.tweet_amp1); break; case 2: case 3: mvVolume.setImageResource(R.drawable.tweet_amp2); break; case 4: case 5: mvVolume.setImageResource(R.drawable.tweet_amp3); break; case 6: case 7: mvVolume.setImageResource(R.drawable.tweet_amp4); break; case 8: case 9: mvVolume.setImageResource(R.drawable.tweet_amp5); break; case 10: case 11: mvVolume.setImageResource(R.drawable.tweet_amp6); break; default: mvVolume.setImageResource(R.drawable.tweet_amp7); break; } } }