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;
????????????}
????????}
????}
}
2015-09-28
這個不知道