本文主要是介绍Android使用AudioRecord遇到的问题与解决方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
问题:
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<Void, Void, Void>{
-
@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<Void, Void, Long>{
-
@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;
-
}
这篇关于Android使用AudioRecord遇到的问题与解决方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!