基礎知識
度量聲音強度,大家最熟悉的單位就是分貝(decibel,縮寫爲dB)。這是一個無綱量的相對單位,計算公式如下:
分子是測量值的聲壓,分母是參考值的聲壓(20微帕,人類所能聽到的最小聲壓)。因此日常中說道聲音強度是多少多少分貝時,都是默認了一個很小的參考值的。
而Android設備傳感器可以提供的物理量是場的幅值(amplitude),常用下列公式計算分貝值:
從SDK中讀取了某段音頻數據的振幅後,取最大振幅或平均振幅(可以用平方和平均,或絕對值的和平均),代入上述公式的A1。
現在問題是,作爲參考值的振幅A0取多少呢?
博主查閱很多帖子、博文,這裏是最一團漿糊的地方。有的博文取600,是基於它視噪音的振幅爲600的假設,此時算出來的是相對背景噪音的分貝值,要是用戶不對麥克風發出聲音,算出的基本都是0分貝。而用戶實際使用場景下的背景噪音大小千差萬別,咱要是也照葫蘆畫瓢就不對了,尤其是對於那些製作絕對分貝計的需求,應找出20微帕聲壓值對應的振幅(或者也可以拿一個標準分貝計做校準參考)。
遵循以往的優良傳統,還是先上代碼吧,下面是佈局activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#EEEEEE" >
<LinearLayout
android:id="@+id/record_ll"
android:layout_width="200dp"
android:layout_height="33dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:background="@drawable/recode_language_bg_nor"
android:gravity="center"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按住 錄製"
android:textColor="#777777"
android:textSize="14sp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@drawable/record_language_img2" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/record_ll"
android:layout_marginBottom="10dp"
android:background="#464646" >
<RelativeLayout
android:id="@+id/record_center_rel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" >
<LinearLayout
android:id="@+id/record_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="horizontal" >
<ImageView
android:layout_width="39dp"
android:layout_height="70dp"
android:background="@drawable/record_language_img" />
<ImageView
android:id="@+id/record_language_intensity_img"
android:layout_width="22dp"
android:layout_height="49dp"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="21dp"
android:src="@drawable/record_language_bg" />
</LinearLayout>
<RelativeLayout
android:id="@+id/record_language_complete_rel"
android:layout_width="110dp"
android:layout_height="110dp"
android:layout_centerInParent="true"
android:visibility="gone" >
<ImageView
android:id="@+id/record_language_complete_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/record_language_complete_bg" />
<ImageView
android:id="@+id/record_language_play_img"
android:layout_width="30dp"
android:layout_height="40dp"
android:layout_centerInParent="true"
android:background="@drawable/record_language_stop_img" />
</RelativeLayout>
</RelativeLayout>
<TextView
android:id="@+id/record_note_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/record_center_rel"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:gravity="center"
android:text="會員可添加\n最長60秒音頻介紹"
android:textColor="#ffffff"
android:textSize="14sp" />
<TextView
android:id="@+id/record_language_time_text"
android:layout_width="50dp"
android:layout_height="20dp"
android:background="@drawable/record_language_time_bg"
android:layout_centerHorizontal="true"
android:layout_below="@id/record_center_rel"
android:layout_marginTop="10dp"
android:textSize="12sp"
android:textColor="#ffffff"
android:gravity="center_vertical"
android:text="0"
android:paddingLeft="25dp"
/>
</RelativeLayout>
<TextView
android:id="@+id/min_time_length"
android:layout_width="130dp"
android:layout_height="30dp"
android:background="@drawable/record_language_min_time_bg"
android:text="錄音時長不足2秒"
android:gravity="center"
android:textSize="12sp"
android:textColor="#ffffff"
android:layout_centerInParent="true"
android:visibility="visible"
/>
</RelativeLayout>
老規矩,不多說,下面看一下activity的代碼:
package com.example.recordlanguage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import android.app.Activity;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnInfoListener;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.example.recordlanguage.RecordEngine.RecordListener;
import com.example.recordlanguage.RecordEngine.RecordTimeListener;
import com.example.recordlanguage.RecordEngine.VolumnChangeListener;
/**
* 語音簡介
*
* @author xiaoyf
*
* @createTime 2016年1月26日 下午5:52:58
*/
public class MainActivity extends Activity implements OnClickListener,
OnTouchListener, RecordListener, OnInfoListener, RecordTimeListener {
private LinearLayout record_ll;
private LinearLayout record_bg;
private ImageView record_language_intensity_img;
private TextView record_note_text;
private RelativeLayout record_language_complete_rel;
private ImageView record_language_complete_img;
private ImageView record_language_play_img;
private TextView record_language_time_text;
private TextView min_time_length;
/**
* 是否正在播放錄音: true:正在播放; false:沒有正在播放的視頻
*/
private boolean isPlaying = false;
private String mLocalRecordFilePath;
private RecordEngine mRecordEngine;
/**
* 錄音時間是否超時
*/
private boolean isRecordTimeOut = false;
private int delayTime = 1000;
private Handler mHintHandler = new Handler();
private Runnable mStopHint = new Runnable() {
public void run() {
// 錄音按鈕不可以點擊
record_ll.setClickable(false);
record_ll.setPressed(false);
record_ll.setFocusable(false);
min_time_length.setVisibility(View.GONE);
mHintHandler.removeCallbacks(mStopHint);
}
};
private Runnable mStartHint = new Runnable() {
public void run() {
mHintHandler.removeCallbacks(mStartHint);
}
};
private Animation animation;
private MediaPlayer mediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
if (mRecordEngine != null) {
mRecordEngine.RecordStop();
mRecordEngine.RecordDelete();
}
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
isPlaying = false;
record_language_complete_img.clearAnimation();
record_language_play_img
.setBackgroundResource(R.drawable.record_language_stop_img);
}
}
/**
* 初始化控件
*/
private void initViews() {
// TODO Auto-generated method stub
record_ll = (LinearLayout) findViewById(R.id.record_ll);
record_bg = (LinearLayout) findViewById(R.id.record_bg);
record_language_intensity_img = (ImageView) findViewById(R.id.record_language_intensity_img);
record_note_text = (TextView) findViewById(R.id.record_note_text);
record_language_complete_rel = (RelativeLayout) findViewById(R.id.record_language_complete_rel);
record_language_complete_img = (ImageView) findViewById(R.id.record_language_complete_img);
record_language_play_img = (ImageView) findViewById(R.id.record_language_play_img);
record_language_time_text = (TextView) findViewById(R.id.record_language_time_text);
min_time_length = (TextView) findViewById(R.id.min_time_length);
setVisibility();
record_bg.setVisibility(View.VISIBLE);
record_note_text.setVisibility(View.VISIBLE);
record_language_play_img.setOnClickListener(this);
record_ll.setOnTouchListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.record_language_play_img:// 播放或暫停錄音
if (isPlaying) {// 正在播放
record_language_play_img
.setBackgroundResource(R.drawable.record_language_stop_img);
isPlaying = false;
record_language_complete_img.clearAnimation();
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
} else {// 沒有正在播放
record_language_play_img
.setBackgroundResource(R.drawable.record_language_play_img);
isPlaying = true;
if (animation == null) {
animation = AnimationUtils.loadAnimation(this,
R.anim.record_language_play_anim);
animation.setInterpolator(new LinearInterpolator());// 不停頓
}
record_language_complete_img.startAnimation(animation);
mediaPlayer();
}
break;
default:
break;
}
}
/**
* 播放語音簡介
*/
private void mediaPlayer() {
// TODO Auto-generated method stub
try {
if (mediaPlayer == null)
mediaPlayer = new MediaPlayer();
boolean isPlay = false;
try {
isPlay = mediaPlayer.isPlaying();
} catch (Exception e) {
// TODO: handle exception
}
if (isPlay) {
mediaPlayer.reset();// 重置爲初始狀態
}
try {
transferFile(mLocalRecordFilePath + "tmp", mLocalRecordFilePath);
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.setDataSource(mLocalRecordFilePath);
mediaPlayer.prepare();// 緩衝
mediaPlayer.start();// 開始
mediaPlayer
.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {// 播出完畢事件
@Override
public void onCompletion(MediaPlayer arg0) {
mediaPlayer.stop();
mediaPlayer.release();// 釋放資源
mediaPlayer = null;
isPlaying = false;
record_language_complete_img.clearAnimation();
record_language_play_img
.setBackgroundResource(R.drawable.record_language_stop_img);
}
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {// 錯誤處理事件
@Override
public boolean onError(MediaPlayer player, int arg1,
int arg2) {
mediaPlayer.stop();
mediaPlayer.release();// 釋放資源
mediaPlayer = null;
Toast.makeText(getApplicationContext(), "語音播放有誤",
Toast.LENGTH_LONG).show();
isPlaying = false;
record_language_complete_img.clearAnimation();
record_language_play_img
.setBackgroundResource(R.drawable.record_language_stop_img);
return false;
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
boolean isPlay = false;
try {
isPlay = mediaPlayer.isPlaying();
} catch (Exception e2) {
// TODO: handle exception
}
if (isPlay) {
mediaPlayer.stop();
mediaPlayer.release();// 釋放資源
mediaPlayer = null;
}
Toast.makeText(getApplicationContext(), "語音播放有誤", Toast.LENGTH_LONG)
.show();
isPlaying = false;
record_language_complete_img.clearAnimation();
record_language_play_img
.setBackgroundResource(R.drawable.record_language_stop_img);
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.record_ll:// 錄音
recordLanguage(event);
break;
default:
break;
}
return true;
}
/**
* 開始錄音
*
* @param event
*/
private boolean recordLanguage(MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
boolean isPlay = false;
try {
if (mediaPlayer != null)
isPlay = mediaPlayer.isPlaying();
} catch (Exception e2) {
// TODO: handle exception
}
if (isPlay) {
mediaPlayer.stop();
mediaPlayer.release();// 釋放資源
mediaPlayer = null;
isPlaying = false;
record_language_complete_img.clearAnimation();
record_language_play_img
.setBackgroundResource(R.drawable.record_language_stop_img);
}
try {
initVoiceModel();
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}
isRecordTimeOut = false;
try {
startRecord();
} catch (Exception e) {
mRecordEngine.RecordStop();
mRecordEngine.RecordDelete();
e.printStackTrace();
Toast.makeText(getApplicationContext(), "語音模塊初始化失敗,請重試!",
Toast.LENGTH_LONG).show();
break;
}
// 提示框顯示: 正在錄音...
mHintHandler.removeCallbacks(mStopHint);
mHintHandler.post(mStartHint);
setVisibility();
record_bg.setVisibility(View.VISIBLE);
record_language_time_text.setVisibility(View.VISIBLE);
record_language_time_text.setText("0");
record_language_time_text.setTextColor(0xffffffff);
record_ll.setBackgroundResource(R.drawable.recode_language_bg_sel);
break;
case MotionEvent.ACTION_UP:
// Log.d("bbb", "擡起 MotionEvent.ACTION_UP");
record_language_intensity_img.getDrawable().setLevel(0);
record_ll.setBackgroundResource(R.drawable.recode_language_bg_nor);
if (!mRecordEngine.ismRecording()) {
return false;
}
mRecordEngine.RecordStop();
// 錄音結束處理
long recordTime = mRecordEngine.getRecordTime();
if (recordTime < 2000) {
setVisibility();
record_bg.setVisibility(View.VISIBLE);
record_language_time_text.setVisibility(View.VISIBLE);
min_time_length.setVisibility(View.VISIBLE);
mHintHandler.postDelayed(mStopHint, delayTime);
return false;
} else if (!isRecordTimeOut) {
setVisibility();
record_language_complete_rel.setVisibility(View.VISIBLE);
record_language_time_text.setVisibility(View.VISIBLE);
}
break;
case MotionEvent.ACTION_CANCEL:// 當權限訪問的時候,彈起權限問詢框的時候會調用
record_ll.setBackgroundResource(R.drawable.recode_language_bg_nor);
if (!mRecordEngine.ismRecording()) {
return false;
}
mRecordEngine.RecordStop();
mRecordEngine.RecordDelete();
setVisibility();
record_bg.setVisibility(View.VISIBLE);
record_note_text.setVisibility(View.VISIBLE);
break;
case MotionEvent.ACTION_MOVE:
break;
default:
break;
}
return true;
}
private void setVisibility() {
record_bg.setVisibility(View.GONE);
record_note_text.setVisibility(View.GONE);
record_language_complete_rel.setVisibility(View.GONE);
record_language_time_text.setVisibility(View.GONE);
min_time_length.setVisibility(View.GONE);
}
public boolean pointInView(View view, float localX, float localY) {
return localX >= 0 && localX < (view.getRight() - view.getLeft())
&& localY >= 0 && localY < (view.getBottom() - view.getTop());
}
/**
* 初始化語音模塊
*
* @throws FileNotFoundException
*/
private void initVoiceModel() throws FileNotFoundException {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
mLocalRecordFilePath = Environment.getExternalStorageDirectory()
.getAbsolutePath()
+ "/record_voice_"
+ System.currentTimeMillis() + ".amr";
mRecordEngine = new RecordEngine(new File(mLocalRecordFilePath
+ "tmp"), this);
mRecordEngine.setRecordListener(this);
mRecordEngine.setInfoListener(this);
mRecordEngine.setRecordTimeListener(this);
}
}
/**
* 語音錄製
*
* @throws IllegalStateException
* @throws IOException
* @throws RuntimeException
*/
private void startRecord() throws IllegalStateException, IOException,
RuntimeException {
// 註冊音量變化偵聽器
mRecordEngine.SetVolumnChangeListener(new VolumnChangeListener() {
@Override
public void change(int level) {
record_language_intensity_img.getDrawable().setLevel(level);
}
});
// 開始錄音
mRecordEngine.RecordStart();
}
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
// TODO Auto-generated method stub
if (what >= MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
mRecordEngine.RecordStop();
setVisibility();
record_language_complete_rel.setVisibility(View.VISIBLE);
record_language_time_text.setVisibility(View.VISIBLE);
isRecordTimeOut = true;
mHintHandler.post(mStopHint);
record_language_time_text.setText("60");
record_language_time_text.setTextColor(Color.RED);
Toast.makeText(getApplicationContext(), "對不起,最長錄音60秒!",
Toast.LENGTH_LONG).show();
}
}
@Override
public void onPrepare() {
// TODO Auto-generated method stub
}
@Override
public void onComplated() {
// TODO Auto-generated method stub
}
@Override
public void refresh(long time) {
// TODO Auto-generated method stub
long recordTime = (time + 500) / 1000;
if (recordTime <= 50) {
record_language_time_text.setText(recordTime + "");
record_language_time_text.setTextColor(0xffffffff);
} else if (recordTime > 50 && recordTime <= 60) {
record_language_time_text.setText(recordTime + "");
record_language_time_text.setTextColor(Color.RED);
} else {
mRecordEngine.RecordStop();
setVisibility();
record_language_complete_rel.setVisibility(View.VISIBLE);
record_language_time_text.setVisibility(View.VISIBLE);
isRecordTimeOut = true;
mHintHandler.post(mStopHint);
}
}
/**
* 通過管道快速複製文件
*
* @param srcFile
* @param dstFile
* @throws IOException
*/
public static void transferFile(String srcFile, String dstFile)
throws IOException {
FileInputStream fin = new FileInputStream(srcFile);
FileOutputStream fout = new FileOutputStream(dstFile);
FileChannel fcin = fin.getChannel();
FileChannel fcout = fout.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024); // 分配1KB作爲緩衝區
while (true) {
buffer.clear(); // 每次使用必須置空緩衝區
int r = fcin.read(buffer);
if (r == -1) {
break;
}
buffer.flip(); // 寫入前使用flip這個方法
fcout.write(buffer);
}
}
}
其實這個activity也沒有過多要強調的,唯一的一點就是,當我們第一次使用這個demo進行錄音,我們按下按鈕開始錄音的時候,Android系統會彈起一個權限問詢彈框,這個時候系統會回調我們寫的ontouch()方法,其中的action是Action_Cancle,這個時候,我們需要在裏面做一些基本的處理。
下面我們來看看這個項目的核心代碼:
package com.example.recordlanguage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import android.app.Service;
import android.content.Context;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.media.MediaRecorder.OnInfoListener;
import android.os.Handler;
import android.util.Log;
/**
* 錄音的工具類
*
* @author xiaoyf
*
* @createTime 2016年1月27日 下午3:54:42
*/
public class RecordEngine {
final int MIN_AMPLITUDE_VALUE = 800; // 錄音程序可以識別的最小聲音振幅
final int MAX_AMPLITUDE_VALUE = 32000;// 最大值有人說[32767]; // 錄音程序可以識別的最大聲音振幅
final int VOLUMN_LEVEL_MAX = 7; // 音量分成7級
final int ampPerLevel = (MAX_AMPLITUDE_VALUE - MIN_AMPLITUDE_VALUE)
/ VOLUMN_LEVEL_MAX;
private int mVolumnLevel = 0;
private File mRecordFile = null;
private MediaRecorder mMediaRecorder;
private MediaPlayer mMediaPlayer = null;
private boolean mRecording = false;
private VolumnChangeListener mVolumnChangeListener;
private OnInfoListener mInfoListener;
private RecordTimeListener recordTimeListener;
private AudioManager audioManager;
private RecordListener listener;
private Context context;
// 錄音音量變化偵聽接口
public interface VolumnChangeListener {
public void change(int level);
}
public void SetVolumnChangeListener(VolumnChangeListener listener) {
mVolumnChangeListener = listener;
}
public void setInfoListener(OnInfoListener mInfoListener) {
this.mInfoListener = mInfoListener;
}
public interface RecordTimeListener {
void refresh(long time);
}
public void setRecordTimeListener(RecordTimeListener listener) {
recordTimeListener = listener;
}
/**
* 根據頻率計算音量級別
*
* @return 音量級別
*/
private int CaculateVolumnLevel() {
int ratio = mMediaRecorder.getMaxAmplitude() / 600;
int db = 0;// 分貝
if (ratio > 1)
db = (int) (20 * Math.log10(ratio));
db /= 4;
db = Math.min(db, 10);
return db;
}
// 錄音定時器,更新狀態
private int mTimingDelay = 100;
private long mRecordTime = 0;
Handler timingHandler = new Handler();
/**
* 更新音量級別
*/
Runnable timingRunnable = new Runnable() {
public void run() {
int newLevel = CaculateVolumnLevel();
if (mVolumnLevel != newLevel) {
mVolumnLevel = newLevel;
if (mVolumnChangeListener != null)
mVolumnChangeListener.change(mVolumnLevel);
}
// 循環啓動定時器
timingHandler.postDelayed(timingRunnable, mTimingDelay);
}
};
/**
* 記錄錄音的時間
*/
Runnable recordTimeRunnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if (recordTimeListener != null) {
long time = System.currentTimeMillis() - mRecordTime;
recordTimeListener.refresh(time);
// 循環啓動定時器
timingHandler.postDelayed(recordTimeRunnable, 950);
}
}
};
private void startTiming() {
mRecordTime = System.currentTimeMillis() + 800L;
timingHandler.postDelayed(timingRunnable, mTimingDelay);
timingHandler.postDelayed(recordTimeRunnable, 950);
}
private void stopTiming() {
mRecordTime = System.currentTimeMillis() - mRecordTime;
timingHandler.removeCallbacks(timingRunnable);
timingHandler.removeCallbacks(recordTimeRunnable);
}
/**
* 獲取本次錄音時間長度
*
* @return
*/
public long getRecordTime() {
return mRecordTime;
}
public RecordEngine(Context mContext) throws FileNotFoundException {
this(null, mContext);
this.context = mContext;
}
public RecordEngine(File recordFile, Context mContext)
throws FileNotFoundException {
if (recordFile != null) {
File dir = recordFile.getParentFile();
if (!dir.exists()) {
dir.mkdirs();
}
// 創建文件
if (!recordFile.exists()) {
try {
recordFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
mRecordFile = recordFile;
mRecordTime = System.currentTimeMillis();
audioManager = (AudioManager) mContext
.getSystemService(Service.AUDIO_SERVICE);
}
public void setRecordListener(RecordListener listener) {
this.listener = listener;
}
/* 錄音 */
public void RecordStart() throws IllegalStateException, IOException,
RuntimeException {
if (listener != null) {
listener.onPrepare();
}
mMediaRecorder = new MediaRecorder();
startTiming();
// AudioRecord audioRecord=new AudioRecord(audioSource, sampleRateInHz,
// channelConfig, audioFormat, bufferSizeInBytes)
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 聲源
// 設置音頻文件的編碼:AAC/AMR_NB/AMR_MB/Default
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);// 編碼
mMediaRecorder.setAudioEncodingBitRate(4000);// 比特率
// mMediaRecorder.setAudioSamplingRate(4000);// 採樣率
mMediaRecorder.setAudioChannels(1);// 單聲道
mMediaRecorder.setOnInfoListener(mInfoListener);
mMediaRecorder.setOutputFile(mRecordFile.getAbsolutePath());
mMediaRecorder.setMaxDuration(60 * 1000);
mMediaRecorder.prepare();
mMediaRecorder.start();
mRecording = true;
}
public void RecordStop() {
if (mRecordFile != null) {
if (mMediaRecorder != null) {
try {
mMediaRecorder.stop();
mMediaRecorder.release();
mMediaRecorder = null;
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
mRecording = false;
stopTiming();
}
if (listener != null) {
listener.onComplated();
}
listener = null;
}
public void RecordPlay(Context mContext) throws IllegalArgumentException,
SecurityException, IllegalStateException, IOException {
// FileInputStream audioFileStream = new FileInputStream(mRecordFile);
if (mRecordFile == null) {
} else {
mMediaPlayer = new MediaPlayer();
// mMediaPlayer = MediaPlayer.create(mContext,
// Uri.fromFile(mRecordFile));
// mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(mRecordFile.getAbsolutePath());
mMediaPlayer.prepare();
mMediaPlayer.start();
}
}
public int getSuitedVolume(int streamType) {
int volume = 10;
if (audioManager != null) {
int currentVolume = audioManager.getStreamVolume(streamType);
int tmpVolume = (int) (audioManager.getStreamMaxVolume(streamType) * 0.6);
// 確保音量至少爲60%
volume = currentVolume >= tmpVolume ? currentVolume
: (tmpVolume > volume ? tmpVolume : volume);
}
return volume;
}
public void RecordPlayStop() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
}
/**
* 設置播放音量
*
* @param volume
* 音量,如果設置爲-1則設置爲當前系統音量
* */
public void setRecordPlayerVolume(int volume) {
if (audioManager != null) {
volume = volume == -1 ? audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC) : volume;
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
volume, AudioManager.FLAG_PLAY_SOUND);
}
}
public String RecordGetPath() {
String path = mRecordFile.getPath();
return path;
}
public void RecordDelete() {
if (mRecordFile != null) {
if (mRecordFile.exists())
mRecordFile.delete();
}
}
public MediaPlayer getMediaPlayer() {
return mMediaPlayer;
}
public boolean ismRecording() {
return mRecording;
}
public interface RecordListener {
public void onPrepare();
public void onComplated();
}
}
這個核心方法裏面會包含一些,對錄音硬件的基本的設置、以及一些回調方法,用來監聽音量的變化、錄音開始和結束、錄音時間
基本到這裏就結束啦,我再給大家分享一篇很不錯的獲取錄音分貝的文章:http://blog.csdn.net/greatpresident/article/details/38402147