Bluetooth Low Energy
概述
Android 4.3(API=18)介绍了内置平台支持蓝牙低能耗(BLE)的中心作用,并提供了API,应用程序可以使用它来发现设备,查询服务和传输信息。
Ble通信适合在传输少量数据的场景下使用。它比Classic蓝牙通信方式的能耗要低很多。如接近传感器、心率监视器和健身设备等都是用Ble方式通信。
一些名词
GATT:现在低功耗蓝牙(BLE)连接都是建立在 GATT (Generic Attribute Profile) 协议之上。GATT 是一个在蓝牙连接之上的发送和接收很短的数据段的通用规范,这些很 短的数据段被称为属性(Attribute)。
Service:通过GATT连接后,可以得到一个Service的集合,每个Service中包含不同的信息,例如当前设备的信息Device Information Service,进行数据传输的service等。
Characteristic:在每一个service下面有存在这一组Characteristic特征值,这些特征值是最小的逻辑数据单元,读取特征值数据,或者写数据,实现双向的通信。
他们的关系如下图:
BLE设备的通信
操作步骤
1,配置权限:
<uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>如果你想声明你的app必须在支持BLE的设备上使用进行如下配置
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>在我们的代码中通过以下方法进行判断:
// Use this check to determine whether BLE is supported on the device. Then // you can selectively disable BLE-related features. if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); finish(); }2,获取BluetoothAdapter
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 或者: BluetoothManager manager =(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); BluetoothAdapter adapter = manager.getAdapter();如果你的环境是:JELLY_BEAN_MR1及以下的话用第一种,否则使用第二种。
3,搜索周围Ble设备:
adapter.statLeScan(BluetoothAdapter.LeScanCallback) // Device scan callback. private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { //do some thing... } };Ble通信使用回调的方式来得到搜索到的蓝牙设备。
4,连接
BluetoothGatt mBluetoothGatt = device.connectGatt(this, false, mGattCallback);通过BluetoothGatt接下来我们可以获得GATT中的Service列表和Service中的Characteristic列表。
mGattCallback:回调接口BluetoothGattCallback的实例,回调Gatt使用过程中的不同操作,和蓝牙状态的回调。如下为自定义的BluetoothGattCallback:
// Implements callback methods for GATT events that the app cares about. For example, // connection change and services discovered. private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { String intentAction; if (newState == BluetoothProfile.STATE_CONNECTED) { Log.e("message","device connected!"); //连接上后去搜寻蓝牙设备的所有Services //mBluetoothGatt.discoverServices(); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { Log.e("message","device disconnected !") } } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { Log.e("message","gatt discovery completed!"); } else { Log.w(TAG, "onServicesDiscovered received: " + status); } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { } } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { } };BluetoothGattCallback的几个回调函数:
onConnectionStateChange:当蓝牙的连接状态发生改变时回调,常常在连接成功后,去启动搜索Gatt操作:mBluetoothGatt.discoverServices(); onServicesDiscovered:当搜索Gatt操作完成或失败时回调。完成后就可以和设备进行通信了。 onCharacteristicRead:当我们读取特征值时回调,对应的还有一个Write方法。 onCharacteristicChanged:当特征值发生改变时回调。5,通信
在我们和Ble设备建立好连接,并且扫描完成Gatt服务之后,我们就可以拿到Services列表和每个Service下的Characteristic列表,我们通信就是通过不同的Characteristic来操作的。 每个Characteristic都有自己的特性:可读,可写,可通知等。 例如: Characteristic.PROPERTY_NOTIFY Characteristic.PROPERTY_READ Characteristic.PROPERTY_WRITE //Characteristic.PROPERTY_WRITE用来向设备发送数据的特征值。 //Characteristic.PROPERTY_NOTIFY用来接收来自蓝牙设备发过来的数据。 //必须进行如下配置才能接收蓝牙设备发来的数据: String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"; BluetoothGattDescriptor descriptor = characteristic.getDescriptor( UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG)); descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); gatt.writeDescriptor(descriptor);好接下来就可以正常的和我们连接上的蓝牙设备进行通信了,
下发指令(手机向蓝牙设备发送数据):
Characteristic characteristic使用特性为PROPERTY_WRITE的作为我们进行写时的特征值,
byte[] commnd1 = new byte[] { (byte) 0xAA, 0x55, 0x0F, 0x02, (byte) 0x83}; characteristic = Characteristic.setValue(commnd1); gatt.write(characteristic)上传指令(手机读取来自蓝牙设备的数据):
当有数据从蓝牙设备发送来手机时会去回调onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)byte[] data = characteristic.getValue()即可拿到数据。
以上为Android 蓝牙Ble通信的过程,总结一下就是,我们通信都是在指定的特征值下进行的,一般对接蓝牙设备时都会拿到它的通信协议,帮助我们解析data字节数据数据。
点击查看官方提供的Demo的github地址。 如果对你有些许帮助请添加公众号: