android蓝牙耳机录音并播放(二)

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

}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: Android蓝牙耳机可以用来进行录音,在一些特定的场景下非常方便。首先,要确保安装了适合的录音应用程序,可以通过应用商店下载并安装。接下来,打开蓝牙设置并将蓝牙耳机连接到Android设备上。连接成功后,打开录音应用程序并进入录音界面。在录音界面上,选择蓝牙耳机作为录音输入设备。这个选项通常可以在设置菜单中找到。完成以上步骤后,您可以开始制声音了。通过按下录音按钮或界面上的相应按钮即可开始制。在录音过程中,蓝牙耳机将会作为麦克风来捕捉声音。录音应用程序通常提供了一些额外的功能,例如调整录音音量、选择录音格式等。制完成后,您可以保存录音文件或进行其他后续处理。总的来说,使用蓝牙耳机进行录音是一种方便快捷的方式,尤其适用于需要移动自由度的情况,如户外采访、会议记等。 ### 回答2: 在 Android 设备上使用蓝牙耳机进行录音是可能的。蓝牙耳机通常有麦克风功能,因此可以用于制语音或音频。要使用蓝牙耳机进行录音,可以按照以下步骤进行操作: 1. 确保蓝牙耳机已与 Android 设备成功配对。通常,在设备的设置中的“蓝牙”选项卡中可以完成配对过程。 2. 打开设备上的录音应用程序。Android 设备通常都预装了一款录音应用程序,你也可以从 Google Play 商店下载其他应用。 3. 在录音应用程序中,选取蓝牙耳机作为录音设备。通常,可以在应用程序的设置或选项中找到这个选项。 4. 确保蓝牙耳机处于录音模式。有些耳机可能需要通过按下耳机上的按钮来启用录音功能。 5. 开始录音。在应用程序界面上,通常有一个“开始录音”或相似的按钮,点击它以开始制。 6. 制完成后,点击“停止录音”按钮来停止制。你也可以在应用程序中选择保存录音文件的位置和名称。 7. 通过蓝牙耳机或设备本身的音频播放功能,可以回放和听取录音。 需要注意的是,由于 Android 设备和蓝牙耳机的品牌和型号众多,某些步骤可能会因设备不同而有所区别。因此,按照设备和耳机的用户手册中提供的具体说明进行操作会更加可靠和准确。 ### 回答3: Android蓝牙耳机可以用于录音蓝牙耳机和手机之间可以进行蓝牙连接,手机可以通过蓝牙耳机的麦克风制声音。 首先,确保蓝牙耳机已经成功连接到手机。打开手机的蓝牙设置,将蓝牙耳机的配对模式打开,然后在手机上选择匹配的蓝牙设备并连接。 接着,打开手机上的录音应用程序。在录音应用程序中,选择蓝牙耳机作为录音的音频输入设备。通常可以通过点击“设置”或者“音频输入”来选择录音设备。在设备列表中,选择已连接的蓝牙耳机。 然后,点击录音应用程序中的“开始制”按钮开始录音。此时,蓝牙耳机的麦克风将开始制声音。可以根据需要进行讲话或者演唱等操作。 制完成后,点击录音应用程序中的“停止制”按钮停止录音录音文件通常会自动保存在手机上的储存空间中。 需要注意的是,不同的录音应用程序可能会有略微不同的操作步骤,具体操作可能会有所变化。但是基本的原理是相同的,即通过蓝牙耳机的麦克风来制声音并保存为文件。 总结一下,Android蓝牙耳机可以通过手机上的录音应用程序进行录音操作。只需连接蓝牙耳机并选择其作为录音设备,然后开始制声音,最后保存录音文件即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值