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. L1-023 输出GPLT (C++解决,含题解)
  2. 春招来袭!程序员如何拿下硅谷顶级公司200万年薪?
  3. 三安光电圈钱凶猛 两年三轮再融资逾百亿
  4. python爬虫beautifulsoup实例-Python爬虫学习(二)使用Beautiful Soup库
  5. 产品经理日常表情包大全,多说是泪拿走不谢!
  6. Linux基础学习1--档案的属性和目录
  7. OSGI嵌入jetty应用服务器
  8. java mouselistener,Java MouseListener接口
  9. java 类加载 双亲委派_Java类加载器和双亲委派机制
  10. 架构组件:基于shard-jdbc中间件,实现数据分库分表
  11. c++ python混合编程 restful_How to use Python to build a RESTful Web Service
  12. 数据挖掘的步骤有哪些
  13. ResponsibleChain(责任链模式)
  14. PyTorch并行与分布式(二)分布式通信包torch.distributed
  15. python catia 接口_使用Python在CATIA中创建新产品
  16. 好多游戏,大部分都有修改器,大家赶紧下!
  17. matlab光学教程,基于MATLAB的物理光学仿真
  18. mysql front新建数据库_简述MySQL-Front数据库的具体操作
  19. python用嵌套if结构开发一个输入(input)快递价格的计算器
  20. Nature|人类肠道细菌对治疗药物的生物累积

热门文章

  1. 物联网开发笔记(26)- 使用Micropython开发ESP32开发板之控制LCD1602显示屏(续)
  2. java asn.1_ASN1编解码实现方法 | 学步园
  3. Unity云渲染搭建二(Unity2019.4)开发版本的webapp服务
  4. 基于51单片机的智能光控路灯设计及设计报告
  5. iOS应用处于前台、后台、应用被杀掉场景-收到远程推送内容进行收款语音播报;
  6. C++实例:根据给定的日期计算天数
  7. 关于ng-alain的st、sf一些小功能的总结
  8. 【期末大作业】基于HTML+CSS+JavaScript网上订餐系统(23个页面)
  9. ICT技术发展趋势,AI、大数据和云计算的概述及存储应用技术【2】
  10. Unity安卓如何调用小键盘对配置文件进行修改