相关权限:
<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"> <Button android:text="播放录音" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20dp" android:id="@+id/btn_three_play" /> <Button android: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" 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{ @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 { @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;
}});