您的位置:首页 > 移动开发 > 微信开发

android 录音问题记录 - 模仿微信聊天录音功能

2016-11-23 17:49 477 查看
模仿微信聊天 - “按住说话” 录音功能键的处理

1、说话按键在点击状态下是不开启录音功能的,只有长按状态下才能开启录音功能,并且在按住说话的时候,手指上移可以取消本次录音。因而,这个录音动作需要对说话按钮进行 touch 触摸监听和 onLongCLick 长点击监听

伪代码如下:

private boolean isLongClicked = false;//长按说话按钮是否被长按标识

btn_voice.setOnTouchListener(new PressToSpeakListen());
btn_voice.setOnLongClickListener(new View.OnLongClickListener() {

@Override
public boolean onLongClick(View arg0) {
isLongClicked = true;
try {
//录音开启操作在线程中处理。防止在首次使用录音功能时,系统弹录音权限框,而用户长时间不处理造成ANR
new Thread(new Runnable() {
@Override
public void run() {
//开始录音
startRecord();
}
}).start();
} catch (Exception e) {
e.printStackTrace();
//取消录音
cancelRecord();
onToast("录音失败,请重试!");
return false;
}

return false;
}
});


btn_voice 按钮Touch监听处理

/**
* 按住说话listener
* 只有按钮长按事件触发后才具体响应 MotionEvent.ACTION_MOVE 和 MotionEvent.ACTION_UP事件
*/
class PressToSpeakListen implements View.OnTouchListener {
@Override
public boolean onTouch(View v, MotionEvent event) {

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:

if (!RecordUtil.existSDCard()) {
onToast("发送语音需要sdcard支持");
return false;
}

return false;
case MotionEvent.ACTION_MOVE: {
if (!isLongClicked ) return true;
if (event.getY() < 0) {
recording_hint.setText("松开手指,取消发送");
} else {
recording_hint.setText("手指上滑,取消发送");
}
return true;
}
case MotionEvent.ACTION_UP:
if (!isLongClicked ) return false;
isLongClicked = false;
recording_container.setVisibility(View.GONE);
if (event.getY() < 0) {
// 停止录音并且删掉音频文件
cancelRecord();
Toast.makeText(ChatRoomActivity.this, "取消录音!", Toast.LENGTH_SHORT).show();
} else {
stopRecord();//停止录音
if(isRecordTimeLessthan2S()){//录音长度校验
onToast("说话时间太短!");
return  false;
}

// 停止录音并且根据录音具体情况发送文件
...

}
return false;
default:
recording_container.setVisibility(View.GONE);
return false;
}
}
}


开始录音操作

private boolean isStart = false;//录音启动标识
private boolean initSuccess;//初始化录音功能是否成功,是否存在SD卡,是否支持录音等
//录音启动测试时间。用于系统录音权限弹框确认,弹框前后时间差过大则需要进行弹框处理
//(系统在弹出权限框时会阻塞线程的执行,即只有用户进行 拒绝/允许 操作后,才会执行语句:startRecordTime = System.currentTimeMillis())
private long startTimeTest;
private long startRecordTime;//真正的开启时间
private MediaRecorder mMediaRecorder;//系统录音媒体库

/**
* 开始录音<BR>
* 录音时长不能超过60秒
* @return
*/
public boolean startRecord(){
try {
isStart = false;
getMediaRecorder();
if(initSuccess == false){
return false;
}
startTimeTest = System.currentTimeMillis();//录音启动测试时间
mMediaRecorder.prepare();
//开始录音
mMediaRecorder.start();
isStart = true;//录音启动
startRecordTime = System.currentTimeMillis();//真正的开启时间
if (startRecordTime - startTimeTest> 1000){//有延时,则说明系统弹出录音权限确认弹框,则对本次录音操作不做处理
cancelRecord();//包含录音关闭和录音文件删除操作
}
return initSuccess;
}
catch (IllegalStateException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return initSuccess;


录音关闭操作

/**
* 停止录音<BR>
* [功能详细描述]
* @return
*/
public boolean stopRecord(){

if(initSuccess == false){//录音初始化不成功
return false;
}

if(mMediaRecorder==null){
return true;
}

if (!isStart){//录音未正常启动
return true;
}

isStart = false;
//录音关闭
mMediaRecorder.stop();
mMediaRecorder.release();
mMediaRecorder = null;
return true;
}




1、有的手机,如oppo,在初次使用录音功能时需要进行权限申请,而且它的权限申请提示框的显示时间比较长,如10s。这个框会塞住主线程,容易造成ANR

解决方案:

在进行 开始录音 动作的时候,开个Thread 来跑,就不会有ANR
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: