单一职责SRP(Single Responsibility Principle)即就一个类而言只有一个引起他变化的原因;简单的来说一个类是由一组相关性很高的方法和属性的集合;
例如:下面录音和播放的代码
import android.Manifest;
import android.content.pm.PackageManager;
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.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.PermissionChecker;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by wangyoude on 18/5/29.
* 实现录音与播放
*/
public class AutoRecordActivity extends AppCompatActivity implements View.OnClickListener{
private static final String TAG = "AutoRecordActivity";
/**
* 实例化AudioRecord需要的参数
*/
private static final int AUDIORECORD_RESOURCE = MediaRecorder.AudioSource.MIC;
private static final int SAMPLE_RATE_INHZ = 8000;
private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;
private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_8BIT;
private static int BUFFERSIZEINBYTE ;
private AudioRecord audioRecord;
private AudioTrack audioTrack;
//授权回调code
private static final int REQUST_PERSSION_CODE = 0x110;
//录音存储的文件
private File file = new File("/sdcard/temp.raw");
private boolean isRecording = true;
private boolean isPlaying = true;
private boolean isRequestPermission = false;
private Button mStartRecordBn,mStopRecordBn,mStartPlayBn,mStopPlayBn;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_autorecord);
mStartRecordBn = findViewById(R.id.button1);
mStopRecordBn = findViewById(R.id.button2);
mStartPlayBn = findViewById(R.id.button3);
mStopPlayBn = findViewById(R.id.button4);
mStartRecordBn.setOnClickListener(this);
mStopRecordBn.setOnClickListener(this);
mStartPlayBn.setOnClickListener(this);
mStopPlayBn.setOnClickListener(this);
requestPermission();
}
@Override
public void onClick(View v) {
if (!isRequestPermission){
Toast.makeText(AutoRecordActivity.this,"未授权",Toast.LENGTH_SHORT).show();
return ;
}
switch (v.getId()){
case R.id.button1:
isRecording = true;
initAudioRecord();
startRecord();
break;
case R.id.button2:
isRecording = false;
stopRecord();
break;
case R.id.button3:
isPlaying = true;
initAudioTrack();
playAudioFile();
break;
case R.id.button4:
isPlaying = false;
stopAudioTrack();
break;
}
}
public void initAudioRecord(){
BUFFERSIZEINBYTE = AudioRecord.getMinBufferSize(SAMPLE_RATE_INHZ,CHANNEL_CONFIG,AUDIO_FORMAT);
audioRecord = new AudioRecord(AUDIORECORD_RESOURCE,SAMPLE_RATE_INHZ,CHANNEL_CONFIG,AUDIO_FORMAT,BUFFERSIZEINBYTE);
}
public void initAudioTrack(){
/**
* int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
int bufferSizeInBytes, int mode
*/
if (!file.exists()){
Toast.makeText(this,"请先录音",Toast.LENGTH_SHORT).show();
return;
}
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,SAMPLE_RATE_INHZ,CHANNEL_CONFIG,AUDIO_FORMAT,
BUFFERSIZEINBYTE,AudioTrack.MODE_STREAM);
new Thread().start();;
}
private void startRecord(){
audioRecord.startRecording();
new Thread(new AudioRecordThread()).start();
}
private void stopRecord(){
isRecording = false;
if (audioRecord != null) {
audioRecord.stop();
audioRecord.release();
audioRecord = null;
}
}
private void stopAudioTrack(){
isPlaying = false;
if (audioTrack != null){
audioTrack.stop();
audioTrack.release();
audioTrack = null;
}
}
class AudioTrackPlayThread implements Runnable{
@Override
public void run() {
try {
FileInputStream fis = new FileInputStream(file);
byte[] playData = new byte[BUFFERSIZEINBYTE];
while(isPlaying && fis.available() > 0){
fis.read(playData);
audioTrack.write(playData,0,BUFFERSIZEINBYTE);
}
CloseBleUtil.close(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class AudioRecordThread implements Runnable{
@Override
public void run() {
try {
if (!file.exists()){
}else {
file.delete();
}
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
byte[] audioData = new byte[BUFFERSIZEINBYTE];
while(isRecording){
audioRecord.read(audioData,0,audioData.length);
fos.write(audioData);
}
fos.flush();
CloseBleUtil.close(fos);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void playAudioFile(){
audioTrack.play();
new Thread(new AudioTrackPlayThread()).start();
}
private void requestPermission() {
List<String> requestPermissionList = new ArrayList<>();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PermissionChecker.PERMISSION_GRANTED){
requestPermissionList.add(Manifest.permission.RECORD_AUDIO);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PermissionChecker.PERMISSION_GRANTED){
requestPermissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) != PermissionChecker.PERMISSION_GRANTED){
requestPermissionList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (requestPermissionList.size() > 0){
ActivityCompat.requestPermissions(this,requestPermissionList.toArray(new String[requestPermissionList.size()]),REQUST_PERSSION_CODE);
}else {
isRequestPermission = true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
int resultIntCode = -1;
switch (requestCode){
case REQUST_PERSSION_CODE:
if (grantResults.length > 0){
for (int i : grantResults){
if (i == PackageManager.PERMISSION_DENIED){
Toast.makeText(this,"授权被拒绝了!!",Toast.LENGTH_SHORT).show();
resultIntCode = -1;
}else {
Log.e(TAG,"授权成功!!");
}
}
}
if (resultIntCode == -1){
Log.e(TAG,"resultIntCode == -1");
}else {
//授权成功
isRequestPermission = true;
}
break;
}
}
}
今天就先写到这里明天继续
昨天写的程序运行可能会有问题,在没有点击录音的,直接点击开始播放程序会崩溃,在开始播放的时候需要判断一下文件是否存在
if (!file.exists()){
Toast.makeText(this,"请先录音",Toast.LENGTH_SHORT).show();
return;
}
这样应该就可以运行了;
现在我们按照单一原则来重新规划一下我们的程序;
具体的代码实现如下:
Activity:
import android.Manifest;
import android.content.pm.PackageManager;
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.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.PermissionChecker;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by wangyoude on 18/5/29.
* 实现录音与播放
*/
public class AutoRecordActivity extends AppCompatActivity implements View.OnClickListener{
private static final String TAG = "AutoRecordActivity";
//授权回调code
private static final int REQUST_PERSSION_CODE = 0x110;
private boolean isRequestPermission = false;
private Button mStartRecordBn,mStopRecordBn,mStartPlayBn,mStopPlayBn;
private PlayAutoInterface playAutoInterface;
private AudioRecordInterface audioRecordInterface;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_autorecord);
mStartRecordBn = findViewById(R.id.button1);
mStopRecordBn = findViewById(R.id.button2);
mStartPlayBn = findViewById(R.id.button3);
mStopPlayBn = findViewById(R.id.button4);
mStartRecordBn.setOnClickListener(this);
mStopRecordBn.setOnClickListener(this);
mStartPlayBn.setOnClickListener(this);
mStopPlayBn.setOnClickListener(this);
requestPermission();
}
@Override
public void onClick(View v) {
if (!isRequestPermission){
Toast.makeText(AutoRecordActivity.this,"未授权",Toast.LENGTH_SHORT).show();
return ;
}
switch (v.getId()){
case R.id.button1:
audioRecordInterface = new AudioRecord2File();
audioRecordInterface.setIsRecording(true);
audioRecordInterface.initParam();
audioRecordInterface.startRecord();
break;
case R.id.button2:
audioRecordInterface.setIsRecording(false);
audioRecordInterface.stopRecord();
break;
case R.id.button3:
playAutoInterface = new PlayAudio2File();
playAutoInterface.setIsPlaying(true);
playAutoInterface.initPlayParam();
playAutoInterface.playMusic(AutoRecordActivity.this);
break;
case R.id.button4:
playAutoInterface.setIsPlaying(false);
playAutoInterface.stopMusic();
break;
}
}
private void requestPermission() {
List<String> requestPermissionList = new ArrayList<>();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PermissionChecker.PERMISSION_GRANTED){
requestPermissionList.add(Manifest.permission.RECORD_AUDIO);
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PermissionChecker.PERMISSION_GRANTED){
requestPermissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) != PermissionChecker.PERMISSION_GRANTED){
requestPermissionList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
}
if (requestPermissionList.size() > 0){
ActivityCompat.requestPermissions(this,requestPermissionList.toArray(new String[requestPermissionList.size()]),REQUST_PERSSION_CODE);
}else {
isRequestPermission = true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
int resultIntCode = -1;
switch (requestCode){
case REQUST_PERSSION_CODE:
if (grantResults.length > 0){
for (int i : grantResults){
if (i == PackageManager.PERMISSION_DENIED){
Toast.makeText(this,"授权被拒绝了!!",Toast.LENGTH_SHORT).show();
resultIntCode = -1;
}else {
Log.e(TAG,"授权成功!!");
}
}
}
if (resultIntCode == -1){
Log.e(TAG,"resultIntCode == -1");
}else {
//授权成功
isRequestPermission = true;
}
break;
}
}
}
AudioRecordInterface:
package com.haier.duizhao;
/**
* Created by wangyoude on 18/5/30.
*/
public interface AudioRecordInterface {
public void startRecord();
public void stopRecord();
public void initParam();
public void setIsRecording(boolean isRecording);
}
AudioRecord2File
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by wangyoude on 18/5/30.
*/
public class AudioRecord2File implements AudioRecordInterface {
private AudioRecord audioRecord;
//录音存储的文件
private File file = new File("/sdcard/temp.raw");
private boolean isRecording = true;
@Override
public void setIsRecording(boolean isRecording){
this.isRecording = isRecording;
}
@Override
public void startRecord() {
audioRecord.startRecording();
new Thread(new AudioRecordThread()).start();
}
class AudioRecordThread implements Runnable{
@Override
public void run() {
try {
if (!file.exists()){
}else {
file.delete();
}
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
byte[] audioData = new byte[ConstantUtil.BUFFERSIZEINBYTE];
while(isRecording){
audioRecord.read(audioData,0,audioData.length);
fos.write(audioData);
}
fos.flush();
CloseBleUtil.close(fos);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void stopRecord() {
isRecording = false;
if (audioRecord != null) {
audioRecord.stop();
audioRecord.release();
audioRecord = null;
}
}
@Override
public void initParam() {
ConstantUtil.BUFFERSIZEINBYTE = AudioRecord.getMinBufferSize(ConstantUtil.SAMPLE_RATE_INHZ,ConstantUtil.CHANNEL_CONFIG
,ConstantUtil.AUDIO_FORMAT);
audioRecord = new AudioRecord(ConstantUtil.AUDIORECORD_RESOURCE,ConstantUtil.SAMPLE_RATE_INHZ,ConstantUtil.CHANNEL_CONFIG
,ConstantUtil.AUDIO_FORMAT,ConstantUtil.BUFFERSIZEINBYTE);
}
}
PlayAutoInterface
import android.content.Context;
/**
* Created by wangyoude on 18/5/30.
*/
public interface PlayAutoInterface {
void initPlayParam();
void playMusic(Context context);
void stopMusic();
public void setIsPlaying(boolean isPlaying);
}
PlayAudio2File
import android.content.Context;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* Created by wangyoude on 18/5/30.
*/
public class PlayAudio2File implements PlayAutoInterface {
private AudioTrack audioTrack;
private boolean isPlaying;
private File file;
@Override
public void setIsPlaying(boolean isPlaying){
this.isPlaying = isPlaying;
}
@Override
public void initPlayParam() {
file = new File(ConstantUtil.FILE_PATH);
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,ConstantUtil.SAMPLE_RATE_INHZ,ConstantUtil.CHANNEL_CONFIG
,ConstantUtil.AUDIO_FORMAT, ConstantUtil.BUFFERSIZEINBYTE,AudioTrack.MODE_STREAM);
}
@Override
public void playMusic(Context context) {
if (!file.exists()){
Toast.makeText(context,"请先录音",Toast.LENGTH_SHORT).show();
return;
}
audioTrack.play();
new Thread(new AudioTrackPlayThread()).start();
}
@Override
public void stopMusic() {
isPlaying = false;
if (audioTrack != null){
audioTrack.stop();
audioTrack.release();
audioTrack = null;
}
}
class AudioTrackPlayThread implements Runnable{
@Override
public void run() {
try {
FileInputStream fis = new FileInputStream(file);
byte[] playData = new byte[ConstantUtil.BUFFERSIZEINBYTE];
while(isPlaying && fis.available() > 0){
fis.read(playData);
audioTrack.write(playData,0,ConstantUtil.BUFFERSIZEINBYTE);
}
CloseBleUtil.close(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
总结:这样Activity就只干界面的处理,录音只干录音的活,播放只干播放的事情.
加如接口是方便以后扩展