蓝牙BLE注解
一个service包含多个characteristic
一个characteristic包含1个value
1个value可以用多个descriptor描述
1,BluetoothGatt:BluetoothGatt 是我们用的最多,也是我们最重要的一个类,为了尽可能通俗的理解,这里我们可以把它看成Android手机与BLE终端设备建立通信的一个管道,只有有了这个管道,我们才有了通信的前提。
2,BluetoothGattService:蓝牙设备的服务,在这里我们把BluetoothGattService比喻成班级。而Bluetoothdevice我们把它比喻成学校,一个学校里面可以有很多班级,也就是说我们每台BLE终端设备拥有多个服务,班级(各个服务)之间通过UUID(唯一标识符)区别
3,BluetoothGattCharacteristic: 蓝牙设备所拥有的特征,它是手机与BLE终端设备交换数据的关键,我们做的所有事情,目的就是为了得到它。在这里我们把它比喻成学生,一个班级里面有很多个学生,也就是说我们每个服务下拥有多个特征,学生(各个特征)之间通过UUID(唯一标识符)区别。
4,总结:当我们想要用手机与BLE设备进行通信时,实际上也就相当于我们要去找一个学生交流,首先我们需要搭建一个管道,也就是我们需要先获取得到一个BluetoothGatt,其次我们需要知道这个学生在哪一个班级,学号是什么,这也就是我们所说的serviceUUID,和charUUID。这里我们还需要注意一下,找到这个学生后并不是直接和他交流,他就好像一个中介一样,在手机和BLE终端设备之间帮助这两者传递着信息,我们手机所发数据要先经过他,在由他传递到BLE设备上,而BLE设备上的返回信息,也是先传递到他那边,然后手机再从他那边进行读取。
BLE流程
// 初始化蓝牙适配器 TODO 1 final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter();
// 确保蓝牙在设备上可以开启 TODO 2 if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); }
/** * TODO 3.1 * 扫描和显示可以提供的蓝牙设备. 10秒后停止寻找. * mBluetoothAdapter.startLeScan(mLeScanCallback); * 如果你只想扫描指定类型的外围设备,可以改为调用startLeScan(UUID[], BluetoothAdapter.LeScanCallback));需要提供你的app支持的GATT services的UUID对象数组。 */ private void scanLeDevice(final boolean enable) { if (enable) { // 经过预定扫描期后停止扫描 mHandler.postDelayed(new Runnable() { @Override public void run() { mScanning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); } }, SCAN_PERIOD); mScanning = true; mBluetoothAdapter.startLeScan(mLeScanCallback); } else { mScanning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); } }
/** * TODO 3.2 * 扫描的回调 */ BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { runOnUiThread(new Runnable() { @Override public void run() { // mLeDeviceListAdapter.addDevice(device); //列表添加扫描到的蓝牙对象 // mLeDeviceListAdapter.notifyDataSetChanged(); } }); } };
public void connect(final String address) { // TODO 4 连接到BLE设备上的GATT服务器(显示到列表上后,根据选择的BEL设备连接通道) mBluetoothGatt = device.connectGatt(this, false, mGattCallback); }
/** * TODO 4.2 * 连接状态的回调 */ private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { //连接状态改变的回调 @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (newState == BluetoothProfile.STATE_CONNECTED) { // 连接成功后启动服务发现 Log.e("AAAAAAAA", "启动服务发现:" + mBluetoothGatt.discoverServices()); } } //发现服务的回调 public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { Log.e(TAG, "成功发现服务"); } else { Log.e(TAG, "服务发现失败,错误码为:" + status); } } //写操作的回调 public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { Log.e(TAG, "写入成功" + characteristic.getValue()); } } //读操作的回调 public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { Log.e(TAG, "读取成功" + characteristic.getValue()); } } //数据返回的回调(此处接收BLE设备返回数据) public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { } };
/** * TODO 5 * 连接到设备之后获取设备的服务(Service)和服务对应的Characteristic。 * 获取到特征之后,找到服务中可以向下位机写指令的特征,向该特征写入指令 * 写入成功之后,开始读取设备返回来的数据。 */