Github下载

package com.example.superb.yy4;

import android.content.Context;

import android.media.AudioFormat;

import android.media.AudioRecord;

import android.media.MediaRecorder;

/**

Function:判断录音权限,兼容android6.0以下以及以上系统

@author xuzhuyun

@date 2018/5/10

*/

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();

}

}

android蓝牙耳机录音播放,android蓝牙耳机录音并播放(二)相关推荐

  1. Android 实时录音和回放,边录音边播放 (KTV回音效果)

    原文地址为: Android 实时录音和回放,边录音边播放 (KTV回音效果) 上一篇介绍了如何使用Mediarecorder来录音,以及播放录音.不过并没有达到我的目的,一边录音一边播放.今天就讲解 ...

  2. android中录音断点播放,Android实现暂停--继续录音(AudioRecord)

    Android提供了两个API用于录音的实现:MediaRecorder 和 AudioRecord,各有优劣. 1.MediaRecorder 已经集成了录音.编码.压缩等,支持少量的录音音频格式, ...

  3. android 实时录音播放,android 使用 audiorecord 和 audiotrack 实现实时录音播放

    基本思路就是用 audiorecord不断得到音频数据,然后使用audiotrack 播放 //得到音频 package com.ysg.audiotest; import java.io.IOExc ...

  4. Android按下录音录音动画效果 ,自定义录音、播放动画View

    Android按下录音录音动画效果 ,自定义录音.播放动画View https://download.csdn.net/download/abc2522/10327428?spm=1001.2101. ...

  5. android中录音断点播放,Android实现语音播放与录音功能

    本文实例为大家分享了Android实现语音播放与录音的具体代码,供大家参考,具体内容如下 项目用到的技术点和亮点 语音录音 (单个和列表) 语音播放(单个和列表) 语音录音封装 语音播放器封装 语音列 ...

  6. android 调用系统自带录音实现,语音录制与播放

    相关权限: <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-perm ...

  7. android 连接蓝牙耳机 播放音乐,android 手机怎么实现和蓝牙耳机建立连接,连接之后可以听音乐...

    如题,手机和蓝牙耳机配对之后,怎么建立连接 解决方案 20 BluetoothA2dpService是底层的Service类,你可以通过BluetoothA2dp类来使用它 android.bluet ...

  8. Android Audio和耳机,蓝牙耳机等音频外设

    文章目录 Android Audio和耳机,蓝牙耳机等音频外设 蓝牙连接处理 广播接收 AudioManager接口 Listener监听 蓝牙耳机和AudioService的交互 蓝牙的状态 A2D ...

  9. android 断点续录,android 录音的断点续传

    系统没有暂停的功能  只能把每次的录音进行拼接... package com.example.zrecord; import java.io.File; import java.io.FileInpu ...

最新文章

  1. 《庆余年》值得一看吗?Python告诉你谁在关注 | CSDN原力计划
  2. Failed to initialize NSS library
  3. jpane1_Java—面板组件(Jpanel)1
  4. 前端学习(590):调试javascript的流程
  5. 软件测试之单元测试之Junit测试使用前准备
  6. 是哪个app_互联网app创业哪个比较好
  7. 组策略之文件夹的重定向
  8. markdown转换html源码,利用Nodejs+Express将Markdown转换为HTML(附源码)
  9. Ubuntu tomcat
  10. leapftp,leapftp怎么上传文件
  11. 实验十、静态路由和直连路由引入配置
  12. 20140322深圳百公里
  13. 商业虚拟专用网络技术二通用路由封装
  14. yEd—很不错的开源跨平台绘图工具
  15. 一份自己整理的不太详细的常见面试题
  16. 毕业步入职场,我是怎么用python自动化做到准时下班,薪资还高的
  17. JavaScript下的setTimeout(fn,0)的作用,涨知识了
  18. uniapp 图片上传与展示
  19. Windows 显示/隐藏文件扩展名
  20. 嵌入式实时操作系统7——任务优先级表

热门文章

  1. 设定相机预览和保存照片尺寸
  2. OpenCV-Python教程:形态学变换~腐蚀和膨胀(erode,dilate)
  3. 使用c语言实现双向链表
  4. linux文件可以设置下载权限吗,linux文件权限说明(四)ACL-当前安全设置不允许下载该文件...
  5. Win8 Metro(C#)数字图像处理--2.70修正后的阿尔法滤波器
  6. Adobe XD使用心得及简单使用技巧
  7. 史上最靠谱 Ubuntu 镜像下载
  8. oracle中闪回和回滚,Oracle Flashback 闪回查询功能9i和10g的区别
  9. 如何系统型地学习深度学习?| 文末送书
  10. 焊接件技术要求怎么写_钣金焊接规范及要求