模仿微信的按住录音功能

          come from :按住录音功能

           Android仿微信录音功能,自定义控件的设计技巧  http://blog.csdn.net/kymjs/article/details/41903565

    将功能封装到view中,降低耦合度,需要的地方直接引入view就可以

     我把整个逻辑封装到一个Button里了,可以直接使用这个Button,当按住时会开始录音,当手指移到Button外时取消录音,该Button还向外暴露了一个Finish接口,录音完成时调用这个接口,具体使用方法看代码吧。

代码:

  1     package demo.com;
  2 
  3     import java.io.File;
  4     import java.io.IOException;
  5 
  6     import android.app.Dialog;
  7     import android.content.Context;
  8     import android.content.DialogInterface;
  9     import android.content.DialogInterface.OnDismissListener;
 10     import android.media.MediaRecorder;
 11     import android.os.Handler;
 12     import android.os.Message;
 13     import android.util.AttributeSet;
 14     import android.view.Gravity;
 15     import android.view.MotionEvent;
 16     import android.view.ViewGroup;
 17     import android.view.WindowManager.LayoutParams;
 18     import android.widget.Button;
 19     import android.widget.ImageView;
 20     import android.widget.Toast;
 21 
 22     public class RecordButton extends Button {
 23 
 24          public RecordButton(Context context) {
 25              super(context);
 26              init();
 27          }
 28 
 29          public RecordButton(Context context, AttributeSet attrs, int defStyle) {
 30              super(context, attrs, defStyle);
 31              init();
 32          }
 33 
 34          public RecordButton(Context context, AttributeSet attrs) {
 35              super(context, attrs);
 36              init();
 37          }
 38 
 39          public void setSavePath(String path) {
 40              mFileName = path;
 41          }
 42 
 43          public void setOnFinishedRecordListener(OnFinishedRecordListener listener) {
 44              finishedListener = listener;
 45          }
 46 
 47          private String mFileName = null;
 48 
 49          private OnFinishedRecordListener finishedListener;
 50 
 51          private static final int MIN_INTERVAL_TIME = 2000;// 2s
 52          private long startTime;
 53 
 54          private Dialog recordIndicator;
 55 
 56          private static int[] res = { R.drawable.mic_2, R.drawable.mic_3,
 57                  R.drawable.mic_4, R.drawable.mic_5 };
 58 
 59          private static ImageView view;
 60 
 61          private MediaRecorder recorder;
 62 
 63          private ObtainDecibelThread thread;
 64 
 65          private Handler volumeHandler;
 66 
 67          private void init() {
 68              volumeHandler = new ShowVolumeHandler();
 69          }
 70 
 71          @Override
 72          public boolean onTouchEvent(MotionEvent event) {
 73 
 74              if (mFileName == null)
 75                  return false;
 76 
 77              int action = event.getAction();
 78 
 79              switch (action) {
 80              case MotionEvent.ACTION_DOWN:
 81                  initDialogAndStartRecord();
 82                  break;
 83              case MotionEvent.ACTION_UP:
 84                  finishRecord();
 85                  break;
 86              case MotionEvent.ACTION_CANCEL:// 当手指移动到view外面,会cancel
 87                  cancelRecord();
 88                  break;
 89              }
 90 
 91              return true;
 92          }
 93 
 94          private void initDialogAndStartRecord() {
 95 
 96              startTime = System.currentTimeMillis();
 97              recordIndicator = new Dialog(getContext(),
 98                      R.style.like_toast_dialog_style);
 99              view = new ImageView(getContext());
100              view.setImageResource(R.drawable.mic_2);
101              recordIndicator.setContentView(view, new LayoutParams(
102                      ViewGroup.LayoutParams.MATCH_PARENT,
103                      ViewGroup.LayoutParams.MATCH_PARENT));
104              recordIndicator.setOnDismissListener(onDismiss);
105              LayoutParams lp = recordIndicator.getWindow().getAttributes();
106              lp.gravity = Gravity.CENTER;
107 
108              startRecording();
109              recordIndicator.show();
110          }
111 
112          private void finishRecord() {
113              stopRecording();
114              recordIndicator.dismiss();
115 
116              long intervalTime = System.currentTimeMillis() - startTime;
117              if (intervalTime < MIN_INTERVAL_TIME) {
118                  Toast.makeText(getContext(), "时间太短!", Toast.LENGTH_SHORT).show();
119                  File file = new File(mFileName);
120                  file.delete();
121                  return;
122              }
123 
124              if (finishedListener != null)
125                  finishedListener.onFinishedRecord(mFileName);
126          }
127 
128          private void cancelRecord() {
129              stopRecording();
130              recordIndicator.dismiss();
131 
132              Toast.makeText(getContext(), "取消录音!", Toast.LENGTH_SHORT).show();
133              File file = new File(mFileName);
134              file.delete();
135          }
136 
137          private void startRecording() {
138              recorder = new MediaRecorder();
139              recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
140              recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
141              recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
142              recorder.setOutputFile(mFileName);
143 
144              try {
145                  recorder.prepare();
146              } catch (IOException e) {
147                  e.printStackTrace();
148              }
149 
150              recorder.start();
151              thread = new ObtainDecibelThread();
152              thread.start();
153 
154          }
155 
156          private void stopRecording() {
157              if (thread != null) {
158                  thread.exit();
159                  thread = null;
160              }
161              if (recorder != null) {
162                  recorder.stop();
163                  recorder.release();
164                  recorder = null;
165              }
166          }
167 
168          private class ObtainDecibelThread extends Thread {
169 
170              private volatile boolean running = true;
171 
172              public void exit() {
173                  running = false;
174              }
175 
176              @Override
177              public void run() {
178                  while (running) {
179                      try {
180                          Thread.sleep(200);
181                      } catch (InterruptedException e) {
182                          e.printStackTrace();
183                      }
184                      if (recorder == null || !running) {
185                          break;
186                      }
187                      int x = recorder.getMaxAmplitude();
188                      if (x != 0) {
189                          int f = (int) (10 * Math.log(x) / Math.log(10));
190                          if (f < 26)
191                              volumeHandler.sendEmptyMessage(0);
192                          else if (f < 32)
193                              volumeHandler.sendEmptyMessage(1);
194                          else if (f < 38)
195                              volumeHandler.sendEmptyMessage(2);
196                          else
197                              volumeHandler.sendEmptyMessage(3);
198 
199                      }
200 
201                  }
202              }
203 
204          }
205 
206          private OnDismissListener onDismiss = new OnDismissListener() {
207 
208              @Override
209              public void onDismiss(DialogInterface dialog) {
210                  stopRecording();
211              }
212          };
213 
214          static class ShowVolumeHandler extends Handler {
215              @Override
216              public void handleMessage(Message msg) {
217                  view.setImageResource(res[msg.what]);
218              }
219          }
220 
221          public interface OnFinishedRecordListener {
222              public void onFinishedRecord(String audioPath);
223          }
224 
225     }

效果图:

 

源码下载:

   andoid按住录音功能http://download.csdn.net/detail/xiaobijia/9423718

原文地址:https://www.cnblogs.com/xiaobijia/p/5173188.html