這是一個(gè)錄音和播放封裝,我們有一個(gè)封裝類:
VoiceManager.class,我們播放音樂(lè)窄做,我們的view也需要對(duì)應(yīng)的變化,音樂(lè)來(lái)控制我們ui控件的變化也就是我們的時(shí)間來(lái)控制我們的ui變化枣购,所以我們需要的一個(gè)計(jì)算時(shí)間的工具類剥汤,也就是我們的VoiceTimeUtils.class
1.播放錄音的工具類--- MediaPlayer
(注意,我們可以看到在準(zhǔn)備播放的方法里面每一個(gè)返回的是布爾值允睹,當(dāng)我們的播放方法執(zhí)行了的時(shí)候就會(huì)放回true运准,沒(méi)有執(zhí)行的時(shí)候幌氮,放回的是false,這個(gè)點(diǎn)子很好胁澳,值得我們記赘没ァ!)
- 準(zhǔn)備工作:
/**
* 播放錄音準(zhǔn)備工作
*/
private boolean prepareMedia(MediaPlayer mp,String file){
boolean result = false;
try {
mp.setDataSource(file);
mp.prepare();
result = true;
} catch (Exception e) {
}
return result;
}
/**
* 播放錄音開(kāi)始
* @param mp
* @return
*/
private boolean playMedia(MediaPlayer mp){
boolean result = false;
try {
if (mp != null) {
mp.start();
result = true;
}
} catch (Exception e) {
}
return result;
}
/**
* 停止播放
* @param mp
* @param release
* @return
*/
private boolean stopMedia(MediaPlayer mp,boolean release){
boolean result = false;
try {
if (mp != null) {
mp.stop();
if (release) {
mp.release();
}
result = true;
}
} catch (Exception e) {
}
return result;
}
/**
* 暫停播放
* @param mp
* @return
*/
private boolean pauseMedia(MediaPlayer mp){
boolean result = false;
try {
if (mp != null) {
mp.pause();
result = true;
}
} catch (Exception e) {
}
return result;
}
此外我們開(kāi)啟一個(gè)線程來(lái)檢測(cè)我們的錄音聲音頻率的大芯禄:
(可以看到我們這個(gè)類中定義了一個(gè)方法叫exit他里面控制一個(gè)布爾值為false慢洋,然后在我們的run方法中用while循環(huán)來(lái)檢測(cè)我們exit方法里面布爾值是否為false,如果為false就停止錄音陆盘,否則就一直錄音)
/**
* 監(jiān)聽(tīng)錄音聲音頻率大小
*/
private class ObtainDecibelThread extends Thread{
private volatile boolean running = true;
public void exit() {
running = false;
}
@Override
public void run() {
while (running) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (mMediaRecorder == null || !running) {
break;
}
try {
final double ratio = mMediaRecorder.getMaxAmplitude()/150;
if (ratio != 0&&voiceRecordCallBack!=null) {
((Activity)context).runOnUiThread(new Runnable() {
@Override
public void run() {
double db=0;// 分貝
if (ratio > 1)
db = (int) (20 * Math.log10(ratio));
voiceRecordCallBack.recVoiceGrade((int)db);
}
});
}
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
}
2 . 我們的錄音的工具類是我們的---MediaRecorder
(可以看到我們的錄音準(zhǔn)備方法里面普筹,回調(diào)的是我們的文件存放地址,這個(gè)就很機(jī)智了隘马,還有就是我們的錄音準(zhǔn)備工作要設(shè)置的配置太防,我們簡(jiǎn)單縮寫(xiě)一下就是,ASM,AEA,UFR,還有一個(gè)就是設(shè)置我們的地址)
- 準(zhǔn)備工作:
1. 判斷我們的錄音的存放地址是否是正確:
public static File recAudioDir(String path) {
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
return file;
}
/**
* 錄音準(zhǔn)備工作 酸员,開(kāi)始錄音
*
* @param mr
* @param start
* @return
*/
@SuppressWarnings("deprecation")
private File prepareRecorder(MediaRecorder mr, boolean start) {
File recFile = null;
if (mr == null) return null;
try {
String path = recAudioDir(recordFilePath).getAbsolutePath();
recFile = new File(path, VoiceTimeUtils.getTime() + ".amr");
mr.setAudioSource(MediaRecorder.AudioSource.MIC);
mr.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mr.setOutputFile(recFile.getAbsolutePath());
mr.prepare();
if (start) {
mr.start();
if (mThread == null) {
mThread = new ObtainDecibelThread();
mThread.start();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return recFile;
}
/**
* 停止錄音和播放
*/
public void stopRecordAndPlay(){
stopRecorder(mMediaRecorder, true);
mMediaRecorder = null;
stopMedia(mMediaPlayer, true);
mMediaPlayer = null;
}
第二部分 接口
/**
* 錄音回調(diào)監(jiān)聽(tīng)
*/
public interface VoiceRecordCallBack{
//錄音中
void recDoing(long time,String strTime);
//錄音中的聲音頻率等級(jí);
void recVoiceGrade(int grade);
//錄音開(kāi)始
void recStart(boolean init);
//錄音暫停
void recPause(String str);
//錄音結(jié)束
void recFinish(long lenth,String strLenth,String path);
}
/**
* 播放錄音回調(diào)監(jiān)聽(tīng)
*/
public interface VoicePlayCallBack{
/**
* 音頻長(zhǎng)度
* 指定的某個(gè)時(shí)間段蜒车,以秒為單位
*/
void voiceTotalLenth(long time,String strTime);
/**
* 播放中
* 指定的某個(gè)時(shí)間段,以秒為單位
*/
void playDoing (long time,String strTime);
//播放暫停
void playPause();
//播放開(kāi)始
void playStart();
//播放結(jié)束
void playFinish();
}
附加一個(gè)我們判斷我們的sd卡是否存在:
/**
* SD卡是否可用
*/
public static boolean isSDCardAvailable() {
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
}
3.第三部分 具體代碼
上面我們完成了我們的準(zhǔn)備工作幔嗦,現(xiàn)在開(kāi)始我們的具體代碼:
public class VoiceManager {
public final int MSG_TIME_INTERVAL = 100;
private static VoiceManager voiceManager =null;
private Context context;
private VoiceRecordCallBack voiceRecordCallBack;
private VoicePlayCallBack voicePlayCallBack;
private SeekBar mSBPlayProgress;
// 多媒體例如聲音的狀態(tài)
public final int MEDIA_STATE_UNDEFINE = 200;
public final int MEDIA_STATE_RECORD_STOP = 210;
public final int MEDIA_STATE_RECORD_DOING = 220;
public final int MEDIA_STATE_RECORD_PAUSE = 230;
public final int MEDIA_STATE_PLAY_STOP = 310;
public final int MEDIA_STATE_PLAY_DOING = 320;
public final int MEDIA_STATE_PLAY_PAUSE = 330;
private MediaRecorder mMediaRecorder = null;
private MediaPlayer mMediaPlayer = null;
private String mRecTimePrev;
private long mRecTimeSum = 0;
private int mSavedState, mDeviceState = MEDIA_STATE_UNDEFINE;
private ArrayList<File> mRecList = new ArrayList<File>();
private ObtainDecibelThread mThread;
/**
* 錄音文件存放的位置(文件夾)
*/
private String recordFilePath = "";
/**
* 播放音頻文件位置
*/
private String playFilePath;
private VoiceManager(Context context){
this.context = context;
}
public static VoiceManager getInstance(Context context){
if(voiceManager == null){
synchronized (VoiceManager.class){
if(voiceManager == null){
voiceManager = new VoiceManager(context);
}
}
}
return voiceManager;
}
/**
* 播放器結(jié)束監(jiān)聽(tīng)
*/
private MediaPlayer.OnCompletionListener mPlayCompetedListener = new MediaPlayer.OnCompletionListener(){
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mDeviceState = MEDIA_STATE_PLAY_STOP;
mHandler.removeMessages(MSG_TIME_INTERVAL);
mMediaPlayer.stop();
mMediaPlayer.release();
if (mSBPlayProgress != null) {
mSBPlayProgress.setProgress(0);
}
if (voicePlayCallBack != null) {
voicePlayCallBack.playFinish();
}
}
};
/**
* 播放或錄音handler
*/
@SuppressLint("HandlerLeak")
private final Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
VoiceTimeUtils ts;
int current;
try {
switch (msg.what) {
case MSG_TIME_INTERVAL:
//錄音
if(mDeviceState == MEDIA_STATE_RECORD_DOING){
ts = VoiceTimeUtils.timeSpanToNow(mRecTimePrev);
mRecTimeSum += ts.mDiffSecond;
mRecTimePrev = VoiceTimeUtils.getTimeStrFromMillis(ts.mNowTime);
ts = VoiceTimeUtils.timeSpanSecond(mRecTimeSum);
//回調(diào)錄音時(shí)間
if (voiceRecordCallBack != null) {
voiceRecordCallBack.recDoing(mRecTimeSum, String.format("%02d:%02d:%02d",
ts.mSpanHour, ts.mSpanMinute, ts.mSpanSecond));
}
mHandler.sendEmptyMessageDelayed(MSG_TIME_INTERVAL, 1000);
}
//播放
else if (mDeviceState == MEDIA_STATE_PLAY_DOING) {
current = mMediaPlayer.getCurrentPosition();
if (mSBPlayProgress != null) {
mSBPlayProgress.setProgress(current);
}
ts = VoiceTimeUtils.timeSpanSecond(current / 1000);
//回調(diào)播放進(jìn)度
if (voicePlayCallBack != null) {
voicePlayCallBack.playDoing(current / 1000, String.format("%02d:%02d:%02d",
ts.mSpanHour, ts.mSpanMinute, ts.mSpanSecond));
}
mHandler.sendEmptyMessageDelayed(MSG_TIME_INTERVAL, 1000);
}
break;
default:
break;
}
} catch (Exception e) {
}
}
};
/*********************************錄音操作begin***************************/
/**
* 設(shè)置錄音監(jiān)聽(tīng)
* @param callback
*/
public void setVoiceRecordListener(VoiceRecordCallBack callback){
this.voiceRecordCallBack = callback;
}
/**
* 開(kāi)始錄音(外部調(diào)用)
* @param filePath
*/
public void startVoiceRecord(String filePath){
if (!isSDCardAvailable()) return ;
this.recordFilePath = filePath;
startVoiceRecord(true);
}
/**
* 繼續(xù)或暫停錄音
*/
public void pauseOrStartVoiceRecord(){
if (mDeviceState == MEDIA_STATE_RECORD_DOING) {
mDeviceState = MEDIA_STATE_RECORD_PAUSE;
stopRecorder(mMediaRecorder, true);
mMediaRecorder = null;
voiceRecordCallBack.recPause("已暫停");
} else {
startVoiceRecord(false);
}
}
/**
* 完成錄音
*/
public void stopVoiceRecord(){
try {
mHandler.removeMessages(MSG_TIME_INTERVAL);
mDeviceState = MEDIA_STATE_RECORD_STOP;
stopRecorder(mMediaRecorder, true);
mMediaRecorder = null;
if (VoiceTimeUtils.timeSpanSecond(mRecTimeSum).mSpanSecond == 0) {
Toast.makeText(context, "時(shí)間過(guò)短", Toast.LENGTH_SHORT).show();
} else {
File file = getOutputVoiceFile(mRecList);
if (file != null && file.length() > 0) {
cleanFieArrayList(mRecList);
//TODO 這里可以返回?cái)?shù)據(jù) setResult
final VoiceTimeUtils ts = VoiceTimeUtils.timeSpanSecond(mRecTimeSum);
//完成錄音
if (voiceRecordCallBack != null) {
voiceRecordCallBack.recFinish(mRecTimeSum, String.format("%02d:%02d:%02d",
ts.mSpanHour, ts.mSpanMinute, ts.mSpanSecond),file.getAbsolutePath());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 開(kāi)始錄音(內(nèi)部調(diào)用)
* @param init
*/
private void startVoiceRecord(boolean init){
if (!isSDCardAvailable()) return;
if (init) {
mRecTimeSum = 0;
cleanFieArrayList(mRecList);
}
//錄音前停止播放回調(diào)
if(voicePlayCallBack!=null){
voicePlayCallBack.playFinish();
}
stopRecorder(mMediaRecorder, true);
mMediaRecorder = null;
stopMedia(mMediaPlayer, true);
mMediaPlayer = null;
mMediaRecorder = new MediaRecorder();
File file = prepareRecorder(mMediaRecorder, true);
if (file != null) {
//開(kāi)始錄音回調(diào)
if (voiceRecordCallBack != null) {
voiceRecordCallBack.recStart(init);
}
mDeviceState = MEDIA_STATE_RECORD_DOING;
mRecTimePrev = VoiceTimeUtils.getTimeStrFromMillis(System.currentTimeMillis());
mRecList.add(file);
mHandler.removeMessages(MSG_TIME_INTERVAL);
mHandler.sendEmptyMessage(MSG_TIME_INTERVAL);
}
}
/**
* 監(jiān)聽(tīng)錄音聲音頻率大小
*/
private class ObtainDecibelThread extends Thread{
private volatile boolean running = true;
public void exit() {
running = false;
}
@Override
public void run() {
while (running) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (mMediaRecorder == null || !running) {
break;
}
try {
final double ratio = mMediaRecorder.getMaxAmplitude()/150;
if (ratio != 0&&voiceRecordCallBack!=null) {
((Activity)context).runOnUiThread(new Runnable() {
@Override
public void run() {
double db=0;// 分貝
if (ratio > 1)
db = (int) (20 * Math.log10(ratio));
voiceRecordCallBack.recVoiceGrade((int)db);
}
});
}
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
}
/**
* 合并錄音
* @param list
* @return
*/
private File getOutputVoiceFile(ArrayList<File> list){
String mMinute1 = VoiceTimeUtils.getTime();
File recDirFile = recAudioDir(recordFilePath);
// 創(chuàng)建音頻文件,合并的文件放這里
File resFile = new File(recDirFile, mMinute1 + ".amr");
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(resFile);
} catch (IOException e) {
}
// list里面為暫停錄音 所產(chǎn)生的 幾段錄音文件的名字酿愧,中間幾段文件的減去前面的6個(gè)字節(jié)頭文件
for (int i = 0; i < list.size(); i++) {
File file = list.get(i);
try {
FileInputStream fileInputStream = new FileInputStream(file);
byte[] myByte = new byte[fileInputStream.available()];
// 文件長(zhǎng)度
int length = myByte.length;
// 頭文件
if (i == 0) {
while (fileInputStream.read(myByte) != -1) {
fileOutputStream.write(myByte, 0, length);
}
}
// 之后的文件,去掉頭文件就可以了
else {
while (fileInputStream.read(myByte) != -1) {
fileOutputStream.write(myByte, 6, length - 6);
}
}
fileOutputStream.flush();
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// 結(jié)束后關(guān)閉流
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return resFile;
}
/**
* 清空暫停錄音所產(chǎn)生的幾段錄音文件
* @param list
*/
private void cleanFieArrayList(ArrayList<File> list){
for (File file : list) {
file.delete();
}
list.clear();
}
/*********************************錄音操作end***************************/
/*********************************播放操作end***************************/
public void setVoicePlayListener(VoicePlayCallBack callback){
voicePlayCallBack = callback;
}
/**
* 播放SeekBar監(jiān)聽(tīng)
* @param seekBar
*/
public void setSeekBarListener(SeekBar seekBar){
mSBPlayProgress = seekBar;
if (mSBPlayProgress != null) {
mSBPlayProgress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
mHandler.removeMessages(MSG_TIME_INTERVAL);
mSavedState = mDeviceState;
if (mSavedState == MEDIA_STATE_PLAY_DOING) {
pauseMedia(mMediaPlayer);
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mHandler.removeMessages(MSG_TIME_INTERVAL);
VoiceTimeUtils ts = VoiceTimeUtils.timeSpanSecond(progress / 1000);
//播放進(jìn)度
if (voicePlayCallBack != null) {
voicePlayCallBack.playDoing(progress / 1000, String.format("%02d:%02d:%02d",
ts.mSpanHour, ts.mSpanMinute, ts.mSpanSecond));
}
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
seekMedia(mMediaPlayer, mSBPlayProgress.getProgress());
if (mSavedState == MEDIA_STATE_PLAY_DOING) {
playMedia(mMediaPlayer);
mHandler.sendEmptyMessage(MSG_TIME_INTERVAL);
}
}
});
}
}
/**
* 開(kāi)始播放(外部調(diào)用)
* @param filePath
*/
public void startPlay(String filePath){
if (TextUtils.isEmpty(filePath)|| !new File(filePath).exists())
{
if (voicePlayCallBack != null) {
voicePlayCallBack.playFinish();
}
Toast.makeText(context,"文件不存在",Toast.LENGTH_SHORT).show();
return;
}else {
playFilePath = filePath;
startPlay(true);
}
}
/**
* 開(kāi)始播放(內(nèi)部調(diào)用)
* @param init
*/
private void startPlay(boolean init){
try {
stopRecorder(mMediaRecorder, true);
mMediaRecorder = null;
stopMedia(mMediaPlayer, true);
mMediaPlayer = null;
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setOnCompletionListener(mPlayCompetedListener);
if (prepareMedia(mMediaPlayer, playFilePath)) {
mDeviceState = MEDIA_STATE_PLAY_DOING;
//總時(shí)間長(zhǎng)度
long totalTime = mMediaPlayer.getDuration() / 1000;
VoiceTimeUtils ts = VoiceTimeUtils.timeSpanSecond(totalTime);
String voiceLength = String.format("%02d:%02d:%02d",
ts.mSpanHour, ts.mSpanMinute, ts.mSpanSecond);
//播放進(jìn)度回調(diào)
if (voicePlayCallBack != null) {
voicePlayCallBack.voiceTotalLenth(totalTime, voiceLength);
voicePlayCallBack.playDoing(0, "00:00:00");
}
if (mSBPlayProgress != null) {
mSBPlayProgress.setMax(Math.max(1, mMediaPlayer.getDuration()));
}
if (init) {
if (mSBPlayProgress != null) {
mSBPlayProgress.setProgress(0);
}
seekMedia(mMediaPlayer, 0);
} else {
seekMedia(mMediaPlayer, mSBPlayProgress.getProgress());
}
if (playMedia(mMediaPlayer)) {
mHandler.removeMessages(MSG_TIME_INTERVAL);
mHandler.sendEmptyMessage(MSG_TIME_INTERVAL);
}
}
} catch (Exception e) {
Log.e("播放出錯(cuò)了", e.getMessage());
}
}
/**
* 繼續(xù)暫停
*/
public void continueOrPausePlay(){
if (mDeviceState == MEDIA_STATE_PLAY_DOING) {
mDeviceState = MEDIA_STATE_PLAY_PAUSE;
pauseMedia(mMediaPlayer);
//暫停
if (voicePlayCallBack != null) {
voicePlayCallBack.playPause();
}
} else if (mDeviceState == MEDIA_STATE_PLAY_PAUSE) {
mDeviceState = MEDIA_STATE_PLAY_DOING;
playMedia(mMediaPlayer);
//播放中
mHandler.removeMessages(MSG_TIME_INTERVAL);
mHandler.sendEmptyMessage(MSG_TIME_INTERVAL);
} else if (mDeviceState == MEDIA_STATE_PLAY_STOP) {
//播放
if (!TextUtils.isEmpty(playFilePath)) {
startPlay(false);
}
}
}
/**
* 停止播放
*/
public void stopPlay(){
mHandler.removeMessages(MSG_TIME_INTERVAL);
mDeviceState = MEDIA_STATE_PLAY_STOP;
stopMedia(mMediaPlayer, true);
mMediaPlayer = null;
}
/**
* 是否在播放中
* @return
*/
public boolean isPlaying(){
return mDeviceState == MEDIA_STATE_PLAY_DOING;
}
/*********************************播放操作end***************************/
/**
* 播放錄音準(zhǔn)備工作
*/
private boolean prepareMedia(MediaPlayer mp,String file){
boolean result = false;
try {
mp.setDataSource(file);
mp.prepare();
result = true;
} catch (Exception e) {
}
return result;
}
/**
* 播放錄音開(kāi)始
* @param mp
* @return
*/
private boolean playMedia(MediaPlayer mp){
boolean result = false;
try {
if (mp != null) {
mp.start();
result = true;
}
} catch (Exception e) {
}
return result;
}
/**
* 拖動(dòng)播放進(jìn)度條
* @param mp
* @param pos
* @return
*/
private boolean seekMedia(MediaPlayer mp,int pos){
boolean result = false;
try {
if (mp != null && pos >= 0) {
mp.seekTo(pos);
result = true;
}
} catch (Exception e) {
}
return result;
}
/**
* 停止播放
* @param mp
* @param release
* @return
*/
private boolean stopMedia(MediaPlayer mp,boolean release){
boolean result = false;
try {
if (mp != null) {
mp.stop();
if (release) {
mp.release();
}
result = true;
}
} catch (Exception e) {
}
return result;
}
/**
* 暫停播放
* @param mp
* @return
*/
private boolean pauseMedia(MediaPlayer mp){
boolean result = false;
try {
if (mp != null) {
mp.pause();
result = true;
}
} catch (Exception e) {
}
return result;
}
private boolean stopRecorder(MediaRecorder mr, boolean release) {
boolean result = false;
try {
if (mr != null) {
mr.stop();
if (release) {
mr.release();
}
result = true;
}
if(mThread!=null){
mThread.exit();
mThread=null;
}
} catch (Exception e) {
if(mThread!=null){
mThread=null;
mThread.exit();
}
}
return result;
}
/**
* 錄音準(zhǔn)備工作 邀泉,開(kāi)始錄音
*
* @param mr
* @param start
* @return
*/
@SuppressWarnings("deprecation")
private File prepareRecorder(MediaRecorder mr, boolean start) {
File recFile = null;
if (mr == null) return null;
try {
String path = recAudioDir(recordFilePath).getAbsolutePath();
recFile = new File(path, VoiceTimeUtils.getTime() + ".amr");
mr.setAudioSource(MediaRecorder.AudioSource.MIC);
mr.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
mr.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mr.setOutputFile(recFile.getAbsolutePath());
mr.prepare();
if (start) {
mr.start();
if (mThread == null) {
mThread = new ObtainDecibelThread();
mThread.start();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return recFile;
}
/**
* 停止錄音和播放
*/
public void stopRecordAndPlay(){
stopRecorder(mMediaRecorder, true);
mMediaRecorder = null;
stopMedia(mMediaPlayer, true);
mMediaPlayer = null;
}
/**
* 錄音回調(diào)監(jiān)聽(tīng)
*/
public interface VoiceRecordCallBack{
//錄音中
void recDoing(long time,String strTime);
//錄音中的聲音頻率等級(jí);
void recVoiceGrade(int grade);
//錄音開(kāi)始
void recStart(boolean init);
//錄音暫停
void recPause(String str);
//錄音結(jié)束
void recFinish(long lenth,String strLenth,String path);
}
/**
* 播放錄音回調(diào)監(jiān)聽(tīng)
*/
public interface VoicePlayCallBack{
/**
* 音頻長(zhǎng)度
* 指定的某個(gè)時(shí)間段嬉挡,以秒為單位
*/
void voiceTotalLenth(long time,String strTime);
/**
* 播放中
* 指定的某個(gè)時(shí)間段,以秒為單位
*/
void playDoing (long time,String strTime);
//播放暫停
void playPause();
//播放開(kāi)始
void playStart();
//播放結(jié)束
void playFinish();
}
/**
* SD卡是否可用
*/
public static boolean isSDCardAvailable() {
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
}
public static File recAudioDir(String path) {
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
return file;
}
}
本項(xiàng)目的url地址:
https://github.com/jaydenxiao2016/VoiceManager/blob/master/app/src/main/java/com/jaydenxiao/voicemanager/RecordVoiceButton.java