zoukankan      html  css  js  c++  java
  • Android 蓝牙模块

    前天想找个蓝牙录音程序,发现居然没有!没办法,就自己动手DIY了。一些关键代码摘出来,希望对大家有用。
        本代码基于android 2.2以上。IOS就不要问我了,不越狱的IOS设备,蓝牙除了用蓝牙耳机,再就是IOS设备之间联机游戏,不可理喻!

    一、初始化

    添加权限:
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />


    ......
        private static String mFileName = null;
        private MediaRecorder mRecorder = null;
        private MediaPlayer   mPlayer = null;
        private AudioManager mAudioManager = null; 
    ......
        mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
    ......
         


    二、录音
       private void startRecording() {
        //获得文件保存路径。记得添加android.permission.WRITE_EXTERNAL_STORAGE权限
        mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
        mFileName += "/btrecorder.3gp";
       
            mRecorder = new MediaRecorder();
            mRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mRecorder.setOutputFile(mFileName);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            try {
                mRecorder.prepare();//如果文件打开失败,此步将会出错。
            } catch (IOException e) {
                Log.e(LOG_TAG, "prepare() failed");
            }

            if(!mAudioManager.isBluetoothScoAvailableOffCall()){
               Log.d(LOG_TAG, "系统不支持蓝牙录音");
            return;
            }
    //蓝牙录音的关键,启动SCO连接,耳机话筒才起作用
            mAudioManager.startBluetoothSco();
            //蓝牙SCO连接建立需要时间,连接建立后会发出ACTION_SCO_AUDIO_STATE_CHANGED消息,通过接收该消息而进入后续逻辑。
            //也有可能此时SCO已经建立,则不会收到上述消息,可以startBluetoothSco()前先stopBluetoothSco()
            registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);

                    if (AudioManager.SCO_AUDIO_STATE_CONNECTED == state) { 
       mAudioManager.setBluetoothScoOn(true);  //打开SCO
                        mRecorder.start();//开始录音
                        unregisterReceiver(this);  //别遗漏
                    }else{//等待一秒后再尝试启动SCO
                        try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
            e.printStackTrace();
                    }
                        mAudioManager.startBluetoothSco(); 
                    }
                }
            }, new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED));
        }

    三、停止录音    
        private void stopRecording() {
        mRecorder.stop();
            mRecorder.release();
            mRecorder = null;
            if(mAudioManager.isBluetoothScoOn()){
                mAudioManager.setBluetoothScoOn(false);
                mAudioManager.stopBluetoothSco();
            }
        }

    四、播放录音到A2DP    
        private void startPlaying() {
            mPlayer = new MediaPlayer();
            try {
                if(!mAudioManager.isBluetoothA2dpOn()) mAudioManager.setBluetoothA2dpOn(true); //如果A2DP没建立,则建立A2DP连接
                mAudioManager.stopBluetoothSco();//如果SCO没有断开,由于SCO优先级高于A2DP,A2DP可能无声音
                try {
    Thread.sleep(500);
       } catch (InterruptedException e) {
    e.printStackTrace();
                }
                mAudioManager.setStreamSolo(AudioManager.STREAM_MUSIC, true);
                //让声音路由到蓝牙A2DP。此方法虽已弃用,但就它比较直接、好用。
                mAudioManager.setRouting(AudioManager.MODE_NORMAL, AudioManager.ROUTE_BLUETOOTH_A2DP, AudioManager.ROUTE_BLUETOOTH);
               mPlayer.setDataSource(mFileName);
                mPlayer.prepare();
                mPlayer.start();
            } catch (IOException e) {
                Log.e(LOG_TAG, "prepare() failed");
            }
        }

    五、停止A2DP播放   
        private void stopPlaying() {
            mPlayer.release();
            mPlayer = null;
            mAudioManager.setStreamSolo(AudioManager.STREAM_MUSIC, false);    

        } 

     总之记住如下的:

     1)要使用蓝牙耳机的mic,则操作SCO这玩意。

     2)如果要将音频输入到蓝牙耳机,则使用A2DP,(比如说打电话,语音播放呀什么的)这个玩意。

     3)记住,SCO这个权限比A2DP的高。如果在进行操作。

  • 相关阅读:
    IntentService使用以及源码分析
    Android HandlerThread源码解析
    Android Handler消息机制源码解析
    Gradle技术之四
    Android EditText实现小数点后几位的终级方案
    Gradle系列之三 Gradle概述以及生命周期
    Gradle系列之二 Groovy对文件的操作
    Gradle系列之一 Groovy语法精讲
    Context源码分析
    用EXCLE群发outlook邮件
  • 原文地址:https://www.cnblogs.com/wsfjlagr/p/3896087.html
Copyright © 2011-2022 走看看