问题:

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()。


解决方法在代码中:


[java]  view plain
  1. package com.androidleaf.audiorecord;  
  2.   
  3. import android.app.ProgressDialog;  
  4. import android.content.Context;  
  5. import android.media.AudioFormat;  
  6. import android.media.AudioRecord;  
  7. import android.media.MediaRecorder;  
  8. import android.os.AsyncTask;  
  9. import android.os.Bundle;  
  10. import android.os.Handler;  
  11. import android.os.Message;  
  12. import android.util.Log;  
  13.   
  14. import com.hisun.phone.core.voice.Device;  
  15. import com.todoroo.aacenc.AACEncoder;  
  16. import com.todoroo.aacenc.AACToM4A;  
  17.   
  18. import java.io.DataInputStream;  
  19. import java.io.File;  
  20. import java.io.FileInputStream;  
  21. import java.io.FileNotFoundException;  
  22. import java.io.IOException;  
  23. import java.io.RandomAccessFile;  
  24.   
  25. import app.jimu.zhiyu.activity.question.AnswerActivity;  
  26.   
  27. public class AudioRecordUtils {  
  28.   
  29.     private final int audioSource = MediaRecorder.AudioSource.MIC;  
  30.     // 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025  
  31.     private final int sampleRateInHz = 16000;  
  32.     // 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道  
  33.     private final int channelConfig = AudioFormat.CHANNEL_IN_STEREO;  
  34.     // 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。  
  35.     private final int audioFormat = AudioFormat.ENCODING_PCM_16BIT;  
  36.       
  37.     private int inBufSize = 0;  
  38.       
  39.     private AudioRecord audioRecord;  
  40.       
  41.     private AACEncoder encoder = null;  
  42.       
  43.     private ProgressDialog mProgressDialog = null;  
  44.       
  45.     private boolean isRecord = false;  
  46.       
  47.     private Context mContext;  
  48.     /** 
  49.      * 录制的音频文件名称 
  50.      */  
  51.     private String mAudioRecordFileName;  
  52.       
  53.     private static final int RECORDED_INIT_DELETE = 0;  
  54.       
  55.     private static final int RECORDED_COMPLETED_DELETE = 1;  
  56.   
  57.     private Handler mHandler;  
  58.   
  59.     /** 
  60.      * 是否可以录音 true 可以录音 
  61.      */  
  62.     private boolean recordEnable = false;  
  63.       
  64.     public AudioRecordUtils(Context context,String audioRecordFileName, Handler handler){  
  65.         mContext = context;  
  66.         mAudioRecordFileName = audioRecordFileName;  
  67.         mHandler = handler;  
  68.         initAudioRecord();  
  69.     }  
  70.       
  71.     /** 
  72.      * 初始化对象 
  73.      */  
  74.     private void initAudioRecord(){  
  75.           
  76.         inBufSize = AudioRecord.getMinBufferSize(  
  77.                 sampleRateInHz,   
  78.                 channelConfig,   
  79.                 audioFormat);  
  80.           
  81.         audioRecord  = new AudioRecord(  
  82.                 audioSource,   
  83.                 sampleRateInHz,   
  84.                 channelConfig,   
  85.                 audioFormat,   
  86.                 inBufSize);  
  87.           
  88.         encoder = new AACEncoder();  
  89.         deleteAllFiles(RECORDED_INIT_DELETE);  
  90.           
  91.         mProgressDialog = new ProgressDialog(mContext);  
  92.         mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);  
  93.         mProgressDialog.setCanceledOnTouchOutside(false);  
  94.         mProgressDialog.setCancelable(false);  
  95.         mProgressDialog.setTitle("提示");  
  96.         mProgressDialog.setMessage("正在保存录音,请耐心等候......");  
  97.           
  98.     }  
  99.       
  100.     /** 
  101.      * 开始录音 
  102.      */  
  103.     public void startRecord(){  
  104.         new AudioRecordTask().execute();  
  105.     }  
  106.       
  107.     /** 
  108.      * 暂停录音 
  109.      */  
  110.     public void pauseRecord(){  
  111.         isRecord = false;  
  112.     }  
  113.       
  114.     /** 
  115.      * 停止录音 
  116.      */  
  117.     public void stopRecord(){  
  118.         new AudioEncoderTask().execute();  
  119.     }  
  120.       
  121.     /** 
  122.      * 重新录制 
  123.      */  
  124.     public void reRecord(){  
  125.         //重新录制时,删除录音文件夹中的全部文件  
  126.         deleteAllFiles(RECORDED_INIT_DELETE);  
  127.     }   
  128.       
  129.     private void encodeAudio(){  
  130.         try {  
  131.             //读取录制的pcm音频文件  
  132.             DataInputStream mDataInputStream = new DataInputStream(new FileInputStream(  
  133.                     FileUtils.getPcmFilePath(mAudioRecordFileName)));  
  134.                 byte[] b = new byte[(intnew File(FileUtils.  
  135.                         getPcmFilePath(mAudioRecordFileName)).length()];  
  136.                 mDataInputStream.read(b);  
  137.                 //初始化编码配置  
  138.                 encoder.init(320002, sampleRateInHz, 16, FileUtils.  
  139.                         getAAcFilePath(mAudioRecordFileName));  
  140.                 //对二进制代码进行编码  
  141.                 encoder.encode(b);  
  142.                 //编码完成  
  143.                 encoder.uninit();  
  144.                 //关闭流  
  145.                 mDataInputStream.close();  
  146.                 try {  
  147.                     //将aac文件转码成m4a文件  
  148.                     new AACToM4A().convert(mContext, FileUtils.getAAcFilePath(mAudioRecordFileName),   
  149.                             FileUtils.getM4aFilePath(mAudioRecordFileName));  
  150.                 } catch (IOException e) {  
  151.                     Log.e("ERROR""error converting", e);  
  152.                 }  
  153.                 deleteAllFiles(RECORDED_COMPLETED_DELETE);  
  154.             } catch (FileNotFoundException e) {  
  155.                 // TODO Auto-generated catch block  
  156.                 e.printStackTrace();  
  157.             } catch (IOException e1) {  
  158.                 // TODO Auto-generated catch block  
  159.                 e1.printStackTrace();  
  160.             }  
  161.     }  
  162.       
  163.     class AudioRecordTask extends AsyncTask{  
  164.   
  165.         @Override  
  166.         protected Void doInBackground(Void... params) {  
  167.             // TODO Auto-generated method stub  
  168.             if(audioRecord == null){  
  169.                 initAudioRecord();  
  170.             }  
  171.             RandomAccessFile mRandomAccessFile = null;  
  172.             try {  
  173.                 mRandomAccessFile = new RandomAccessFile(new File(  
  174.                         FileUtils.getPcmFilePath(mAudioRecordFileName)), "rw");  
  175.                 byte[] b = new byte[inBufSize/4];  
  176.                 //开始录制音频  
  177.                 try{  
  178.                     // 防止某些手机崩溃,例如联想  
  179.                     audioRecord.startRecording();  
  180.                 }catch (IllegalStateException e){  
  181.                     e.printStackTrace();  
  182.                 }  
  183.   
  184.                 //判断是否正在录制  
  185.                 isRecord = true;  
  186.                 long wait = 0;  
  187.                 long maxWait = 10;  
  188.                 while(isRecord){  
  189.                     //r是实际读取的数据长度,一般而言r会小于buffersize  
  190.                     int r = audioRecord.read(b, 0, b.length);  
  191.                     long v = 0;  
  192.                     // 将 buffer 内容取出,进行平方和运算  
  193.                     for (int i = 0; i < b.length; i++) {  
  194.                          v += b[i] * b[i];  
  195.                     }  
  196.                     // 平方和除以数据总长度,得到音量大小。  
  197.                     double mean = v / (double) r;  
  198.                     double volume = 10 * Math.log10(mean);  
  199.   
  200.                     wait++;  
  201.                     if(wait > maxWait){  
  202.                         wait = 0;  
  203.                         Log.d(this.getClass().getName(), "分贝值:" + volume + " " + (volume > 0));  
  204.                         if(volume > 0){  
  205.                             recordEnable = true;  
  206.                         }  
  207.                         Message msg = new Message();  
  208.                         msg.what = AnswerActivity.STATUS_PREPARE;  
  209.                         Bundle bundle = new Bundle();  
  210.                         bundle.putDouble(Device.VOICE_AMPLITUDE, volume);  
  211.                         msg.obj = bundle;  
  212.                         mHandler.sendMessage(msg);  
  213.                     }  
  214.   
  215.                     //向文件中追加内容  
  216.                     mRandomAccessFile.seek(mRandomAccessFile.length());  
  217.                     mRandomAccessFile.write(b, 0, b.length);  
  218.                 }  
  219.                 //停止录制  
  220.                 try {  
  221.                     // 防止某些手机崩溃,例如联想  
  222.                     audioRecord.stop();  
  223.                     // 彻底释放资源  
  224.                     audioRecord.release();  
  225.                     audioRecord = null;  
  226.                 }catch (IllegalStateException e){  
  227.                     e.printStackTrace();  
  228.                 }  
  229.                 mRandomAccessFile.close();  
  230.             } catch (FileNotFoundException e) {  
  231.                 // TODO Auto-generated catch block  
  232.                 e.printStackTrace();  
  233.             } catch (IOException e) {  
  234.                 // TODO Auto-generated catch block  
  235.                 e.printStackTrace();  
  236.             }  
  237.             return null;  
  238.         }  
  239.     }  
  240.       
  241.     class AudioEncoderTask extends AsyncTask{  
  242.   
  243.         @Override  
  244.         protected void onPreExecute() {  
  245.             // TODO Auto-generated method stub  
  246.             super.onPreExecute();  
  247.             if(mProgressDialog != null && !mProgressDialog.isShowing()){  
  248. //              mProgressDialog.show();  
  249.                 Message msg = new Message();  
  250.                 msg.what = 2;  
  251.                 mHandler.sendMessage(msg);  
  252.             }  
  253.         }  
  254.   
  255.         @Override  
  256.         protected Long doInBackground(Void... params) {  
  257.             // TODO Auto-generated method stub  
  258.             encodeAudio();  
  259.             return null;  
  260.         }  
  261.   
  262.         @Override  
  263.         protected void onPostExecute(Long result) {  
  264.             // TODO Auto-generated method stub  
  265.             super.onPostExecute(result);  
  266.             if(mProgressDialog.isShowing()){  
  267.                 mProgressDialog.cancel();  
  268.                 mProgressDialog.dismiss();  
  269.             }  
  270.         }  
  271.     }  
  272.       
  273.     /** 
  274.      * 清空音频录制文件夹中的所有文件 
  275.      * @param isRecorded 
  276.      */  
  277.     public void deleteAllFiles(int isRecorded){  
  278.          File[] files = new File(FileUtils.getAudioRecordFilePath()).listFiles();  
  279.         switch (isRecorded) {  
  280.         case RECORDED_INIT_DELETE:  
  281.             for(File file: files){  
  282.                 file.delete();  
  283.             }  
  284.             break;  
  285.         case RECORDED_COMPLETED_DELETE:  
  286.             for(File file: files){  
  287.                 if(!file.getName().equals(mAudioRecordFileName + Constants.M4A_SUFFIX)){  
  288.                     file.delete();  
  289.                 }  
  290.             }  
  291.             break;  
  292.         default:  
  293.             break;  
  294.         }  
  295.     }  
  296.   
  297.     public boolean isRecordEnable() {  
  298.         return recordEnable;  
  299.     }  
  300. }  

更多相关文章

  1. Android(安卓)Studio NDK及so文件开发 以及常见错误
  2. android进行录音功能并保存播放
  3. Android上传图片到服务器,android-async-http上传图片到服务器
  4. Intent(open file) android
  5. Android(安卓)源代码编后的目录分析
  6. Android系统权限和root权限
  7. Android(安卓)Studio主要目录及文件简介
  8. Android(安卓)如何判断CPU是32位还是64位
  9. NPM 和webpack 的基础使用

随机推荐

  1. Android和PC端通过局域网文件同步
  2. Android——Notifications笔记
  3. Android fragment在xml中使用没添加ID
  4. android ListView 的使用
  5. Android 给View加圆角
  6. Android :java.lang.RuntimeException: t
  7. Android的系统通知栏小例子
  8. Android剪贴板操作
  9. 解决android.os.DeadObjectException问题
  10. Android中获取应用程序(包)的信息-----Pa