在项目开发中,有个需求:实现模仿微信录音,发送语音的功能。长按按钮录音,弹框显示语音时间,以及上滑取消发送。我重写了一个发送语音的控件,以实现该功能。
首先添加权限:
AudioRecorderButton,自己实现的自定义录音控件
public class AudioRecorderButton extends Button {
private static final int STATE_NORMAL = 1;// 默认的状态
private static final int STATE_RECORDING = 2;// 正在录音
private static final int STATE_WANT_TO_CANCEL = 3;// 希望取消
private int mCurrentState = STATE_NORMAL; // 当前的状态
private boolean isRecording = false;// 已经开始录音
private static final int DISTANCE_Y_CANCEL = 50;
private DialogManager mDialogManager;
private AudioManager mAudioManager;
// 是否触发longClick
private boolean mReady;
android.media.AudioManager audioManager;
private static final int MSG_AUDIO_PREPARED = 0x110;
private static final int MSG_VOICE_CHANGED = 0x111;
private static final int MSG_DIALOG_DIMISS = 0x112;
private static final int MSG_TIME_OUT = 0x113;
private static final int UPDATE_TIME = 0x114;
private boolean mThreadFlag = false;
private int time = 0;
private float mTime;
/*
* 获取音量大小的线程
*/
private Runnable mGetVoiceLevelRunnable = new Runnable() {
public void run() {
while (isRecording) {
try {
Thread.sleep(100);
mTime += 0.1f;
time++;
if (isWantToCancel) {
} else {
if (time % 10 == 0) {
mHandler.sendEmptyMessage(UPDATE_TIME);
}
}
mHandler.sendEmptyMessage(MSG_VOICE_CHANGED);
if (mTime >= 10.0f) {//如果时间超过10秒,自动结束录音
while (!mThreadFlag) {//记录已经结束了录音,不需要再次结束,以免出现问题
mDialogManager.dimissDialog();
mAudioManager.release();
if (audioFinishRecorderListener != null) {
//发消息给主线程,告诉他reset();
mHandler.sendEmptyMessage(MSG_TIME_OUT);
audioFinishRecorderListener.onFinish(mTime, mAudioManager.getCurrentFilePath());
}
mThreadFlag = !mThreadFlag;
}
isRecording = false;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_AUDIO_PREPARED:
// 显示對話框在开始录音以后
mDialogManager.showRecordingDialog();
isRecording = true;
// 开启一个线程
new Thread(mGetVoiceLevelRunnable).start();
break;
case MSG_VOICE_CHANGED:
mDialogManager.updateVoiceLevel(mAudioManager.getVoiceLevel(7));
break;
case MSG_DIALOG_DIMISS:
mDialogManager.dimissDialog();
break;
case MSG_TIME_OUT://录音超时
reset();
break;
case UPDATE_TIME://更新时间
if (time % 10 == 0) {
mDialogManager.updateTime(time / 10);
}
break;
}
}
};
/**
* 以下2个方法是构造方法
*/
public AudioRecorderButton(Context context, AttributeSet attrs) {
super(context, attrs);
mDialogManager = new DialogManager(context);
audioManager = (android.media.AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
String dir = Environment.getExternalStorageDi