Android使用AudioRecord遇到的问题与解决方法

来源:互联网 发布:美图软件大全 编辑:程序博客网 时间:2024/06/06 16:30

问题:

1、android判断是否禁用了录音权限

      通过判断分贝值是否大于0,在代码中搜索 volume > 0

2、部分手机在调用 audioRecord.startRecording(); 和audioRecord.stop();方法时会抛出异常,例如联想手机

3、部分手机(例如联想)会抛出java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.

      解决方法来源于:http://www.cnblogs.com/mythou/p/3241925.html

       原因:

       

出现上面问题的原因是录音的硬件资源被申请了,但是没有释放,然后你再次申请资源,导致初始化失败。这里需要注意的是不仅仅需要调用Release()方法。还需要把AudioRecord对象置为null,否则还是释放失败。下面是Android 开发网上面的一个对于AudioRecord的释放说明。

Releases the native AudioRecord resources. The object can no longer be used and the reference should be set to null after a call to release()。


解决方法在代码中:


package com.androidleaf.audiorecord;import android.app.ProgressDialog;import android.content.Context;import android.media.AudioFormat;import android.media.AudioRecord;import android.media.MediaRecorder;import android.os.AsyncTask;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import com.hisun.phone.core.voice.Device;import com.todoroo.aacenc.AACEncoder;import com.todoroo.aacenc.AACToM4A;import java.io.DataInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.RandomAccessFile;import app.jimu.zhiyu.activity.question.AnswerActivity;public class AudioRecordUtils {private final int audioSource = MediaRecorder.AudioSource.MIC;// 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025    private final int sampleRateInHz = 16000;    // 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道    private final int channelConfig = AudioFormat.CHANNEL_IN_STEREO;    // 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。    private final int audioFormat = AudioFormat.ENCODING_PCM_16BIT;        private int inBufSize = 0;private AudioRecord audioRecord;private AACEncoder encoder = null;private ProgressDialog mProgressDialog = null;private boolean isRecord = false;private Context mContext;/** * 录制的音频文件名称 */private String mAudioRecordFileName;private static final int RECORDED_INIT_DELETE = 0;private static final int RECORDED_COMPLETED_DELETE = 1;    private Handler mHandler;/** * 是否可以录音 true 可以录音 */private boolean recordEnable = false;public AudioRecordUtils(Context context,String audioRecordFileName, Handler handler){mContext = context;mAudioRecordFileName = audioRecordFileName;        mHandler = handler;initAudioRecord();}    /** * 初始化对象 */    private void initAudioRecord(){inBufSize = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);audioRecord  = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, inBufSize);encoder = new AACEncoder();deleteAllFiles(RECORDED_INIT_DELETE);mProgressDialog = new ProgressDialog(mContext);mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);mProgressDialog.setCanceledOnTouchOutside(false);mProgressDialog.setCancelable(false);mProgressDialog.setTitle("提示");mProgressDialog.setMessage("正在保存录音,请耐心等候......");}        /** * 开始录音 */public void startRecord(){new AudioRecordTask().execute();}/** * 暂停录音 */public void pauseRecord(){isRecord = false;}/** * 停止录音 */public void stopRecord(){new AudioEncoderTask().execute();}/** * 重新录制 */public void reRecord(){//重新录制时,删除录音文件夹中的全部文件deleteAllFiles(RECORDED_INIT_DELETE);} private void encodeAudio(){try {//读取录制的pcm音频文件    DataInputStream mDataInputStream = new DataInputStream(new FileInputStream(    FileUtils.getPcmFilePath(mAudioRecordFileName)));byte[] b = new byte[(int) new File(FileUtils.getPcmFilePath(mAudioRecordFileName)).length()];mDataInputStream.read(b);//初始化编码配置encoder.init(32000, 2, sampleRateInHz, 16, FileUtils.getAAcFilePath(mAudioRecordFileName));//对二进制代码进行编码        encoder.encode(b);        //编码完成        encoder.uninit();        //关闭流        mDataInputStream.close();        try {        //将aac文件转码成m4a文件            new AACToM4A().convert(mContext, FileUtils.getAAcFilePath(mAudioRecordFileName),             FileUtils.getM4aFilePath(mAudioRecordFileName));        } catch (IOException e) {            Log.e("ERROR", "error converting", e);        }        deleteAllFiles(RECORDED_COMPLETED_DELETE);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}class AudioRecordTask extends AsyncTask<Void, Void, Void>{@Overrideprotected Void doInBackground(Void... params) {// TODO Auto-generated method stubif(audioRecord == null){initAudioRecord();}RandomAccessFile mRandomAccessFile = null;try {mRandomAccessFile = new RandomAccessFile(new File(FileUtils.getPcmFilePath(mAudioRecordFileName)), "rw");byte[] b = new byte[inBufSize/4];//开始录制音频try{// 防止某些手机崩溃,例如联想audioRecord.startRecording();}catch (IllegalStateException e){e.printStackTrace();}//判断是否正在录制isRecord = true;                long wait = 0;                long maxWait = 10;while(isRecord){                    //r是实际读取的数据长度,一般而言r会小于buffersize                    int r = audioRecord.read(b, 0, b.length);                    long v = 0;                    // 将 buffer 内容取出,进行平方和运算                    for (int i = 0; i < b.length; i++) {                         v += b[i] * b[i];                    }                    // 平方和除以数据总长度,得到音量大小。                    double mean = v / (double) r;                    double volume = 10 * Math.log10(mean);                    wait++;                    if(wait > maxWait){                        wait = 0;                        Log.d(this.getClass().getName(), "分贝值:" + volume + " " + (volume > 0));if(volume > 0){recordEnable = true;}                        Message msg = new Message();                        msg.what = AnswerActivity.STATUS_PREPARE;                        Bundle bundle = new Bundle();                        bundle.putDouble(Device.VOICE_AMPLITUDE, volume);                        msg.obj = bundle;                        mHandler.sendMessage(msg);                    }//向文件中追加内容mRandomAccessFile.seek(mRandomAccessFile.length());mRandomAccessFile.write(b, 0, b.length);                }//停止录制try {// 防止某些手机崩溃,例如联想audioRecord.stop();// 彻底释放资源audioRecord.release();audioRecord = null;}catch (IllegalStateException e){e.printStackTrace();}mRandomAccessFile.close();} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}}class AudioEncoderTask extends AsyncTask<Void, Void, Long>{@Overrideprotected void onPreExecute() {// TODO Auto-generated method stubsuper.onPreExecute();if(mProgressDialog != null && !mProgressDialog.isShowing()){//mProgressDialog.show();                Message msg = new Message();                msg.what = 2;                mHandler.sendMessage(msg);}}@Overrideprotected Long doInBackground(Void... params) {// TODO Auto-generated method stubencodeAudio();return null;}@Overrideprotected void onPostExecute(Long result) {// TODO Auto-generated method stubsuper.onPostExecute(result);if(mProgressDialog.isShowing()){mProgressDialog.cancel();mProgressDialog.dismiss();}}}/** * 清空音频录制文件夹中的所有文件 * @param isRecorded */public void deleteAllFiles(int isRecorded){ File[] files = new File(FileUtils.getAudioRecordFilePath()).listFiles();switch (isRecorded) {case RECORDED_INIT_DELETE:for(File file: files){        file.delete();        }break;case RECORDED_COMPLETED_DELETE:        for(File file: files){        if(!file.getName().equals(mAudioRecordFileName + Constants.M4A_SUFFIX)){        file.delete();        }        }break;default:break;}}public boolean isRecordEnable() {return recordEnable;}}


1 0
原创粉丝点击