一.蓝牙相关的类
1)BluetoothSettings.java
该类是蓝牙配置和连接管理界面,就是咱们常见的蓝牙界面。它管理着蓝牙界面的加载,蓝牙搜索,蓝牙连接,蓝牙重命名等管理功能。(顺便借用一下大牛做的图片:https://www.cnblogs.com/dixonyy/p/4246057.html)
2)BluetoothEnable.java
该类是蓝牙辅助类,用来管理蓝牙的开和关以及蓝牙状态的标题显示。如打开或关闭蓝牙的switchbar的状态和文本显示。
3)DeviceListPreferenceFragment.java
该类是BluetoothSettings类的父类,是一个抽象类,该类包含了用于保存蓝牙设备的链表以及蓝牙。还包含蓝牙设备的一些回调方法。例如,蓝牙设备的删除、扫描状态的改变、蓝牙状态的改变等回调方法的实现。(回调接口所在的类:BluetoothCallback.java)
final WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap =
new WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference>();
该变量保存的是用于显示的蓝牙设备集合,可以删除或添加相应的蓝牙设备。
4)CachedBluetoothDevice.java
缓存蓝牙设备,该类代表了一个远程设备,它包含了蓝牙设备的一些属性(例如蓝牙地址,名字,信号强度等)。该类还可以进行蓝牙设备的连接、配对、断开连接等功能。
5)BluetoothDevice.java
该类也代表了一个远程设备,但是与上面不同的是就相当与你买了一个水杯,水杯就是BluetothDevice,用包装盒包裹起来的就是CachedBluetoothDevice。(个人比喻,有什么不对的可以指点改正,谢谢!)
6)BluetoothDevicePreference.java
该类是在设置界面显示蓝牙设备的偏好类型。点击界面上的配对、连接、断开就是在这操作的。
7)BluetoothAdapter.java
蓝牙适配器,是蓝牙的总中枢,是蓝牙的起点。要想使用蓝牙必须要开启或关闭,它就是蓝牙的总开关。该类让你执行基本的蓝牙任务,例如:初始化发现设别,查询绑定/配对的设备,使用蓝牙MAC地址实例化一个BLuetoothDevice,创建一个BLuetoothServerSocket来监听来自其它蓝牙设备的请求连接,开始扫描蓝牙低功耗设备等等。
8)蓝牙事件管理BluetoothEventManager.java
首先这里注册一个事件接收广播mContext.registerReceiver(mBroadcastReceiver, mAdapterIntentFilter);,用于接收底层驱动发来的广播。然后根据不同的action分发给不同的handler处理。这里的handler都需要通过addHandler函数保存到mHandlerMap中。然后在Handler中调用回调BluetoothCallback(接口),来交给ui上层处理。当然这里继承了BluetoothCallback接口的回调都是事先注册了的registerCallback。在设置中是DeviceListPreferenceFragment注册了。
9)LocalBluetoothAdapter.java
蓝牙接口适配为本地的蓝牙接口适配器,为应用提供接口,同时调用BluetoothAdapter的接口,起到应用和底层的适配作用。
10)CachedBluetoothDeviceManager.java
该类负责管理蓝牙的缓存(已配对的设备和搜索到的设备)主要都保存在List<CachedBluetoothDevice> mCachedDevices中
11)LocalBluetoothProfileManager.java
该类提供访问有效的蓝牙协议对象LocalBluetoothProfile
二.蓝牙流程
1.开启关闭蓝牙
1)开启过程
开启和关闭蓝牙的switchbar的监听状态存在与BluetoothEnable类中,当打开switchbar时
@Overridepublic void onSwitchChanged(Switch switchView, boolean isChecked) {// Show toast message if Bluetooth is not allowed in airplane modeif (isChecked &&!WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) {Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();// Reset switch to offswitchView.setChecked(false);}MetricsLogger.action(mContext, MetricsLogger.ACTION_BLUETOOTH_TOGGLE, isChecked);if (mLocalAdapter != null) {
//若isChecked为true,说明要开启蓝牙mLocalAdapter.setBluetoothEnabled(isChecked);}mSwitch.setEnabled(false);}
public void setBluetoothEnabled(boolean enabled) {boolean success = enabled? mAdapter.enable(): mAdapter.disable();if (success) {setBluetoothStateInt(enabled? BluetoothAdapter.STATE_TURNING_ON: BluetoothAdapter.STATE_TURNING_OFF);} else {if (Utils.V) {Log.v(TAG, "setBluetoothEnabled call, manager didn't return " +"success for enabled: " + enabled);}syncBluetoothState();}}
--》BluetoothAdapter.enable()-->BluetoothManagerService.enable()
到了BluetoothManagerService就有点麻烦了
BluetoothManagerService.enable()
public boolean enable() {if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&(!checkIfCallerIsForegroundUser())) {Log.w(TAG,"enable(): not allowed for non-active and non system user");return false;}mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,"Need BLUETOOTH ADMIN permission");if (DBG) {Log.d(TAG,"enable(): mBluetooth =" + mBluetooth +" mBinding = " + mBinding);}synchronized(mReceiver) {mQuietEnableExternal = false;mEnableExternal = true;// waive WRITE_SECURE_SETTINGS permission checksendEnableMsg(false);}if (DBG) Log.d(TAG, "enable returning");return true;}
BluetoothManagerService.sendEnableMsg()发送一个handler开启蓝牙的消息
private void sendEnableMsg(boolean quietMode) {mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ENABLE,quietMode ? 1 : 0, 0));}
BluetoothManagerService.handler
case MESSAGE_ENABLE:if (DBG) {Log.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth);}mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);mEnable = true;handleEnable(msg.arg1 == 1);break;
BMS.handleEnable() 只取了部分开启蓝牙的代码
//Enable bluetoothtry {if (!mQuietEnable) {
//开启蓝牙if(!mBluetooth.enable()) {Log.e(TAG,"IBluetooth.enable() returned false");}}else {if(!mBluetooth.enableNoAutoConnect()) {Log.e(TAG,"IBluetooth.enableNoAutoConnect() returned false");}}} catch (RemoteException e) {Log.e(TAG,"Unable to call enable()",e);}
接下来又调用了IBluetooth.enable(),具体实现是在AdapterService中,进而调用了AdapterService.enable()-->enable(boolean),代码如下:
public synchronized boolean enable(boolean quietMode) {enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission");debugLog("enable() - Enable called with quiet mode status = " + mQuietmode);mQuietmode = quietMode;Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_ON);mAdapterStateMachine.sendMessage(m);return true;}
接下来就到状态机AdapterState了,下面对BLE_TURN_ON消息进行处理
case BLE_TURN_ON: notifyAdapterStateChange(BluetoothAdapter.STATE_BLE_TURNING_ON);mPendingCommandState.setBleTurningOn(true);transitionTo(mPendingCommandState);sendMessageDelayed(BLE_START_TIMEOUT, BLE_START_TIMEOUT_DELAY);adapterService.BleOnProcessStart();break;
蓝牙开启之后,状态肯定变化了,所以也要发送一个广播,通知调用蓝牙的地方告诉它蓝牙状态已经改变,快做其它处理吧
private void notifyAdapterStateChange(int newState) {AdapterService adapterService = mAdapterService;AdapterProperties adapterProperties = mAdapterProperties;if ((adapterService == null) || (adapterProperties == null)) {errorLog("notifyAdapterStateChange after cleanup:" + newState);return;}int oldState = adapterProperties.getState();adapterProperties.setState(newState);infoLog("Bluetooth adapter state changed: " + oldState + "-> " + newState); adapterService.updateAdapterState(oldState, newState);}
下面就到了adapterservice里进行状态的更新了
void updateAdapterState(int prevState, int newState){if (mCallbacks !=null) {int n=mCallbacks.beginBroadcast();debugLog("updateAdapterState() - Broadcasting state to " + n + " receivers.");for (int i=0; i <n;i++) {try { mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState,newState);} catch (RemoteException e) {debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")");}}mCallbacks.finishBroadcast();}}
上面的加红的到底跳到哪个地方了哪?答案就是又回到BluetoothManagerService里了,这个回调主要实现的功能就是发送一个蓝牙状态改变的广播。
private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {@Overridepublic void onBluetoothStateChange(int prevState, int newState) throws RemoteException {Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE,prevState,newState);mHandler.sendMessage(msg);}};
懒得做时序图了,顺便再借用以下别人的。
蓝牙开启时序图
好了,蓝牙开启的部分已经结束了。通过上面的流程代码和时序图相信大家基本上能够搞清楚了。
2)蓝牙关闭流程
这个就不贴代码详细介绍了,基本的流程和蓝牙开启基本上都是一个样,请自行分析源代码。
这一节就介绍那么多,下一节将介绍蓝牙的配对、连接流程。