添加权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.RECORD_AUDIO" />
1、新建活动
fragment_audio_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.test.androidtest.AudioMainActivity$PlaceholderFragment" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始录音" android:onClick="startRecording" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="停止录音" android:onClick="stopRecording" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="播放录音" android:onClick="playRecording" /> </LinearLayout>
代码
package com.test.androidtest; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import android.app.Activity; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioRecord; import android.media.AudioTrack; import android.media.MediaRecorder; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.View; public class AudioMainActivity extends Activity { //以下值会影响所录制音频的大小和质量 //采样频率 private int frequency = 11025; //声道配置 private int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO; //音频编码 private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; private boolean isRecording = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_audio_main); } public void startRecording(View view) { Log.d("test", "开始录音"); Thread thread=new Thread(new Runnable() { @Override public void run() { File file = new File(Environment.getExternalStorageDirectory(), "raw.pcm");//保存在SD卡上 try{ file.createNewFile(); }catch(IOException e){ Log.e("test", "IO Exception", e); } try{ OutputStream os = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(os); DataOutputStream dos = new DataOutputStream(bos); int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding); short[] buffer = new short[bufferSize]; //创建一个新的AudioRecord对象来录制音频 AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,//从麦克风录制原始音频 frequency, channelConfiguration, audioEncoding, bufferSize); audioRecord.startRecording();//开始异步录制 isRecording = true; while(isRecording){ int bufferReadResult = audioRecord.read(buffer, 0, bufferSize); Log.d("test", "bufferReadResult="+bufferReadResult); for(int i=0; i<bufferReadResult; i++) dos.writeShort(buffer[i]); } audioRecord.stop(); dos.flush(); dos.close(); }catch(Throwable t){ Log.e("test", "An error occurred during recording", t); } } }); thread.start(); } public void stopRecording(View view) { Log.d("test", "停止录音"); isRecording = false; } public void playRecording(View view) { Log.d("test", "播放录音"); File file = new File(Environment.getExternalStorageDirectory(), "raw.pcm"); //用于存储音轨的short数组(每个short占用16位,即2个字节) int audioLength = (int)(file.length()/2); short[] audio = new short[audioLength]; try{ InputStream is = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(is); DataInputStream dis = new DataInputStream(bis); int i = 0; while(dis.available() > 0){ audio[i] = dis.readShort(); i++; } //关闭输入流 dis.close(); //创建和播放新的AudioTrack对象 //由于录制的原始音频没有关联元数据,因此必须将音频的数据属性设为与录制时相同 AudioTrack audioTrack = new AudioTrack( AudioManager.STREAM_MUSIC,//流模式 frequency,//频率 channelConfiguration,//声道配置 audioEncoding,//音频编码类型 audioLength,//要播放的音频的长度 AudioTrack.MODE_STREAM); audioTrack.play();//异步播放 audioTrack.write(audio, 0, audioLength);//将原始音频数据添加到播放缓冲区 }catch(Throwable t){ Log.d("test", "An error occurred during playback", t); } } }
运行效果