模仿微信的按住录音功能
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