问题
I have a BluetoothDevice with it's associated BluetoothGatt object. This is a device that the user connects to daily, and it does not have any characteristics or services that change often.
Right now in order to interact with the device, after each connect I have to first discover all services, which often adds 1-5 seconds of delay to the whole process.
My question is: is it possible to save a cache of my devices' services and characteristics so that I don't have to actually do a call to discoverServices
after each connect ?
回答1:
I don't know about iOS phones but Android phones always cach the discovered characteristics and services so that service discovery takes shorter time compared to first connection. See this thread .
You question should be whether it is possible to eliminate service discovery or not at all. According to Bluetooth spec, you don't need to perform service discovery after each connection. If you know the UUIDs of the characteristic and its service, it is possible to directly do (without service discovery) GATT operations based on the characteristic properties.
Android requires service discovery to instantiate BluetoothGattService
and BluetoothGattCharacteristic
objects. However, you can instantiate your own BluetoothGattService
and BluetoothGattCharacteristic
objects by looking into the source code of Android and using Java reflections. You can first create these objects with the constructors which are available in BLE API. Then to hook the characteristics to services, and services to BluetoothGatt object, you will need to use Java reflection methods. To do that, you should read the source code of the classes (just hold control and click on the class in Android Studio to view the source code). I, by myself implemented this and soon I will update this thread with my blog post, but here is a sneak peek:
BluetoothGattService mService = new BluetoothGattService(mServiceUuid, BluetoothGattService.SERVICE_TYPE_PRIMARY);
BluetoothGattCharacteristic mCharacteristic1 = new BluetoothGattCharacteristic(mChar1Uuid, BluetoothGattCharacteristic.PROPERTY_WRITE, 0);
BluetoothGattCharacteristic mCharacteristic2 = new BluetoothGattCharacteristic(mChar2Uuid, BluetoothGattCharacteristic.PROPERTY_NOTIFY, 0);
BluetoothGattDescriptor mChar2Cccd = new BluetoothGattDescriptor(mCccdUuid, 0);
You should use Java reflection methods; firstly to hook the characteristics to the service; secondly service to BluetoothGatt instance which is instantiated as soon as the BLE Gatt connection is established.
回答2:
For iOS, it won't work.
If you don't call discoverServices
for each connect,your Peripheral instance's services property will always be nil,so is services' characters.
Anything after that won't work.
If you have yet to call the discoverServices: method to discover the services of the peripheral, or if there was an error in doing so, the value of this property is nil.
来源:https://stackoverflow.com/questions/34378786/save-a-cache-of-all-services-and-characteristics-of-a-bluetoothdevice-possible