添加权限
<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);
}
}
}
运行效果