package com.imooc.weixinaudio.view;
import com.imooc.weixinaudio.R;
import com.imooc.weixinaudio.view.AudioManager.AudioPrepareListener;
import android.content.Context;
import android.os.Environment;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
public class AudioRecorderButton extends Button implements AudioPrepareListener {
private static final int DISTANCE_Y_CANCEL = 25;
private static final int STATE_NORMAL = 1;
private static final int STATE_RECORDING = 2;
private static final int STATE_WANT_TO_CANCEL = 3;
// 最大音量格数
private static final int MAX_VOICE = 7;
// 录音太短对话框显示时间
private static final int DIALOG_DISMISS_TIME = 1500;
// 是否触发longClick的标志位
private boolean isReady;
// 当前状态标志位
private int curState = STATE_NORMAL;
// 判断是否开始录音的标志位
private boolean isRecording = false;
// 开始录音后的计时
private float mTime;
private DialogManager mDialogManager;
private AudioManager mAudioManager;
public AudioRecorderButton(Context context) {
this(context, null);
}
public AudioRecorderButton(Context context, AttributeSet attrs) {
super(context, attrs);
this.mDialogManager = new DialogManager(getContext());
String dir = Environment.getExternalStorageDirectory()
+ "/imooc_recorder_audios";
mAudioManager = AudioManager.getInstance(dir);
this.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
isReady = true;
mAudioManager.prepareAudio();
return false;
}
});
}
/**
* 录音完成后的回调接口
*
* @author Administrator
*
*/
public interface AudioFinishListener {
void onFinish(float seconds, String filePath);
}
private AudioFinishListener mListener;
public void setOnAudioFinishListener(AudioFinishListener listener) {
mListener = listener;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// 获取当前event
int action = event.getAction();
int x = (int) event.getX();
int y = (int) event.getY();
// 判断状态
switch (action) {
case MotionEvent.ACTION_DOWN:
// 改变按钮状态
mDialogManager.showRecorderDialog();
// TODO 测试
// isRecording = true;
Log.i("lang", "Down");
changeState(STATE_RECORDING);
break;
case MotionEvent.ACTION_MOVE:
Log.i("lang:isRecording", ""+isRecording);
if (isRecording) {
// 根据x,y判断是否达到取消的条件
if (wantToCancel(x, y)) {
changeState(STATE_WANT_TO_CANCEL);
} else {
changeState(STATE_RECORDING);
}
}
break;
case MotionEvent.ACTION_UP:
// 如果没有触发LongClick
if (!isReady) {
reset();
return super.onTouchEvent(event);
}
// 触发了LongClick 但是mediaRecorder没有达到prepared状态,或者录音时间小于0.5秒
if (!isRecording || mTime < 0.5f) {
// 显示录音太短对话框
mDialogManager.tooShort();
// 释放资源
mAudioManager.cancel();
// 延迟1.5秒,发送隐藏对话框信息
mHandler.sendEmptyMessageDelayed(MSG_DIALOG_DISMISS,
DIALOG_DISMISS_TIME);
} else if (curState == STATE_RECORDING) {// 正常录音状态下
mAudioManager.release();
// callBack();
if (mListener != null) {
mListener.onFinish(mTime, mAudioManager.getCurrentPath());
}
} else if (curState == STATE_WANT_TO_CANCEL) {
// 取消录音
mAudioManager.cancel();
// 隐藏对话框(在reset()方法中)
}
// 恢复状态(重置标志位,以及隐藏对话框)
reset();
break;
}
return super.onTouchEvent(event);
}
/**
* 1.定义一个Handler来处理消息 2.定义MSG常量
*/
public static final int MSG_PREPREAD = 0x111;
public static final int MSG_VOICE_CHANGED = 0x112;
public static final int MSG_DIALOG_DISMISS = 0x113;
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case MSG_PREPREAD:
// 1.显示录音Dialog
// mDialogManager.showRecorderDialog();
isRecording = true;
// 2.开启新的线程,来更新音量图标
new Thread(myVioceRunnable).start();
break;
case MSG_VOICE_CHANGED:
// 1.获取当前音量大小
int level = mAudioManager.getVoiceLevel(MAX_VOICE);
// 2.更新音量图标
mDialogManager.updateVoiceLevel(level);
break;
case MSG_DIALOG_DISMISS:
mDialogManager.dismissDialog();
}
};
};
/**
* 1.定义新的Runnable
*
*/
Runnable myVioceRunnable = new Runnable() {
@Override
public void run() {
if (isRecording) {
// 每隔100毫秒,更新一次
try {
Thread.sleep(100);
mTime += 0.1f;
} catch (InterruptedException e) {
e.printStackTrace();
}
mHandler.sendEmptyMessage(MSG_VOICE_CHANGED);
}
}
};
@Override
public void wellPrepared() {
mHandler.sendEmptyMessage(MSG_PREPREAD);
}
/**
* 重置
*/
private void reset() {
isRecording = false;
isReady = false;
changeState(STATE_NORMAL);
mTime = 0;
mDialogManager.dismissDialog();
}
private boolean wantToCancel(int x, int y) {
if (x < 0 || x > getWidth()) {
return true;
} else if (y < -DISTANCE_Y_CANCEL
|| y > getHeight() + DISTANCE_Y_CANCEL) {
return true;
}
return false;
}
private void changeState(int state) {
// 根据当前状态,对按钮样式进行更新
if (curState != state) {
// 将curState变量置为当前状态
curState = state;
switch (state) {
case STATE_NORMAL:
setBackgroundResource(R.drawable.btn_normal);
setText(R.string.btn_str_normal);
break;
case STATE_RECORDING:
setBackgroundResource(R.drawable.btn_recording);
setText(R.string.btn_str_recording);
mDialogManager.recording();
break;
case STATE_WANT_TO_CANCEL:
setBackgroundResource(R.drawable.btn_recording);
setText(R.string.btn_str_want_to_cancel);
mDialogManager.wantToCancel();
break;
}
}
}
}