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

问题:

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<Void, Void, Void>{  
  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<Void, Void, Long>{  
  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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值