package com.example.superb.yy4;
import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
/**
public class CheckAudioPermission {
/**
* 音频获取源
/
public static int audioSource = MediaRecorder.AudioSource.MIC;
/*
* 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025
*/
public static int sampleRateInHz = 44100;
/**
* 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道
*/
public static int channelConfig = AudioFormat.CHANNEL_IN_STEREO;
/**
* 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。
*/
public static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
/**
* 缓冲区字节大小
*/
public static int bufferSizeInBytes = 0;
public static AudioRecord audioRecord;
/**
* 判断是是否有录音权限.
*/
public static boolean isHasPermission(final Context context) {
bufferSizeInBytes = 0;
bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,
channelConfig, audioFormat);
if (audioRecord == null) {
audioRecord = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes);
}
//开始录制音频
try {
// 防止某些手机崩溃,例如联想
audioRecord.startRecording();
} catch (IllegalStateException e) {
e.printStackTrace();
}
/**
* 根据开始录音判断是否有录音权限s
*/
if (audioRecord.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) {
return false;
}
audioRecord.stop();
//释放资源
audioRecord.release();
audioRecord = null;
return true;
}
}
package com.example.superb.yy5;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
/**
desc:测试录音权限.
steps:
检测是否有权限–有--执行相关操作
–无权限–
–判断系统版本
–小于6.0 直接获取
–大于6.0 动态申请权限
–对申请结果的处理回调
–允许
–拒绝
test:
test1 build.gradle minsdk <23 真机android7.1 清单文件中配置了录音权限
test2 build.gradle minsdk >=23 真机android7.1 清单文件中配置了录音权限
@author xuzhuyun
@date 2018/5/10
*/
public class Main2Activity extends AppCompatActivity {
private static final String TAG = “MainActivity”;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
//检测是否有录音权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, “默认无录音权限”);
if (Build.VERSION.SDK_INT >= 23) {
Log.i(TAG, “系统版本不低于android6.0 ,需要动态申请权限”);
requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO}, 1001);
}
} else {
Log.i(TAG, “默认有录音权限”);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1001) {
//方式一校验
boolean isHasAudioPermission = CheckAudioPermission.isHasPermission(this);
Log.i(TAG, “申请权限完毕,当前录音权限:” + isHasAudioPermission);
//方式二校验
int result = 0;
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
result++;
}
}
if (result != permissions.length) {
//没有权限
Log.i(TAG, “onRequestPermissionsResult: 申请权限完毕,当前录音权限:false”);
return;
}
//有权限
Log.i(TAG, “onRequestPermissionsResult: 申请后,是否有权限:true”);
}
}
public void ccc(View view) {
startActivity(new Intent(this,MainActivity.class));
}
}
package com.example.superb.yy5;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class MainActivity extends Activity {
//耳机
//耳机
PipedInputStream in;
boolean isRrcord;
mAudio mm ;
mAudioPlayer m;
TextView T1,T2;
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn=findViewById(R.id.search_close_btn);
T1=findViewById(R.id.dddd);
isRrcord = false;
}
public void btnclick(View v){
if (isRrcord){
isRrcord = false;
mm.stopRecord();m.stopPlay();
btn.setText("开始");
T1.setText("点击开始");
}else{
isRrcord = true;
startRecord();
btn.setText("停止");
T1.setText("点击停止");
}
}
private void startRecord(){
in = new PipedInputStream();
new Thread(new Runnable() {
@Override
public void run() {
try {
mm = new mAudio(MainActivity.this, in);
mm.StartAudioData();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
byte[] buffer = new byte[1024];
PipedOutputStream pout = new PipedOutputStream();
m = new mAudioPlayer(MainActivity.this);
try {
m.setOutputStream(pout);
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
m.startPlayAudio();
}
}).start();
} catch (IOException e1) {
e1.printStackTrace();
}
int size = 0 ;
try {
while (true){
while (in.available()>0){
size = in.read(buffer);
pout.write(buffer, 0, size);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
package com.example.superb.yy5;
import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.util.Log;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
/*
To getaudio or play audio
*/
public class mAudio {
//
private int SAMPLE_RATE_HZ = 16000;
private AudioManager mAudioManager;
//
private AudioRecord audioRecord;
private Context context;
private boolean isRecording = false ;
private PipedOutputStream outstream ;//利用管道传输数据
public mAudio(Context context , PipedInputStream instream) throws IOException {
this.context = context;
//初始化管道流 用于向外传输数据
outstream = new PipedOutputStream();
outstream.connect(instream);
}
public void StartAudioData(){//得到录音数据
int frequency = 11025;
mAudioManager = (AudioManager)context.getSystemService(context.AUDIO_SERVICE);
// mAudioManager.setMode(AudioManager.MODE_NORMAL);
// mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
//MODE_IN_COMMUNICATION
mAudioManager.setBluetoothScoOn(true);
//frequency采样率:音频的采样频率,每秒钟能够采样的次数,采样率越高,音质越高。
// 给出的实例是44100、22050、11025但不限于这几个参数。
// 例如要采集低质量的音频就可以使用4000、8000等低采样率。
@SuppressWarnings("deprecation")
int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO;//立体声录制通道
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
//编码制式和采样大小:采集来的数据当然使用PCM编码(脉冲代码调制编码,
// 即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。) android支持的采样大小16bit 或者8bit。
// 当然采样大小越大,那么信息量越多,音质也越高,
// 现在主流的采样大小都是16bit,在低质量的语音传输的时候8bit足够了。
//
int buffersize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
//采集数据需要的缓冲区的大小,如果不知道最小需要的大小可以在getMinBufferSize()查看。
//手机VOICE_RECOGNITION
if(!mAudioManager.isBluetoothScoAvailableOffCall()){
Log.d(“dddddddddd”, “系统不支持蓝牙录音”);
return;
}
// mAudioManager.setBluetoothScoOn(true); //打开SCO}
//蓝牙录音的关键,启动SCO连接,耳机话筒才起作用
//mAudioManager.startBluetoothSco();
//蓝牙SCO连接建立需要时间,连接建立后会发出ACTION_SCO_AUDIO_STATE_CHANGED消息,通过接收该消息而进入后续逻辑。
//也有可能此时SCO已经建立,则不会收到上述消息,可以startBluetoothSco()前先stopBluetoothSco()
// if (AudioManager.SCO_AUDIO_STATE_CONNECTED == state) {
// mAudioManager.setBluetoothScoOn(true); //打开SCO}
// }
// mAudioManager.setBluetoothScoOn(true); //打开SCO}
//VOICE_COMMUNICATION
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,frequency, channelConfiguration, audioEncoding, buffersize);
//audioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION,frequency, channelConfiguration, audioEncoding, buffersize);
// 耳机
// buffersize = AudioRecord.getMinBufferSize(SAMPLE_RATE_HZ,
// AudioFormat.CHANNEL_IN_MONO,
// AudioFormat.ENCODING_PCM_16BIT) * 2;
//
// int audiosource = MediaRecorder.AudioSource.VOICE_RECOGNITION;
// audioRecord = new AudioRecord(audiosource,
// SAMPLE_RATE_HZ,
// AudioFormat.CHANNEL_IN_MONO,
// AudioFormat.ENCODING_PCM_16BIT,
// buffersize);
// audioRecord = new AudioRecord(audiosource,
// SAMPLE_RATE_HZ,
// AudioFormat.CHANNEL_IN_MONO,
// AudioFormat.ENCODING_PCM_16BIT,
// buffersize);
//音频源:指的是从哪里采集音频。这里我们当然是从麦克风采集音频,所以此参数的值为MIC
//frequency采样率:音频的采样频率,每秒钟能够采样的次数,采样率越高,音质越高。
// 给出的实例是44100、22050、11025但不限于这几个参数。
// 例如要采集低质量的音频就可以使用4000、8000等低采样率。
byte[]buffer = new byte[buffersize];
audioRecord.startRecording();//开始录音
isRecording = true;
int bufferReadSize = 1024;
mAudioManager.startBluetoothSco();
while (isRecording){
audioRecord.read(buffer, 0, bufferReadSize);
try {
outstream.write(buffer, 0, bufferReadSize);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void stopRecord(){//停止录音
// mAudioManager.setMode(AudioManager.MODE_NORMAL);
isRecording = false;
audioRecord.stop();
mAudioManager.startBluetoothSco();
try {
outstream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.example.superb.yy5;
import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class mAudioPlayer {
private Context context;
private PipedInputStream instream;
private boolean isPlaying ;
private AudioTrack audioplayer;
private AudioManager mAudioManager;
private byte[] buffer;
public mAudioPlayer(Context context) {
isPlaying = false;
instream = null;
//初始化播音类
this.context=context;
mAudioManager = (AudioManager)context.getSystemService(context.AUDIO_SERVICE);
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
mAudioManager.setMode(AudioManager.MODE_RINGTONE);
mAudioManager.setBluetoothA2dpOn(false);
int bufsize = AudioTrack.getMinBufferSize(11025, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
audioplayer = new AudioTrack(AudioManager.STREAM_VOICE_CALL, 11025, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT, bufsize,AudioTrack.MODE_STREAM);
}
//设置管道流,用于接受音频数据
public void setOutputStream(PipedOutputStream out) throws IOException{
instream = new PipedInputStream(out);
}
public void startPlayAudio(){ //调用之前先调用setOutputStream 函数
isPlaying = true;
audioplayer.play();//开始接受数据流播放
buffer = new byte[1024];
// mAudioManager.stopBluetoothSco();
while (instream!=null&&isPlaying){
try {
while (instream.available()>0){
int size = instream.read(buffer);
audioplayer.write(buffer, 0
, size);//不断播放数据
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void stopPlay(){//停止播放
isPlaying = false ;
mAudioManager.setMode(AudioManager.MODE_NORMAL);
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
try {
instream.close();
} catch (IOException e) {
e.printStackTrace();
}
audioplayer.stop();
}
}