2015年05月14日 12:11:55 wyyl1 阅读数:26347更多
个人分类: android判断是否禁用了录音权限Android
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wyyl1/article/details/45719099
问题:
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 block
e.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
class AudioRecordTask extends AsyncTask
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
if(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 block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
class AudioEncoderTask extends AsyncTask
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
if(mProgressDialog != null && !mProgressDialog.isShowing()){
// mProgressDialog.show();
Message msg = new Message();
msg.what = 2;
mHandler.sendMessage(msg);
}
}
@Override
protected Long doInBackground(Void... params) {
// TODO Auto-generated method stub
encodeAudio();
return null;
}
@Override
protected void onPostExecute(Long result) {
// TODO Auto-generated method stub
super.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;
}
}