解决 android audiorecord 蓝牙耳机 重启导致录音数据异常问题

来源:互联网 发布:c语言map容器 编辑:程序博客网 时间:2024/05/17 22:18

解决 android audiorecord 蓝牙耳机 重启导致录音数据异常问题

蓝牙 两种同步链路(SCO)和异步链路(ACL)。A2DP(Advanced Audio Distribution Profile 高级音频传输模型)是跑在ACL链路上去高品质音频协议。A2DP定义了ACL(Asynchronous Connectionless 异步无连接)信道上传送单声道或立体声等高质量音A2DP 功能频信息的协议和过程。
蓝牙物理链路SCO(Synchronous Connection Oriented)主要用来传输对时间要求很高的数据通信, 另外的一种链路是ACL(Asynchronous Connectionless)。
 SCO连接为对称连接,利用保留时隙传送数据包。连接建立后,主设备和从设备可以不被选中就发送SCO数据包。SCO数据包既可以传送话音,也可以传送数据,但在传送数据时,只用于重发被损坏的那部分的数据。
       ACL链路就是定向发送数据包,它既支持对称连接,也支持不对称连接(既可以一对一,也可以一对多。主设备负责控制链路带宽,并决定微微网中的每个从设备可以占用多少带宽和连接的对称性。从设备只有被选中时才能传送数据。ACL链路也支持接收主设备发给微微网中所有从设备的广播消息

我们要选用的SCO模式,A2DP模式是默认链接的只进不出,蓝牙只能听到手机播放音乐不能录制声音

1.获取 AudioMannager

 mAudioManager = ((AudioManager) getSystemService(Context.AUDIO_SERVICE));

2. 设置音频模式为交流模式

mAudioManager.setMode(mAudioManager.MODE_IN_COMMUNICATION);

3. 注册 蓝牙监控事件

mAudioManager.registerMediaButtonEventReceiver(new ComponentName(                this,                MusicIntentReceiver.class));


@SuppressLint("InlinedApi")    public class MusicIntentReceiver extends BroadcastReceiver {        private static final String LOG_TAG = "jni";        private Context mContext;        private KeyService mKeyService;        @Override        public void onReceive(Context context, Intent intent) {            mContext = context;            mKeyService = new KeyService(mContext);            if (intent.getAction().equals(                    android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {                Toast.makeText(context, "Headphones disconnected.",                        Toast.LENGTH_SHORT).show();                Log.i(LOG_TAG, "Headphones disconnected.!");                // send an intent to our MusicService to telling it to pause the                // audio                // context.startService(new Intent(MusicService.ACTION_PAUSE));            } else if (intent.getAction().equals(Intent.ACTION_MEDIA_BUTTON)) {                Log.i(LOG_TAG, "ACTION_MEDIA_BUTTON!");                KeyEvent keyEvent = (KeyEvent) intent.getExtras().get(                        Intent.EXTRA_KEY_EVENT);                if (keyEvent.getAction() != KeyEvent.ACTION_DOWN)                    return;                switch (keyEvent.getKeyCode()) {                    case KeyEvent.KEYCODE_HEADSETHOOK:                    case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:                        // context.startService(new                        // Intent(MusicService.ACTION_TOGGLE_PLAYBACK));                        break;                    case KeyEvent.KEYCODE_MEDIA_PLAY:                        // context.startService(new Intent(MusicService.ACTION_PLAY));                        break;                    case KeyEvent.KEYCODE_MEDIA_PAUSE:                        // context.startService(new Intent(MusicService.ACTION_PAUSE));                        break;                    case KeyEvent.KEYCODE_MEDIA_STOP:                        // context.startService(new Intent(MusicService.ACTION_STOP));                        break;                    case KeyEvent.KEYCODE_MEDIA_NEXT:                        // context.startService(new Intent(MusicService.ACTION_SKIP));                        break;                    case KeyEvent.KEYCODE_MEDIA_PREVIOUS:                        // TODO: ensure that doing this in rapid succession actually                        // plays the                        // previous song                        // context.startService(new Intent(MusicService.ACTION_REWIND));                        break;                }            } else if (intent.getAction().equals(                    BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {                int state = intent.getIntExtra(                        BluetoothAdapter.EXTRA_CONNECTION_STATE, 0);                if (state == BluetoothAdapter.STATE_CONNECTED                        ) {                    Log.i(LOG_TAG, "BluetoothAdapter.ACTION_CONNECTION_STATE_CONNECT");                }                else if (state == BluetoothAdapter.STATE_DISCONNECTED){                    Log.i(LOG_TAG, "BluetoothAdapter.ACTION_CONNECTION_STATE_DISCONNECTED");                }            } else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {                Log.i(LOG_TAG, "Intent.ACTION_BOOT_COMPLETED");            } else if (intent.getAction().equals("android.intent.action.UPDATE_SUSPEND_TIME_BY_HAND")) {                Log.i(LOG_TAG, "Intent.UPDATE_SUSPEND_TIME_BY_HAND");            } else {//            Log.i(LOG_TAG, "other intent");            }        }

4. 开启线程监控 控制录音

if (mKeyService.isBtConect()) {                        if (!is_record) {                            try {                                Thread.sleep(15000);                            } catch (InterruptedException e) {                                e.printStackTrace();                            }                         mAudioManager.setMode(mAudioManager.MODE_IN_COMMUNICATION);                            mAudioManager.startBluetoothSco();                            mAudioManager.setSpeakerphoneOn(false);                            mAudioManager.setBluetoothScoOn(true);                            Log.i(LOG_TAG, "bluetooth is connect at start activity =  " + mAudioManager.isBluetoothScoOn() + mAudioManager.getMode());                            record = new RecordPlayActivity();                            record.playStart();                            is_record = true;                        }                    } else {                        if (is_record == true) {//                            mAudioManager.stopBluetoothSco();                            mAudioManager.setMode(mAudioManager.MODE_NORMAL);//                            mAudioManager.setBluetoothScoOn(false);//                            mAudioManager.stopBluetoothSco();                            record.stopRecord();                            record = null;                            is_record = false;                        }                    }
注意红色字体,这个是解决蓝牙重新连接开始录音的关键,因为蓝牙重连接虽然广播收到了通知,但是蓝牙耳机自己还没准备好,所以当接收到蓝牙耳机连接好的通知,在延迟一定的时间,既可以完美解决了这个问题了。




阅读全文
0 0