Android實(shí)現(xiàn)錄音方法(仿微信語(yǔ)音、麥克風(fēng)錄音、發(fā)送語(yǔ)音、解決5.0以上BUG)
先給大家展示下效果圖,如果大家感覺(jué)不錯(cuò),請(qǐng)參考使用方法,
效果圖如下所示:

使用方法:
錄音工具類(lèi):AudioRecoderUtils.java,代碼如下:
public class AudioRecoderUtils {
//文件路徑
private String filePath;
//文件夾路徑
private String FolderPath;
private MediaRecorder mMediaRecorder;
private final String TAG = "fan";
public static final int MAX_LENGTH = 1000 * 60 * 10;// 最大錄音時(shí)長(zhǎng)1000*60*10;
private OnAudioStatusUpdateListener audioStatusUpdateListener;
/**
* 文件存儲(chǔ)默認(rèn)sdcard/record
*/
public AudioRecoderUtils(){
//默認(rèn)保存路徑為/sdcard/record/下
this(Environment.getExternalStorageDirectory()+"/record/");
}
public AudioRecoderUtils(String filePath) {
File path = new File(filePath);
if(!path.exists())
path.mkdirs();
this.FolderPath = filePath;
}
private long startTime;
private long endTime;
/**
* 開(kāi)始錄音 使用amr格式
* 錄音文件
* @return
*/
public void startRecord() {
// 開(kāi)始錄音
/* ①I(mǎi)nitial:實(shí)例化MediaRecorder對(duì)象 */
if (mMediaRecorder == null)
mMediaRecorder = new MediaRecorder();
try {
/* ②setAudioSource/setVedioSource */
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 設(shè)置麥克風(fēng)
/* ②設(shè)置音頻文件的編碼:AAC/AMR_NB/AMR_MB/Default 聲音的(波形)的采樣 */
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
/*
* ②設(shè)置輸出文件的格式:THREE_GPP/MPEG-4/RAW_AMR/Default THREE_GPP(3gp格式
* ,H263視頻/ARM音頻編碼)、MPEG-4、RAW_AMR(只支持音頻且音頻編碼要求為AMR_NB)
*/
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
filePath = FolderPath + TimeUtils.getCurrentTime() + ".amr" ;
/* ③準(zhǔn)備 */
mMediaRecorder.setOutputFile(filePath);
mMediaRecorder.setMaxDuration(MAX_LENGTH);
mMediaRecorder.prepare();
/* ④開(kāi)始 */
mMediaRecorder.start();
// AudioRecord audioRecord.
/* 獲取開(kāi)始時(shí)間* */
startTime = System.currentTimeMillis();
updateMicStatus();
Log.e("fan", "startTime" + startTime);
} catch (IllegalStateException e) {
Log.i(TAG, "call startAmr(File mRecAudioFile) failed!" + e.getMessage());
} catch (IOException e) {
Log.i(TAG, "call startAmr(File mRecAudioFile) failed!" + e.getMessage());
}
}
/**
* 停止錄音
*/
public long stopRecord() {
if (mMediaRecorder == null)
return 0L;
endTime = System.currentTimeMillis();
//有一些網(wǎng)友反應(yīng)在5.0以上在調(diào)用stop的時(shí)候會(huì)報(bào)錯(cuò),翻閱了一下谷歌文檔發(fā)現(xiàn)上面確實(shí)寫(xiě)的有可能會(huì)報(bào)錯(cuò)的情況,捕獲異常清理一下就行了,感謝大家反饋!
try {
mMediaRecorder.stop();
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
audioStatusUpdateListener.onStop(filePath);
filePath = "";
}catch (RuntimeException e){
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
File file = new File(filePath);
if (file.exists())
file.delete();
filePath = "";
}
return endTime - startTime;
}
/**
* 取消錄音
*/
public void cancelRecord(){
try {
mMediaRecorder.stop();
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
}catch (RuntimeException e){
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
}
File file = new File(filePath);
if (file.exists())
file.delete();
filePath = "";
}
private final Handler mHandler = new Handler();
private Runnable mUpdateMicStatusTimer = new Runnable() {
public void run() {
updateMicStatus();
}
};
private int BASE = 1;
private int SPACE = 100;// 間隔取樣時(shí)間
public void setOnAudioStatusUpdateListener(OnAudioStatusUpdateListener audioStatusUpdateListener) {
this.audioStatusUpdateListener = audioStatusUpdateListener;
}
/**
* 更新麥克狀態(tài)
*/
private void updateMicStatus() {
if (mMediaRecorder != null) {
double ratio = (double)mMediaRecorder.getMaxAmplitude() / BASE;
double db = 0;// 分貝
if (ratio > 1) {
db = 20 * Math.log10(ratio);
if(null != audioStatusUpdateListener) {
audioStatusUpdateListener.onUpdate(db,System.currentTimeMillis()-startTime);
}
}
mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);
}
}
public interface OnAudioStatusUpdateListener {
/**
* 錄音中...
* @param db 當(dāng)前聲音分貝
* @param time 錄音時(shí)長(zhǎng)
*/
public void onUpdate(double db,long time);
/**
* 停止錄音
* @param filePath 保存路徑
*/
public void onStop(String filePath);
}
}
使用很簡(jiǎn)單,主要就是開(kāi)始錄音startRecord()、取消錄音cancelRecord()、結(jié)束錄音stopRecord()和錄音監(jiān)聽(tīng)setOnAudioStatusUpdateListener(),注意,取消錄音不保存文件,結(jié)束錄音會(huì)保存文件!
在布局文件中添加一個(gè)控件(任意一個(gè)都行)
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="按住說(shuō)話" android:textColor="@android:color/white" android:id="@+id/button" android:background="@color/colorPrimary" />
在Activity中使用:
//當(dāng)前布局文件的根layout
final RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl);
mButton = (Button) findViewById(R.id.button);
//PopupWindow的布局文件
final View view = View.inflate(this, R.layout.layout_microphone, null);
final PopupWindowFactory mPop = new PopupWindowFactory(this,view);
//PopupWindow布局文件里面的控件
mImageView = (ImageView) view.findViewById(R.id.iv_recording_icon);
mTextView = (TextView) view.findViewById(R.id.tv_recording_time);
mAudioRecoderUtils = new AudioRecoderUtils();
//錄音回調(diào)
mAudioRecoderUtils.setOnAudioStatusUpdateListener(new AudioRecoderUtils.OnAudioStatusUpdateListener() {
//錄音中....db為聲音分貝,time為錄音時(shí)長(zhǎng)
@Override
public void onUpdate(double db, long time) {
//根據(jù)分貝值來(lái)設(shè)置錄音時(shí)話筒圖標(biāo)的上下波動(dòng),下面有講解
mImageView.getDrawable().setLevel((int) (3000 + 6000 * db / 100));
mTextView.setText(TimeUtils.long2String(time));
}
//錄音結(jié)束,filePath為保存路徑
@Override
public void onStop(String filePath) {
Toast.makeText(MainActivity.this, "錄音保存在:" + filePath, Toast.LENGTH_SHORT).show();
mTextView.setText(TimeUtils.long2String(0));
}
});
//Button的touch監(jiān)聽(tīng)
mButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
mPop.showAtLocation(rl,Gravity.CENTER,0,0);
mButton.setText("松開(kāi)保存");
mAudioRecoderUtils.startRecord();
break;
case MotionEvent.ACTION_UP:
mAudioRecoderUtils.stopRecord(); //結(jié)束錄音(保存錄音文件)
// mAudioRecoderUtils.cancelRecord(); //取消錄音(不保存錄音文件)
mPop.dismiss();
mButton.setText("按住說(shuō)話");
break;
}
return true;
}
});
總結(jié)
以上所述是小編給大家介紹的Android實(shí)現(xiàn)錄音方法(仿微信語(yǔ)音、麥克風(fēng)錄音、發(fā)送語(yǔ)音、解決5.0以上BUG),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- Android音頻錄制MediaRecorder之簡(jiǎn)易的錄音軟件實(shí)現(xiàn)代碼
- Android簡(jiǎn)單的利用MediaRecorder進(jìn)行錄音的實(shí)例代碼
- Android實(shí)現(xiàn)錄音功能實(shí)現(xiàn)實(shí)例(MediaRecorder)
- Android應(yīng)用開(kāi)發(fā):電話監(jiān)聽(tīng)和錄音代碼示例
- Android App調(diào)用MediaRecorder實(shí)現(xiàn)錄音功能的實(shí)例
- 詳解Android開(kāi)發(fā)錄音和播放音頻的步驟(動(dòng)態(tài)獲取權(quán)限)
- Android實(shí)現(xiàn)語(yǔ)音播放與錄音功能
- Android編程實(shí)現(xiàn)錄音及保存播放功能的方法【附demo源碼下載】
- Android開(kāi)發(fā)四大組件之實(shí)現(xiàn)電話攔截和電話錄音
- Android實(shí)現(xiàn)錄音聲波圖
相關(guān)文章
Android Studio下載、安裝和配置+SDK+tools下載(無(wú)敵超級(jí)詳細(xì)版本)
這篇文章主要介紹了Android Studio下載、安裝和配置+SDK+tools下載(無(wú)敵超級(jí)詳細(xì)版本),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
SimpleCommand實(shí)現(xiàn)圖片下載(二)
這篇文章主要為大家詳細(xì)介紹了SimpleCommand實(shí)現(xiàn)圖片下載,并顯示到ImageView控件上,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
Android 中 退出多個(gè)activity的經(jīng)典方法
這篇文章主要介紹了Android 中 退出多個(gè)activity的經(jīng)典方法 的相關(guān)資料,本文給大家分享兩種方法,在這小編給大家推薦使用第一種方法,對(duì)此文感興趣的朋友可以參考下2016-09-09
android應(yīng)用實(shí)現(xiàn)開(kāi)機(jī)自動(dòng)啟動(dòng)方法
這篇文章主要介紹了android應(yīng)用實(shí)現(xiàn)開(kāi)機(jī)自動(dòng)啟動(dòng)方法,本文講解了原理和編碼實(shí)例,需要的朋友可以參考下2015-05-05
Android自定義View實(shí)現(xiàn)心形圖案
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)心形圖案,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
Android實(shí)現(xiàn)下載m3u8視頻文件問(wèn)題解決
這篇文章主要介紹了Android實(shí)現(xiàn)下載m3u8視頻文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-01-01
Android PopupWindow實(shí)現(xiàn)遮罩層效果
這篇文章主要為大家詳細(xì)介紹了Android PopupWindow實(shí)現(xiàn)遮罩層效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10

