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

来源:互联网 发布:传单制作软件 编辑:程序博客网 时间:2024/04/30 02:15

模仿微信聊天 - “按住说话” 录音功能键的处理
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

0 0