Android录音并保存为MP3
这几天要实现一个在Android6.0+的环境中的录音功能,总结出来大概有这么几个问题:权限的动态开启(就因为这个愁死我了),声音的录制,流的MP3转存。
首先说一下权限动态开启:
需要先定义一个String数组来存储需要开启的权限
private static String[] PERMISSIONS_STORAGE = {android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.RECORD_AUDIO};
然后,定义一个请求权限代码
private static int REQUEST_PERMISSION_CODE = 3;
然后写一个方法,因为我是封装了一个类,所以还需要传入一个Activity来调用
public void open(Activity obj){
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
for (int i = 0 ; i < PERMISSIONS_STORAGE.length ; i++){
if (ActivityCompat.checkSelfPermission(obj,
PERMISSIONS_STORAGE[i])!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(obj, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
}
}
}
}
在主函数中直接调用这个方法,就可以实现动态获取权限了,这里开启的是读写权限和话筒权限,如果需要其他的可以自行添加。
CALENDAR 日历
CAMERA 相机
CONTACTS 联系人
LOCATION 定位
MICROPHONE 麦克相关,比如录音
PHONE 手机状态
SENSORS 传感器
SMS 短信
STORAGE 存储权限
这些是其中一些可调用权限。
接下来说一下最复杂的一部分,就是录音以及存储:
当然,这里我还是封装成了一个类,为了后期其他项目方便调用。
首先创建所要用到的变量
MediaRecorder recorder;
File audioFile; //录音保存的文件
boolean isRecoding=false;// true 表示正在录音
//这里接收传递的Activity,如果直接写在Activity中则不需要写这一个
Activity activity;
传递Activity
public void setActivity(Activity activity){
this.activity = activity;
}
初始化MediaRecorder
public void init(){
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//设置播放源 麦克风
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); //设置输入格式 3gp
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //设置编码 AMR
}
接下来就是录音功能的实现:
public void recod(){
//这里为文件保存路径
File path = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/MediaRecorderTest");
init();
if(!path.exists())
{
path.mkdirs();
}
try {
//这个地方写文件名,可以利用时间来保存为不同的文件名
audioFile=new File(path,"test.MP3");
if(audioFile.exists())
{
audioFile.delete();
}
audioFile.createNewFile();//创建文件
} catch (Exception e) {
throw new RuntimeException("Couldn't create recording audio file", e);
}
recorder.setOutputFile(audioFile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
throw new RuntimeException("IllegalStateException on MediaRecorder.prepare", e);
} catch (IOException e) {
throw new RuntimeException("IOException on MediaRecorder.prepare", e);
}
isRecoding=true;
recorder.start();
}
然后封装方法,首先是开始录音,这个比较简单,调用之前的方法就可以
public void startin(){
Toast.makeText(activity,"开始录音",Toast.LENGTH_SHORT).show();
this.recod();
}
最后是停止录音,这个比较费劲,之前因为某些原因,需要点击两次,将程序点崩溃才能保存,然后利用trycatch和初始化,保证一次成功
public void stopin(){
if(isRecoding)
{
Toast.makeText(activity,"停止录音",Toast.LENGTH_SHORT).show();
if (recorder != null){
try {
recorder.stop();
} catch (IllegalStateException e) {
// TODO 如果当前java状态和jni里面的状态不一致,
//e.printStackTrace();
recorder = null;
recorder = new MediaRecorder();
}
recorder.release();
recorder = null;
}
}
}
千万不要忘记在AndroidMainfest.xml中加入权限
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
最后是布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#fff"
android:gravity="center">
<Button
android:text="开始录音"
android:id="@+id/StartRecording"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:text="停止录音"
android:id="@+id/StopRecording"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/playAui"
android:text="测试按钮"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>