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

模仿微信聊天 - “按住说话” 录音功能键的处理
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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值