|
package com.fuly.util; |
|
|
|
import com.fuly.irecoder.R; |
|
import com.fuly.util.RecoderManager.RecoderManagerListener; |
|
import com.fuly.util.RecoderManager; |
|
|
|
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 RecoderButton extends Button implements RecoderManagerListener{ |
|
|
|
//按钮的三个状态 |
|
|
|
private static final int STATE_NORMAL = 1;//正常 |
|
private static final int STATE_RECODING = 2;//录音状态 |
|
private static final int STATE_CACLE = 3;//取消状态 |
|
|
|
private int mCurState = STATE_NORMAL;//记录当前按钮状态 |
|
|
|
private int Y = 50;//限定手指移动的上下宽度 |
|
|
|
private DialogManager mDialogManager;//对话框管理类 |
|
private RecoderManager mRecoderManager;//录音器的管理类 |
|
|
|
private boolean isRecoding = false; |
|
private boolean isLongClick =false;//是否为长安按钮,默认为没有触发 |
|
|
|
private float mTime=0;//用来记录录音的时长 |
|
|
|
private RecoderButtonListener mListener;//用来传递数据的实体 |
|
|
|
public RecoderButton(Context context) { |
|
|
|
this(context,null); |
|
} |
|
|
|
public RecoderButton(Context context, AttributeSet attrs) { |
|
|
|
super(context, attrs); |
|
|
|
mDialogManager = new DialogManager(context);//实例化对话框管理类 |
|
|
|
String path = Environment.getExternalStorageDirectory()+"//MyAudio"; |
|
Log.d("付勇j的文件夹---->",path); |
|
mRecoderManager = RecoderManager.getRecoderMananger(path);//获取一个实例 |
|
|
|
mRecoderManager.setOnRecoderManagerListener(this); |
|
|
|
setOnLongClickListener(new OnLongClickListener() { |
|
|
|
public boolean onLongClick(View v) { |
|
|
|
isLongClick = true; |
|
mRecoderManager.recoderPrepared(); |
|
return false; |
|
} |
|
}); |
|
|
|
} |
|
|
|
//定义一个回调接口,用来将数据返回,录音的时长和录音存放的路径 |
|
|
|
public interface RecoderButtonListener{ |
|
|
|
void onFinish(int mTime,String filePath); |
|
} |
|
|
|
public void setOnRecoderButtonListener( RecoderButtonListener listener){ |
|
|
|
this.mListener = listener; |
|
} |
|
|
|
private static final int CHANGE_VOICE = 0X110; |
|
private static final int DIALOG_DISS = 0X111; |
|
private static final int MEDIA_PREPARED = 0X112; |
|
|
|
private Runnable mRunnable = new Runnable(){ |
|
|
|
public void run() { |
|
|
|
while(isRecoding){ |
|
|
|
try { |
|
Thread.sleep(100); |
|
} catch (InterruptedException e) { |
|
e.printStackTrace(); |
|
} |
|
|
|
mTime+=0.1f; |
|
|
|
mHandler.sendEmptyMessage(CHANGE_VOICE); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
private Handler mHandler = new Handler(){ |
|
|
|
public void handleMessage(android.os.Message msg) { |
|
|
|
switch(msg.what){ |
|
|
|
case MEDIA_PREPARED: |
|
mDialogManager.dialogShow(); |
|
isRecoding = true; |
|
new Thread(mRunnable).start(); |
|
break; |
|
|
|
case CHANGE_VOICE: |
|
|
|
//获取声音等级,并在对话框中改变 |
|
mDialogManager.updateVoiceLevel(mRecoderManager.getVoiceLevel(7)); |
|
|
|
break; |
|
case DIALOG_DISS: |
|
mDialogManager.dialogDismiss(); |
|
break; |
|
} |
|
|
|
}; |
|
}; |
|
|
|
//回调方法,当该方法在RecoderManager中被调用时,说明录音器已经准备完毕 |
|
//可以开始录音了 |
|
public void wellPrepared() { |
|
|
|
mHandler.sendEmptyMessage(MEDIA_PREPARED); |
|
} |
|
|
|
//捕捉按钮点击事件 |
|
public boolean onTouchEvent(MotionEvent event) { |
|
|
|
int x = (int) event.getX(); |
|
int y =(int)event.getY(); |
|
|
|
switch(event.getAction()){ |
|
|
|
case MotionEvent.ACTION_DOWN: |
|
|
|
changeState(STATE_RECODING);//按下按钮,改变按钮状态 |
|
|
|
break; |
|
case MotionEvent.ACTION_MOVE: |
|
|
|
if(isRecoding){ |
|
|
|
if(wantCancel(x,y)){ //如果检测到取消,则改变按钮状态为取消 |
|
|
|
changeState(STATE_CACLE); |
|
mDialogManager.dialogRecoderCancel(); |
|
|
|
}else{ |
|
changeState(STATE_RECODING); |
|
mDialogManager.dialogRecoding(); |
|
|
|
} |
|
} |
|
|
|
break; |
|
case MotionEvent.ACTION_UP: |
|
//手指抬起的几种情况 |
|
//(1)正常录音结束后的抬起 (2)取消录音的抬起 (3)迅速抬起,此时会造成录音时间过短 |
|
//(2)可能录音器还没准备好,就手指抬起了。 也可看成是录音的时间太短(5)没有触发长安安钮就抬起 |
|
|
|
if(!isLongClick){ //如果没有触发长安安钮 |
|
|
|
reset(); |
|
return super.onTouchEvent(event); |
|
} |
|
|
|
if(!isRecoding||mTime<0.6f){//如果没有准备好录音器或者录音时间太短 |
|
|
|
mDialogManager.tooShort(); |
|
mRecoderManager.cancel(); |
|
mHandler.sendEmptyMessageDelayed(DIALOG_DISS, 2000); |
|
|
|
}else if(mCurState == STATE_RECODING){//正常录音结束 |
|
|
|
//在这里应该返回录音的文件路径和时长给播放器 |
|
|
|
mDialogManager.dialogDismiss(); |
|
mRecoderManager.release(); |
|
|
|
//此时应将录音的时长和路径传递给MainActivity |
|
if(mListener != null){ |
|
mListener.onFinish((int)mTime, mRecoderManager.getPath()); |
|
} |
|
|
|
}else if(mCurState == STATE_CACLE){// 如果为取消录音的抬起 |
|
|
|
mDialogManager.dialogDismiss(); |
|
mRecoderManager.cancel(); |
|
} |
|
|
|
reset();//各种设置复位 |
|
|
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
return super.onTouchEvent(event); |
|
} |
|
|
|
//复位 |
|
private void reset() { |
|
|
|
isRecoding = false; |
|
isLongClick =false; |
|
mTime = 0; |
|
mCurState = STATE_NORMAL; |
|
setText(R.string.btn_normal); |
|
|
|
} |
|
|
|
//检查手指移动范围,从而确定用户是否想取消录音 |
|
private boolean wantCancel(int x, int y) { |
|
|
|
if(x<0||x>getWidth()){ |
|
|
|
return true; |
|
} |
|
|
|
if(y<-Y||y>getHeight()+Y){ |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
//改变状态,包括按钮等 |
|
private void changeState(int state) { |
|
|
|
if(mCurState != state){ |
|
|
|
mCurState = state; |
|
|
|
switch(mCurState){ |
|
|
|
case STATE_NORMAL: |
|
|
|
setText(R.string.btn_normal); |
|
|
|
break; |
|
case STATE_RECODING: |
|
|
|
setText(R.string.btn_recoding); |
|
|
|
break; |
|
case STATE_CACLE: |
|
|
|
setText(R.string.btn_cancel); |
|
|
|
break; |
|
default: |
|
break; |
|
|
|
} |
|
} |
|
|
|
} |
|
|
|
} |