(L1) AudioService AudioServiceBroadcastReceiver
2015-08-05 14:07
459 查看
startBluetoothSco
stopBluetoothSco
startBluetoothScoVirtualCall
---> startBluetoothScoInt --> ScoClient incCount ---> requestScoState ----> call BluetoothHeadset APIs
setBluetoothScoOn
----> setForceUse
setMode
-----> provide for telephony
Intent.ACTION_SCREEN_OFF
Intent.ACTION_CONFIGURATION_CHANGED
Intent.ACTION_USER_SWITCHED
stopBluetoothSco
startBluetoothScoVirtualCall
---> startBluetoothScoInt --> ScoClient incCount ---> requestScoState ----> call BluetoothHeadset APIs
setBluetoothScoOn
----> setForceUse
setMode
-----> provide for telephony
构造函数中注册intent
// Register for device connection intent broadcasts. IntentFilter intentFilter = new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED); intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); intentFilter.addAction(Intent.ACTION_DOCK_EVENT); intentFilter.addAction(AudioManager.ACTION_USB_AUDIO_ACCESSORY_PLUG); intentFilter.addAction(AudioManager.ACTION_USB_AUDIO_DEVICE_PLUG); intentFilter.addAction(Intent.ACTION_SCREEN_ON); intentFilter.addAction(Intent.ACTION_SCREEN_OFF); intentFilter.addAction(Intent.ACTION_USER_SWITCHED); intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
context.registerReceiver(mReceiver, intentFilter);
AudioServiceBroadcastReceiver
Intent.ACTION_DOCK_EVENT
BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED
Sco 连接 或 断开 的处理state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO; inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET; String address = null; BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (btDevice == null) { return; } address = btDevice.getAddress(); BluetoothClass btClass = btDevice.getBluetoothClass(); // 区分 out device,最终分为两种 sco headset, sco carkit if (btClass != null) { switch (btClass.getDeviceClass()) { case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET: case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET; break; case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO: outDevice = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT; break; } } if (!BluetoothAdapter.checkBluetoothAddress(address)) { address = ""; } // 判断连接状态:连接 或者 断开 boolean connected = (state == BluetoothProfile.STATE_CONNECTED); // out device, in device 由 handleDeviceConnection 分别处理 boolean success = handleDeviceConnection(connected, outDevice, address) && handleDeviceConnection(connected, inDevice, address); if (success) { synchronized (mScoClients) { if (connected) { mBluetoothHeadsetDevice = btDevice; } else { mBluetoothHeadsetDevice = null; resetBluetoothSco(); } } }
AudioManager.ACTION_USB_AUDIO_ACCESSORY_PLUG
AudioManager.ACTION_USB_AUDIO_DEVICE_PLUG
BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED
sco 状态改变 则改变变量 mScoAudioState, 在requestScoState, checkScoAudioState, disconnectBluetoothSco 时会用到boolean broadcast = false; int scoAudioState = AudioManager.SCO_AUDIO_STATE_ERROR; synchronized (mScoClients) { int btState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); // broadcast intent if the connection was initated by AudioService if (!mScoClients.isEmpty() && (mScoAudioState == SCO_STATE_ACTIVE_INTERNAL || mScoAudioState == SCO_STATE_ACTIVATE_REQ || mScoAudioState == SCO_STATE_DEACTIVATE_REQ)) { // broadcast 只有这种情况下是 true broadcast = true; } switch (btState) { case BluetoothHeadset.STATE_AUDIO_CONNECTED: scoAudioState = AudioManager.SCO_AUDIO_STATE_CONNECTED; if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL && mScoAudioState != SCO_STATE_DEACTIVATE_REQ && mScoAudioState != SCO_STATE_DEACTIVATE_EXT_REQ) { mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL; } break; case BluetoothHeadset.STATE_AUDIO_DISCONNECTED: scoAudioState = AudioManager.SCO_AUDIO_STATE_DISCONNECTED; mScoAudioState = SCO_STATE_INACTIVE; clearAllScoClients(0, false); break; case BluetoothHeadset.STATE_AUDIO_CONNECTING: if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL && mScoAudioState != SCO_STATE_DEACTIVATE_REQ && mScoAudioState != SCO_STATE_DEACTIVATE_EXT_REQ) { mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL; } default: // do not broadcast CONNECTING or invalid state broadcast = false; break; } }
if (broadcast) { broadcastScoConnectionState(scoAudioState); //FIXME: this is to maintain compatibility with deprecated intent // AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate. Intent newIntent = new Intent(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED); newIntent.putExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, scoAudioState); sendStickyBroadcastToAll(newIntent); }
checkScoAudioState
判断条件中, mif (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null && mScoAudioState == SCO_STATE_INACTIVE && mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice) != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) { mScoAudioState = SCO_STATE_ACTIVE_EXTERNAL; }
requestScoState
disconnectBluetoothSco
Intent.ACTION_SCREEN_ONIntent.ACTION_SCREEN_OFF
Intent.ACTION_CONFIGURATION_CHANGED
Intent.ACTION_USER_SWITCHED
相关文章推荐
- IOS开发获取手机内照片属性
- iOS 多线程 锁 互斥 同步
- iOS是开发之 对数组中的元素排序后输出
- iOS开发阶段技能总结
- iOS开发之——单例的几种设计方式
- iOS后台挂起程序 当程序到后台后,继续完成Long-Running Task 任务
- iOS 引用外部静态库(.a文件)时,Category方法无法加载问题
- Xcode 文档安装-iOS 8.1 Documentation
- iOS 使用nib文件(一)
- 斯坦福大学iOS8公开课笔记04—先暂停学习
- iOS 判断身份证号码
- ios7适配一些问题
- NSCache在IOS中的使用
- iOS 使用Block实现界面间传值
- iOS Navigation自定义设置Item
- ios framework通用库的制作
- 史上最完整的iOS DIY framework 详细教程(二)
- iOS 在一个TableView内使用不同的Cell
- iOS 获取应用当前定位授权状态
- ios8后点击通讯录跳转