需求:长按开始录音,松开后保存文件到本地(文件上传暂不讲解)。
上代码,封装好的工具类,张口即食,香香。。。
/**
* 音频录制工具类
* 使用方式:
* 1.获取实例 new VoiceRecordingUtil()
* 2.设置文件需要保存的路径 setSavePath()
* 3.设置文件名 setFileName()
* 4.设置最大录制时长 setRecordMaxTime()默认60秒
* 5.设置监听 setOnRecorderListenerListener()
* 1.> onStartRecorder(int seconds) 开始监听 同时会返回剩余最大时长秒数
* 2.> onStopRecorder() 结束监听
* */
public class VoiceRecordingUtil {
private Activity mActivity;
private onRecorderListener listener;
private String mSavePath;//文件需要保存的路径
private String mFileName;//文件名
private MediaRecorder recorder;//录音类
private boolean isRecording;//是否正在录制
private Timer mTimer;// 计时器
private int mRecordMaxTime = 60;// 一次拍摄最长时间(默认60秒)
private int mTimeCount;// 时间计数
private long currentTime;//开始录制时的时间戳
public VoiceRecordingUtil(Activity activity){
this.mActivity = activity;
}
/**
* 设置输出路径
* */
public void setSavePath(String mSavePath) {
this.mSavePath = mSavePath;
}
/**
* 设置文件名
* */
public void setFileName(String mFileName) {
this.mFileName = mFileName;
}
/**
* 设置最大录制时间 默认60秒
* */
public void setRecordMaxTime(int mRecordMaxTime) {
this.mRecordMaxTime = mRecordMaxTime;
}
/**
* 设置录音监听
* */
public void setOnRecorderListenerListener(onRecorderListener listener) {
this.listener = listener;
}
/**
* 获取录制时长
* */
public int getTimeCount(){
return this.mTimeCount;
}
/**
* 是否正在录制
* */
public boolean isRecording(){
return this.isRecording;
}
/**
* 开始录制
* */
public void startRecorder() {
if (TextUtils.isEmpty(mSavePath) || TextUtils.isEmpty(mFileName)){
Log.e("VoiceRecordingUtil", "startRecorder: filePath or fileName is Null");
return;
}
if (!checkPermissions()){
Log.e("VoiceRecordingUtil", "read and write permission not obtained");
return;
}
if(null == recorder){
recorder = new MediaRecorder();
}
recorder.reset();
// recorder.setOnErrorListener(this);//监听暂不实现
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//设置录音来源
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//设置输出格式
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置编码格式
recorder.setOutputFile(mSavePath + "/" + mFileName);//设置输出路径
try {
recorder.prepare();//准备
recorder.start();//开始录音
isRecording = true;
} catch (IOException e) {
e.printStackTrace();
}
//记录开始录制的时间戳,在结束时进行判断最少不得超过1秒,否则会抛异常
currentTime = System.currentTimeMillis();
mTimeCount = 0;// 时间计数器重新赋值
if (null != listener){
listener.onStartRecorder(mRecordMaxTime - mTimeCount);
}
mTimer = new Timer();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
mTimeCount++;
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (null != listener && isRecording){
listener.onStartRecorder(mRecordMaxTime - mTimeCount);
}
if (mTimeCount == mRecordMaxTime) {// 达到指定时间,停止录制
stopRecorder();
}
}
});
}
},0,1000);
}
/**
* 结束录制
* */
public void stopRecorder() {
isRecording = false;
if (mTimer != null){
mTimer.cancel();
}
if(null != recorder){
long millis = System.currentTimeMillis();
//停止时判断录制时间是否大于1秒,true则停止,否则会抛异常
if ((millis - currentTime) > 1000){
recorder.stop();//停止录音
}
recorder.reset();//重置
recorder.release();//释放资源
recorder = null;
if (null != listener){
listener.onStopRecorder();
}
}
}
/**
* 删除文件
* */
public boolean deleteFile() {
File file = new File(mSavePath + "/" + mFileName);
if (file.isFile() && file.exists()) {
return file.delete();
}
return false;
}
/**
* 检查读写权限
* */
private boolean checkPermissions() {
boolean isAllow = true;
//判断安卓版本
if(Build.VERSION.SDK_INT >=23){
//需要申请的权限
String [] permission={
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO
};
for (String perString : permission){
//判断是否有权限
if(mActivity.checkSelfPermission(perString) != PackageManager.PERMISSION_GRANTED){
mActivity.requestPermissions(permission,10);
isAllow = false;
}
}
}
return isAllow;
}
public interface onRecorderListener {
void onStartRecorder(int seconds);
void onStopRecorder();
}
}
上面的音频录制工具类拿来即食,接下来看下如何使用的。
public class MainActivity extends AppCompatActivity {
private TextView tv_Time;
private VoiceRecordingUtil voiceRecordingUtil;//音频录制工具类
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_Time = findViewById(R.id.tv_Time);
tv_Time.setText("10");
//保存到手机的文件名
String savePath = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "voiceRecordingDemo.mp3";
voiceRecordingUtil = new VoiceRecordingUtil(this);
voiceRecordingUtil.setSavePath(savePath);
voiceRecordingUtil.setFileName(fileName);
voiceRecordingUtil.setRecordMaxTime(10);
voiceRecordingUtil.setOnRecorderListenerListener(new VoiceRecordingUtil.onRecorderListener() {
@Override
public void onStartRecorder(int seconds) {
((Button) findViewById(R.id.startRecording)).setText("松开结束录制语音");
tv_Time.setVisibility(View.VISIBLE);
tv_Time.setText(seconds + "");
Toast.makeText(MainActivity.this,"开始录音",Toast.LENGTH_SHORT).show();
}
@Override
public void onStopRecorder() {
((Button) findViewById(R.id.startRecording)).setText("长按开始录制语音");
tv_Time.setVisibility(View.GONE);
if (voiceRecordingUtil.getTimeCount() < 2 && voiceRecordingUtil.deleteFile()){
//录制时长小于2秒 删除
Toast.makeText(MainActivity.this,"录制时间太短了,请重新录制",Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(MainActivity.this,"录音结束",Toast.LENGTH_SHORT).show();
}
});
// 手势操作处理
findViewById(R.id.startRecording).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
//按下处理
voiceRecordingUtil.startRecorder();
if (event.getAction() == MotionEvent.ACTION_UP) {
// 放开处理
voiceRecordingUtil.stopRecorder();
}
return true;
}
});
}
}
tv_Time是一个TextView,用来展示剩余倒计时,按下时显示,松开后隐藏,xml很简单,就一个TextView展示倒计时,Button实现按下和抬起时音频的开始和结束录制。