您的位置:首页 > 移动开发 > Android开发

Android调用手机系统自带录音功能实现语音录制与播放

2016-12-20 17:20 786 查看
首先调用手机系统自带的录音功能需要相关权限以及读写SD卡的权限
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
添加布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:orientation="vertical"
android:layout_width="match_parent" 
    android:layout_height="match_parent"tools:context="example.com.recorder.MainActivity">
<Buttonandroid:text="播放录音"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
android:id="@+id/btn_three_play" />

<Buttonandroid:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn_three_recorder"
android:textSize="20dp"
android:text="开始录音并保存" />
<TextView
android:id="@+id/tv_progress3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="40sp"
android:textStyle="bold"
<
4000
/span>android:text="0"/>
</LinearLayout>
MainActivity.class 代码如下
public class MainActivity extends Activity implements MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener {
private MediaPlayer mediaPlayer;
private boolean isRecording = false;
private TextView mTv_progress3;
Button btn_three_play, btn_three_recorder;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_three_play = (Button) findViewById(R.id.btn_three_play);
btn_three_recorder = (Button) findViewById(R.id.btn_three_recorder);
mTv_progress3 = (TextView) findViewById(R.id.tv_progress3);

mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnPreparedListener(this);
btn_three_play.setEnabled(false);
btn_three_play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playRecorder();
}
});

btn_three_recorder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
recorder_Audio();
btn_three_play.setEnabled(true);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}

private boolean isPlaying = false;
private int frequency = 11025;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int audiosource = MediaRecorder.AudioSource.MIC;
int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
File recordingFile = null;
MainActivity.RecordAudio recordAudio = null;
MainActivity.PlayAudio playAudio = null;

public void recorder_Audio() throws IOException {
//AudioRecord不会直接保存音频,需要自己保存
File path = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
path.mkdirs();

try {
recordingFile = File.createTempFile("recording", ".pcm", path);
} catch (IOException e) {
e.printStackTrace();
}
recordAudio = new MainActivity.RecordAudio();
recordAudio.execute();
}

public void playRecorder() {
isRecording = false;
playAudio = new MainActivity.PlayAudio();
playAudio.execute();
}

public void onCompletion(MediaPlayer mp) {

}

public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}

private class PlayAudio extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... params) {
isPlaying = true;
int bufferSize = AudioTrack.getMinBufferSize(frequency, channelConfig, audioFormat);
short[] buffer = new short[bufferSize / 4];
DataInputStream dis = null;
try {
dis = new DataInputStream(new BufferedInputStream(new FileInputStream(recordingFile)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency, channelConfig, audioFormat, bufferSize, AudioTrack.MODE_STREAM);
audioTrack.play();
try {
while (isPlaying && dis.available() > 0) {
int i = 0;
while (dis.available() > 0 && i < buffer.length) {
buffer[i] = dis.readShort();
i++;
}
audioTrack.write(buffer, 0, buffer.length);
}
dis.close();

} catch (IOException e) {
e.printStackTrace();
}
return null;
}

@Override
protected void onPreExecute() {
super.onPreExecute();

Toast.makeText(MainActivity.this, "语音开始播放", Toast.LENGTH_SHORT).show();
}

@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText(MainActivity.this, "语音播放完了", Toast.LENGTH_SHORT).show();

}
}

private class RecordAudio extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... params) {
isRecording = true;
DataOutputStream dos = null;
try {
dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(recordingFile)));
int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfig, audioFormat);
AudioRecord audioRecord = new AudioRecord(audiosource, frequency, channelConfig, audioFormat, bufferSize);
short[] buffer = new short[bufferSize];
audioRecord.startRecording();
int r = 0;
while (isRecording) {
int bufferReadResult = audioRecord.read(buffer, 0, bufferSize);
for (int i = 0; i < bufferReadResult; i++) {
try {
dos.writeShort(buffer[i]);

} catch (IOException e) {
e.printStackTrace();
}
}
publishProgress(new Integer(r));
r++;
}
audioRecord.stop();
dos.close();
} catch (Exception e) {
e.printStackTrace();
}

return null;
}

@Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(MainActivity.this, "正在录音", Toast.LENGTH_SHORT).show();
}

@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
mTv_progress3.setText(values[0] + "");
}
}
}
其中先设置播放按钮为不可点击,录音后才可点击,不然会报空指针异常  或者可以用按住录音 松开播放来实现 代码如下
btn_three_recorder .setOnTouchListener(new View.OnTouchListener() {
    @Override    public boolean onTouch(View view, MotionEvent motionEvent) { 
switch (motionEvent.getAction()) {         
case MotionEvent.ACTION_DOWN: //按下             
try {                 
recorder_Audio();                          
} catch (IOException e) {   
e.printStackTrace();               
}            
break;          
case MotionEvent.ACTION_MOVE: //移动         
   break;          
case MotionEvent.ACTION_UP: //抬起          
playRecorder();              
break;       
}        
return true;   
}});
下载链接 http://download.csdn.net/download/csj731742019/9716796
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: