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>