问题:

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{@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{@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. Android实现为GridView添加边框效果
  2. android binder机制之二 Service Manager
  3. android中使用properties文件配置
  4. AIDL笔记
  5. Android(安卓)开发环境准备(Ubuntu)
  6. 使用本地仓库实现最新版ReactNative集成Android
  7. Android(安卓)系统分区分析
  8. ViewPager实现QQ主界面,ViewFlipper实现某些新闻应用,自动播放,很
  9. NPM 和webpack 的基础使用

随机推荐

  1. 瘦瘦App Android(安卓)redesign简版
  2. Android与PHP交互,Android传递JSON数据,PHP
  3. 深入源码系列:聊聊android属性动画执行线
  4. Android中实现倒影效果
  5. Android(安卓)应用之安全开发
  6. Android(安卓)程序应该考虑的问题
  7. Android(安卓)APP启动优化二 使用Systrac
  8. Android(安卓)签名
  9. 盘点Android应用开发中曾经很流行但是已
  10. Android的四种监听事件处理方式