Bluetooth 蓝牙打开流程
2016-05-03 11:43
489 查看
蓝牙的打开连接主要流程:
打开
检测
扫描
连接
一、打开(开启蓝牙BT Turn on Turn off)
(蓝牙的on/off由类BluetoothEnabler控制。)
打开过程涉及到的类:
BluetoothEnabler(on/off的控制界面,界面的点击和状态文字的显示)
BluetoothService(最主要的类,开启具体命令的线程进行enable,disable等操作)
LocalBluetoothManager(本机蓝牙设备管理,开启关闭,搜索等等,初始化BluetoothAdapter)
BluetoothAdapter(framework封装的类,提供本地蓝牙设备的配置,包括开启蓝牙,搜索周围蓝牙设备,设置本地蓝牙可见性;建立LocalBluetoothManager和BluetoothService的映射关系,主要是通过它调用BluetoothService的函数)
BluetoothEventRedirector(接收Bluetooth API 的广播和回调,并且将Settings中的UI线程上的事件分派到正确的类)
以下是结合google原生6.0代码作的简要分析
/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEnabler.java
BluetoothEnabler.java里面的函数onSwitchChanged(Switch switchView, boolean isChecked)监听on/off的变化,通过mLocalAdapter.setBluetoothEnabled(isChecked);设置下去。
2.打开(关闭)操作成功后会有一个异步事件ACTION_STATE_CHANGED返回,异步事件由类BluetoothEventRedirector控制(接收广播,进行处理)。在收到ACTION_STATE_CHANGED异步事件后,还需要做update本地设备profile的事情,读取上次关闭前搜索到的蓝牙设备。
(1) ACTION_STATE_CHANGED: 定义在/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java中。
(2)通过LocalBluetoothManager.setBluetoothStateInt(int state)方法调到 CachedBluetoothDeviceManager.onBluetoothStateChanged方法来读取上次关闭之前搜索到device.
(3)来开启EnableThread线程,进行打开操作,蓝牙的打开关闭属于异步操作。
注意:
在启动蓝牙的时候,要注意的地方是不能正常启动蓝牙的情况,因为正常启动的时候会返回BluetoothIntent.ENABLED_ACTION 这个Intent,当时当启动出现异常的时候是没有Intent返回的,android使用回调函数来解决这个问题。
二、是否可检测性(Discoverable)
蓝牙模式有两种模式:
SCAN_MODE_CONNECTABLE_DISCOVERABLE(可连接可发现)
SCAN_MODE_CONNECTABLE(可连接但不可发现)
蓝牙的discoverable mode由/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java控制,
通过onPreferenceClick()方法,调用setEnabled(mDiscoverable);,然后调用到BluetoothAdapter.java里面的setScanMode () 方法
小结可检测性这里用到的类有:
BluetoothDiscoverableEnabler.java
BluetoothAdapter.java
LocalBluetoothManager
三、扫描蓝牙
在/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothSettings.java里面调用方法startScanning() ,然后到/frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
里面的函数
打开
检测
扫描
连接
一、打开(开启蓝牙BT Turn on Turn off)
(蓝牙的on/off由类BluetoothEnabler控制。)
打开过程涉及到的类:
BluetoothEnabler(on/off的控制界面,界面的点击和状态文字的显示)
BluetoothService(最主要的类,开启具体命令的线程进行enable,disable等操作)
LocalBluetoothManager(本机蓝牙设备管理,开启关闭,搜索等等,初始化BluetoothAdapter)
BluetoothAdapter(framework封装的类,提供本地蓝牙设备的配置,包括开启蓝牙,搜索周围蓝牙设备,设置本地蓝牙可见性;建立LocalBluetoothManager和BluetoothService的映射关系,主要是通过它调用BluetoothService的函数)
BluetoothEventRedirector(接收Bluetooth API 的广播和回调,并且将Settings中的UI线程上的事件分派到正确的类)
以下是结合google原生6.0代码作的简要分析
/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothEnabler.java
BluetoothEnabler.java里面的函数onSwitchChanged(Switch switchView, boolean isChecked)监听on/off的变化,通过mLocalAdapter.setBluetoothEnabled(isChecked);设置下去。
@Override 179 public void onSwitchChanged(Switch switchView, boolean isChecked) { 180 // Show toast message if Bluetooth is not allowed in airplane mode 181 if (isChecked && 182 !WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) { 183 Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show(); 184 // Reset switch to off 185 switchView.setChecked(false); 186 } 187 188 MetricsLogger.action(mContext, MetricsLogger.ACTION_BLUETOOTH_TOGGLE, isChecked); 189 190 if (mLocalAdapter != null) { 191 mLocalAdapter.setBluetoothEnabled(isChecked); 192 } 193 mSwitch.setEnabled(false); 194 }
2.打开(关闭)操作成功后会有一个异步事件ACTION_STATE_CHANGED返回,异步事件由类BluetoothEventRedirector控制(接收广播,进行处理)。在收到ACTION_STATE_CHANGED异步事件后,还需要做update本地设备profile的事情,读取上次关闭前搜索到的蓝牙设备。
(1) ACTION_STATE_CHANGED: 定义在/frameworks/base/core/java/android/bluetooth/BluetoothAdapter.java中。
(2)通过LocalBluetoothManager.setBluetoothStateInt(int state)方法调到 CachedBluetoothDeviceManager.onBluetoothStateChanged方法来读取上次关闭之前搜索到device.
public synchronized void onBluetoothStateChanged(int bluetoothState) { 153 // When Bluetooth is turning off, we need to clear the non-bonded devices 154 // Otherwise, they end up showing up on the next BT enable 155 if (bluetoothState == BluetoothAdapter.STATE_TURNING_OFF) { 156 for (int i = mCachedDevices.size() - 1; i >= 0; i--) { 157 CachedBluetoothDevice cachedDevice = mCachedDevices.get(i); 158 if (cachedDevice.getBondState() != BluetoothDevice.BOND_BONDED) { 159 cachedDevice.setVisible(false); 160 mCachedDevices.remove(i); 161 } else { 162 // For bonded devices, we need to clear the connection status so that 163 // when BT is enabled next time, device connection status shall be retrieved 164 // by making a binder call. 165 cachedDevice.clearProfileConnectionState(); 166 } 167 } 168 } 169 }
(3)来开启EnableThread线程,进行打开操作,蓝牙的打开关闭属于异步操作。
注意:
在启动蓝牙的时候,要注意的地方是不能正常启动蓝牙的情况,因为正常启动的时候会返回BluetoothIntent.ENABLED_ACTION 这个Intent,当时当启动出现异常的时候是没有Intent返回的,android使用回调函数来解决这个问题。
二、是否可检测性(Discoverable)
蓝牙模式有两种模式:
SCAN_MODE_CONNECTABLE_DISCOVERABLE(可连接可发现)
SCAN_MODE_CONNECTABLE(可连接但不可发现)
蓝牙的discoverable mode由/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java控制,
128 public boolean onPreferenceClick(Preference preference) { 129 // toggle discoverability 130 mDiscoverable = !mDiscoverable; 131 setEnabled(mDiscoverable); 132 return true; 133 }
通过onPreferenceClick()方法,调用setEnabled(mDiscoverable);,然后调用到BluetoothAdapter.java里面的setScanMode () 方法
1133 /** @hide */ 1134 public boolean setScanMode(int mode) { 1135 if (getState() != STATE_ON) return false; 1136 /* getDiscoverableTimeout() to use the latest from NV than use 0 */ 1137 return setScanMode(mode, getDiscoverableTimeout()); 1138 }
小结可检测性这里用到的类有:
BluetoothDiscoverableEnabler.java
BluetoothAdapter.java
LocalBluetoothManager
三、扫描蓝牙
在/packages/apps/Settings/src/com/android/settings/bluetooth/BluetoothSettings.java里面调用方法startScanning() ,然后到/frameworks/base/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothAdapter.java
里面的函数
public void startScanning(boolean force) { 151 // Only start if we're not already scanning 152 if (!mAdapter.isDiscovering()) { 153 if (!force) { 154 // Don't scan more than frequently than SCAN_EXPIRATION_MS, 155 // unless forced 156 if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) { 157 return; 158 } 159 160 // If we are playing music, don't scan unless forced. 161 A2dpProfile a2dp = mProfileManager.getA2dpProfile(); 162 if (a2dp != null && a2dp.isA2dpPlaying()) { 163 return; 164 } 165 } 166 167 if (mAdapter.startDiscovery()) {//开始搜索 168 mLastScan = System.currentTimeMillis(); 169 } 170 } 171 }
相关文章推荐
- uitextfield placehold 颜色
- easyui 日期范围前后台的设置以及实现
- kendo ui grid 高度自适应
- 【Android UI】动态改变ListView布局
- CoreThink主题开发(七)使用H-ui开发博客主题之新闻资讯正文页面
- 知问前端——日历UI(三)
- easyUI获取index值以及修改某列的值
- 【Android UI】具有弹性的ListView
- ios上 更改 状态栏(UIStatusBar)的颜色
- 使用NSOperation以及NSOperationQueue
- UIView的autoresizingMask属性的研究
- UIBezierPath精讲
- Unknown table ‘system_sequences’ in information_schema错误解决
- leetcode 347. Top K Frequent Elements
- NSDictionary中取出value的值赋给float型
- FluentData -Micro ORM with a fluent API that makes it simple to query a database
- android学习笔记---UI布局
- UIView 中常见的方法总结
- 【Android UI】自动显示、隐藏布局的ListView
- Null value was assigned to a property of primitive type setter of