解决 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链路也支持接收主设备发给微微网中所有从设备的广播消息。
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
- 解决 android audiorecord 蓝牙耳机 重启导致录音数据异常问题
- Android蓝牙开发浅谈 __ 耳机录音
- AudioRecord录音初始化异常
- 蓝牙耳机录音
- 蓝牙耳机录音
- Android AudioRecord实现录音
- Android录音--AudioRecord、MediaRecorder
- Android录音--AudioRecord、MediaRecorder
- Android录音--AudioRecord、MediaRecorder
- Android APP通过蓝牙耳机录音可行性分析
- 关于android AudioRecord MediaRecord 录音格式 问题存档
- Androidの解决自动旋转导致activity重启问题
- 【Android】【录音】Android录音--AudioRecord、MediaRecorder
- 【Android】【录音】Android录音--AudioRecord、MediaRecorder
- 【Android】【录音】Android录音--AudioRecord、MediaRecorder
- 【Android】【录音】Android录音--AudioRecord、MediaRecorder
- 【Android】【录音】Android录音--AudioRecord、MediaRecorder
- Android之录音--AudioRecord、MediaRecorder
- iOS 单例模式的写法
- Java调用本地接口:java.lang.UnsatisfiedLinkError
- Android系统性能调优工具介绍
- PHP:const 和 defind 的区别
- 2017年校招全国统一模拟笔试(第二场)编程题集合--Python
- 解决 android audiorecord 蓝牙耳机 重启导致录音数据异常问题
- VS发布应用未能创建默认证书的问题解决方法
- 字符串
- Hibernate学习笔记(九)Hibernate 查询方式
- JDBC连接数据库经验技巧
- Darknet—yolo实时目标检测
- MySQL数据恢复方法
- LeetCode 467 Unique Substrings in Wraparound String (思维题)
- 如何定义一个只能在堆上生成对象的类