首先添加錄音權限
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
方式一:MediaRecorder
private MediaRecorder mediaRecorder;
private boolean isRecording;
設定存儲路徑
private final String FILE = Environment.getExternalStorageDirectory() + File.separator + "volomeDemo.aac";
初始化mediaRecorder
initMediaRecorder();
public void initMediaRecorder()
{
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setOutputFile(FILE);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
Log.w("madiarecorder","初始化成功");
try{
mediaRecorder.prepare();
mediaRecorder.start();
isRecording=true;
Log.w("madiarecorder","已啟動");
}catch(Exception e)
{
Log.w("madiarecorder","異常");
}
}
利用
mediaRecorder.getMaxAmplitude();
得到目前某一時刻檢測到的音量,這個數值通常可以上萬
建立一個可視的繪圖線程,一會兒實時将音量繪制出來
class Draw_thread extends Thread
{
@Override
public void run(){
while(true)
{
if (mediaRecorder == null) {
initMediaRecorder();
}
try{
myDraw();
Thread.sleep(30);
}
catch (Exception e) {
Log.w("線程", "異常");
}
}
}
} initMediaRecorder();
}
try{
myDraw();
Thread.sleep(30);
}
catch (Exception e) {
Log.w("線程", "異常");
}
}
}
}
利用
isRecording
記錄是否在監聽中
重寫銷毀方法
protected void onDestroy() {
super.onDestroy();
if (mediaRecorder!=null&&isRecording) {
isRecording = false;
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
mediaRecorder = null;
}
}
方法二:AudioRecord
聲明變量
private AudioRecord audioRecord;
private int bufferSize;
private byte[] buffer;
初始化函數
public void initAudioRecord()
{
bufferSize = AudioRecord.getMinBufferSize(16000, AudioFormat.CHANNEL_IN_MONO , AudioFormat.ENCODING_PCM_16BIT);
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 16000,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSize);
audioRecord.startRecording();
// 用于讀取的 buffer
buffer= new byte[bufferSize];
}
在繪圖線程中擷取某一時刻音量,和mediaRecorder.getMaxAmplitude();作用差不多
try {
int r = audioRecord.read(buffer, 0, bufferSize);
int v = 0;
// 将 buffer 内容取出,進行平方和運算
for (int i = 0; i < buffer.length; i++) {
// 這裡沒有做運算的優化,為了更加清晰的展示代碼
v += buffer[i] * buffer[i];
}
// 平方和除以資料總長度,得到音量大小。可以擷取白噪聲值,然後對實際采樣進行标準化。
// 如果想利用這個數值進行操作,建議用 sendMessage 将其抛出,在 Handler 裡進行處理。
double dB = 10*Math.log10(v/(double)r);
得到的db就是目前音量大小
但是這個數值基本隻能用來判斷有沒有聲音,
而分别不出來音量大小,是以建議使用第一種方式
繪圖函數
canvas.drawColor(Color.BLACK);//背景
canvas.drawLine(200,250,200,250-6*(int)dB,paint);//子線程更新UI,如果是監聽器等調用的函數,是屬于主線程裡的!!!
canvas.drawText(7*(int)dB+"",150,30,paint);
int maxa=mediaRecorder.getMaxAmplitude();
if(maxa<1600)
{
canvas.drawLine(100,250,100,250-maxa/8,paint);
}
else
{
canvas.drawLine(100,250,100,50,paint);
paint.setColor(Color.RED);
canvas.drawLine(150,250,150,250-maxa/100,paint);
paint.setColor(Color.GREEN);
}
canvas.drawText(maxa+"",30,30,paint);
mHandler.post(new Runnable() {
@Override
public void run() {
iv_audio.setImageBitmap(bitmap);
}
}); dB+"",150,30,paint);
int maxa=mediaRecorder.getMaxAmplitude();
if(maxa<1600)
{
canvas.drawLine(100,250,100,250-maxa/8,paint);
}
else
{
canvas.drawLine(100,250,100,50,paint);
paint.setColor(Color.RED);
canvas.drawLine(150,250,150,250-maxa/100,paint);
paint.setColor(Color.GREEN);
}
canvas.drawText(maxa+"",30,30,paint);
mHandler.post(new Runnable() {
@Override
public void run() {
iv_audio.setImageBitmap(bitmap);
}
});
用了draw和paint展示了一下兩種方式的效果
我将第一種方法獲得的音量用綠色(小數值時)+紅色(大數值時)顯示出來
這個綠色随着聲音的增大,變化明顯
而第二種方式,基本隻要有點聲音,綠色就滿了
沒聲音時數值,還可能為負值
是以第一種好用