onservicesbe discoveredd怎么获取读写和特征的uuid

我再网上看了很多关于BLE开发的技术博客已经文章,基本都是翻译Goole的API文档,基本没有解决我的问题,经过我自己的研究我基本解决了手头上的问题。现在我把它分享给大家。
问题1:UUID的获取。
看过goole文档的朋友应该对SampleGattAttributes这个类不陌生,因为文档中的UUID就是从这个类中获取到的,但是这个类又在哪里呢?
经过我的研究 我完善了SampleGattAttributes这个类。代码如下:
public class SampleGattAttributes {
private static HashMap&String, String& attributes = new HashMap&String, String&();
public static String HEART_RATE_MEASUREMENT = &0-805f9b34fb&;
public static String CLIENT_CHARACTERISTIC_CONFIG = &0-805f9b34fb&;
public static String MYCJ_BLE = &服务UUID&;
public static String MYCJ_BLE_READ = &读属性UUID&;
public static String MYCJ_BLE_WRITE = &写属性UUID&;
attributes.put(&0000fff-f9b34fb&, &Heart Rate Service&);
attributes.put(&00-805f9b34fb&, &Device Information Service&);
attributes.put(HEART_RATE_MEASUREMENT, &Heart Rate Measurement&);
attributes.put(&0-805f9b34fb&, &Manufacturer Name String&);
public static String getUUID(String uuidKey) {
return attributes.get(uuidKey);
关于UUID 每个设备都会有很多UUID组,那如何获取他们呢? 这就是接下来我要告诉大家的事情。
BluetoothGattCallback接口获取大家都不陌生,在BluetoothGattCallback接口中的&onServicesDiscovered(BluetoothGatt gatt, int status)方法中 使用gatt对象调用getServices()方法就可以得到这个设备的全部的UUID组了。
代码如下:
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
gatt.discoverServices();
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
mGattServices = gatt.getServices();
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorRead(gatt, descriptor, status);
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
super.onReadRemoteRssi(gatt, rssi, status);
获取到全部的服务,但是如何获取到服务中的读写特征的UUID呢?
代码如下:
private void getUUID(List&BluetoothGattService& gattServices) {
ArrayList&HashMap&String, String&& gattServiceData = new ArrayList&HashMap&String, String&&();
ArrayList&ArrayList&HashMap&String, String&&& gattCharacteristicData = new ArrayList&ArrayList&HashMap&String, String&&&();
mGattCharacteristics = new ArrayList&ArrayList&BluetoothGattCharacteristic&&();
for (BluetoothGattService gattService : gattServices) {
HashMap&String, String& currentServiceData = new HashMap&String, String&();
uuid = gattService.getUuid().toString();
if (gattService.getType() == BluetoothGattService.SERVICE_TYPE_PRIMARY) {
uuid = gattService.getUuid().toString();
if (gattService.getType() == BluetoothGattService.SERVICE_TYPE_SECONDARY) {
uuid = gattService.getUuid().toString();
currentServiceData.put(LIST_UUID, uuid);
gattServiceData.add(currentServiceData);
ArrayList&HashMap&String, String&& gattCharacteristicGroupData = new ArrayList&HashMap&String, String&&();
List&BluetoothGattCharacteristic& gattCharacteristics = gattService.getCharacteristics();
charas = new ArrayList&BluetoothGattCharacteristic&();
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
charas.add(gattCharacteristic);
HashMap&String, String& currentCharaData = new HashMap&String, String&();
uuid = gattCharacteristic.getUuid().toString();
if ((BluetoothGattCharacteristic.PROPERTY_READ | gattCharacteristic.getProperties()) & 0) {
// READ set one
uuid = gattCharacteristic.getUuid().toString();;
if ((BluetoothGattCharacteristic.PROPERTY_WRITE & gattCharacteristic.getProperties()) & 0) {
// write set one
uuid = gattCharacteristic.getUuid().toString();
currentCharaData.put(LIST_UUID, uuid);
gattCharacteristicGroupData.add(currentCharaData);
mGattCharacteristics.add(charas);
gattCharacteristicData.add(gattCharacteristicGroupData);
setCharacteristicNotification();
获取到所有的服务UUID与特征UUID。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1239次
排名:千里之外一:BLE相关概念概述
1:相关概念
Generic Attribute Profile (GATT)
通过BLE连接,读写属性类小数据的Profile通用规范。现在所有的BLE应用Profile都是基于GATT的。
Attribute Protocol (ATT)
GATT是基于ATT Protocol的。ATT针对BLE设备做了专门的优化,具体就是在传输过程中使用尽量少的数据。每个属性都有一个唯一的UUID,属性将以characteristics and services的形式传输。
Characteristic
Characteristic可以理解为一个数据类型,它包括一个value和0至多个对次value的描述(Descriptor)。
Descriptor
对Characteristic的描述,例如范围、计量单位等。
Characteristic的集合。例如一个service叫做“Heart Rate Monitor”,它可能包含多个Characteristics,其中可能包含一个叫做“heart rate measurement&的Characteristic。
2:相关原理图
周围设备模型:
二:应用层框架层重要内容介绍
周围设备中的介绍:
BluetoothManager.java
BluetoothAdapter.java
BluetoothGattServer.java
BluetoothGatt.java
BluetoothGattService.java
BluetoothGattCharacteristic.java
BluetoothGattDescriptor.java
上述类位于frameworks/base/core/java/src/android/bluetooth/
BluetoothLeAdvertiser.java
AdvertiseSettings.java
上面的类设置Advertise时候的参数,构造方法私有,需要通过公开的Builder类来构造这个类的实例
AdvertiseData.java
上面的类设置Advertise时候的相关数据,构造方法私有,需要通过公开的Builder类来构造这个类的实例
上述类位于frameworks/base/core/java/src/android/bluetooth/le
2重要的方法
public BluetoothGattServer openGattServer(
Context context,BluetoothGattServerCallback callback)
获取GattServer实例
BluetoothGattService的构造方法
public BluetoothGattService(UUID uuid, int serviceType)
serviceType服务类型可以有BluetoothGattService.SERVICE_TYPE_PRIMARY和
BluetoothGattService.SERVICE_TYPE_SECONDARY
BluetoothGattCharacteristic的构造方法参数介绍
public BluetoothGattCharacteristic(UUID uuid, int properties, int permissions)
uuid Characteristic的唯一标识符
properties Characteristic的属性详细数据见BluetoothGattCharacteristic类开头
permissions Characteristic所支持的权限比如可读可写0x11同样在类开头有英文介绍
BluetoothGattDescriptor的构造方法参数介绍
public BluetoothGattDescriptor(UUID uuid, int permissions)
同Characteristic在类的开头也有英文介绍。
public void startAdvertising(AdvertiseSettings settings,
AdvertiseData advertiseData, final AdvertiseCallback callback)
发送让中心设备获取自己信息的方法
BluetoothGattServerCallback中的相关方法的介绍:
方法都是异步的方法,因此在回调中不要写大量的工作
public void onConnectionStateChange(BluetoothDevice device, int status,
int newState)
当连接状态发生变化的时候的回调,比如连接和断开的时候都会回调
device 产生回调的远端设备引用
status 回调的时候的状态信息
newState 进入的新的状态的信息
public void onServiceAdded(int status, BluetoothGattService service) {
当服务添加到Server中时的回调
status 添加服务的状态信息,成功还是失败
service 添加的服务的引用
public void onCharacteristicReadRequest(BluetoothDevice device, int requestId,int offset, BluetoothGattCharacteristic characteristic)
当有服务请求读 characteristic的时候
device发请求的远端设备引用
requestId 请求Id
offset 偏移量
characteristic被请求的 characteristic
public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded,int offset, byte[] value)
characteristic 需要写的 characteristic
preparedWrite 是不是需要保存到队列之后执行写入操作的
responseNeeded 需不需要返回数据的
value 需要写的数据
public void onDescriptorReadRequest(BluetoothDevice device,int requestId, int offset, BluetoothGattDescriptor descriptor)
类似characteristic的读
public void onDescriptorWriteRequest(BluetoothDevice device,int requestId, BluetoothGattDescriptor descriptor,boolean preparedWrite, boolean responseNeeded, int offset,byte[] value)
类似characteristic的写
public void onExecuteWrite(BluetoothDevice device, int requestId,boolean execute)
执行将保存到队列中的数据写入到characteristic的回调
public void onNotificationSent(BluetoothDevice device, int status)
会回调当有服务端的数据传送到客户端的时候
BluetoothGattServer中一些方法的说明
public boolean connect(BluetoothDevice device, boolean autoConnect)
连接远端蓝牙设备
public void cancelConnection(BluetoothDevice device)
断开和远端设备的连接
public boolean sendResponse(BluetoothDevice device, int requestId,int status, int offset, byte[] value)
当远端设备需要读或者写的时候,本读需要发送一个回应
public boolean notifyCharacteristicChanged(BluetoothDevice device,BluetoothGattCharacteristic characteristic, boolean confirm)
设置提醒Characteristic改变的提醒,同时可以设置Characteristic,会产生远端设备的某个回调
客户端中某些方法介绍
BluetoothAdapter中的方法
由于扫描设备是能源集中型的方法需要谨慎使用适时的停止。
public boolean startLeScan(LeScanCallback callback)
开始扫描设备
public void stopLeScan(LeScanCallback callback)
停止扫描设备
BluetoothDevice中的方法
public BluetoothGatt connectGatt(Context context, boolean autoConnect,BluetoothGattCallback callback)
连接周围设备,返回BluetoothGatt对象
BluetoothGatt中的方法
public void disconnect()
用完了之后需要断开连接
public boolean discoverServices()
发现服务的请求
public List&BluetoothGattService& getServices()
获取当前连接的周围设备上的服务的请求
public boolean readCharacteristic(BluetoothGattCharacteristic characteristic)
发起对某个 characteristic的读请求
public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic)
发起对某个characteristic的写请求
public boolean readDescriptor(BluetoothGattDescriptor descriptor)
类似characteristic
public boolean writeDescriptor(BluetoothGattDescriptor descriptor)
类似characteristic
public boolean beginReliableWrite()
开始可靠的characteristic写的请求,所有characteristic的写请求都会保存在gattServer中的队列中,直到有executeReliableWrite()执行,中途可以检验某个之是不是已经正确写入,同时可以调用public void abortReliableWrite()来终止这次可靠写characteristic请求,所有从开始的数据都不会写入到characteristic中
public boolean executeReliableWrite()
执行可靠写数据的请求
public void abortReliableWrite()
放弃可靠写请求
public boolean readRemoteRssi()
读取当前的Rssi的值
public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic,boolean enable)
发起对某个characteristic改变的提醒, 通过enable参数来设置开启和关闭
BluetoothGattCallback中的某些方法的介绍与ServerCallback类似是异步的所以需要注意
public void onConnectionStateChange(BluetoothGatt gatt, int status,int newState)
请求连接之后的回调, status返回的状态成功与否, newState提示新的状态
public void onServicesDiscovered(BluetoothGatt gatt, int status)
服务发现之后的回调
public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status)
请求 characteristic读之后的回调
public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status)
请求characteristic写之后的回调
public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic)
characteristic属性改变之后的回调
public void onDescriptorRead(BluetoothGatt gatt,BluetoothGattDescriptor descriptor, int status)
类似characteristic
public void onDescriptorWrite(BluetoothGatt gatt,BluetoothGattDescriptor descriptor, int status)
类似characteristic
public void onReliableWriteCompleted(BluetoothGatt gatt, int status)
可靠写完成之后的回调
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status)
读远端Rssi请求之后的回调
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status)
请求MTU改变之后的回调
3重要的接口
BluetoothAdapter.LeScanCallback
当有搜索结果的时候回调
4重要的抽象类
BluetoothGattServerCallback.java
上面的回调类服务的回调都写在这个抽象类中,需要扩展下,实现更加具体的逻辑。
BluetoothGattCallback.java
上面的回调类的回调是中心设备的具体回调,需要扩展下,实现更加具体的逻辑。
位于frameworks/base/core/java/src/android/bluetooth/
AdvertiseCallback
上面的回调类发送自身信息完成后的回调,会返回发送的结果和实际发送的信息
位于frameworks/base/core/java/src/android/bluetooth/le
三:实现例子
周围端的实现的例子:
步骤一:获取BluetoothGattServer的实例
例子如下:
mBluetoothManager=(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
gattServer = mBluetoothManager.openGattServer(this, mCallback);
步骤二:添加gattServer中的service,characteristic和descriptor
例子如下:
gattService = new BluetoothGattService(SERVICE_UUID,BluetoothGattService.SERVICE_TYPE_PRIMARY);
BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(CHARACTERISTIC_UUID, 0x0A, 0x11);
BluetoothGattDescriptor descriptor = new BluetoothGattDescriptor(DESCRIPTOR_UUID, 0x11);
descriptor.setValue(&gdd test&.getBytes());
characteristic.addDescriptor(descriptor);
characteristic.setValue(&the characteristic&.getBytes());
BluetoothGattCharacteristic characteristicUpdating = new BluetoothGattCharacteristic(CHARACTERISTIC_UUID_UPDATING, 0x0A, 0x11);
gattService.addCharacteristic(characteristic);
gattService.addCharacteristic(characteristicUpdating);
gattServer.addService(gattService);
步骤三:实现mCallback的功能
需要具体化的方法罗列如下:
public void onConnectionStateChange(BluetoothDevice device, int status,
int newState) {
public void onServiceAdded(int status, BluetoothGattService service) {
public void onCharacteristicReadRequest(BluetoothDevice device, int requestId,
int offset, BluetoothGattCharacteristic characteristic) {
public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,
BluetoothGattCharacteristic characteristic,
boolean preparedWrite, boolean responseNeeded,
int offset, byte[] value) {
public void onDescriptorWriteRequest(BluetoothDevice device, int requestId,
BluetoothGattDescriptor descriptor,
boolean preparedWrite, boolean responseNeeded,
int offset,& byte[] value) {
public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
public void onNotificationSent(BluetoothDevice device, int status) {
步骤四:让中心设备可以发现我们的设备
例子如下:
adapter = mBluetoothManager.getAdapter();
leAdvertiser = adapter.getBluetoothLeAdvertiser();
leAdvertiser.startAdvertising(
new AdvertiseSettings.Builder().build(),
new AdvertiseData.Builder()
.addServiceUuid(new ParcelUuid(SERVICE_UUID))
.addManufacturerData(1, &1&.getBytes())
.setIncludeDeviceName(true)
.addServiceData(new ParcelUuid(SERVICE_UUID),
&1&.getBytes()).build(),
new AdvertiseCallback() {
public void onStartSuccess(
AdvertiseSettings settingsInEffect) {
Log.d(TAG,
&AdvertiseCallbackImpl-&onStartSuccess is being invoked!!!&);
Log.d(TAG, &SETTING MODE:& + settingsInEffect.getMode());
Log.d(TAG,
&SETTING TIMEOUT:&
+ settingsInEffect.getTimeout());
Log.d(TAG,
&SETTING TxPowerLevel:&
+ settingsInEffect.getTxPowerLevel());
public void onStartFailure(int errorCode) {
Log.d(TAG,
&AdvertiseCallbackImpl-&onStartFailure is being invoked!!!&);
Log.d(TAG, &errorCode is :& + errorCode);
到此gattServer的设置完成,开始等待中心设备连接
中心设备的实例的例子:
步骤一:搜索到周围设备
例子如下:
开始搜索的代码入下:
private void startScanning() {
Log.d(TAG, &startScanning&);
mLeDeviceListAdapter.clear();
mLeDeviceListAdapter.notifyDataSetChanged();
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
public void run() {
isScanning =
mBluetoothAdapter.stopLeScan(mLeScanCallback);
invalidateOptionsMenu();
}, SCAN_PERIOD);
isScanning =
mBluetoothAdapter.startLeScan(mLeScanCallback);
invalidateOptionsMenu();
mLeScanCallback 的代码如下:
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
Log.d(&gdd debug&, device.getAddress() + && rssi:& + rssi
+ &scanRecord:& + scanRecord.toString());
runOnUiThread(new Runnable() {
public void run() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
步骤二:通过回调来的设备信息,进行连接周围设备
例子如下:
private boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG, &BluetoothAdapter not initialized or unspecified address.&);
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.w(TAG, &Device not found.& Unable to connect.&);
// We want to directly connect to the device, so we are setting the autoConnect
// parameter to false.
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
showLOG(&Connecting to & + address);
Log.d(TAG, &Trying to create a new connection.&);
步骤三:通过的mBluetoothGatt 请求方法异步调用mGattCallback中的回调
通过以上代码大致可以写出周围设备和中心设备实现gatt通讯的例子
四 : 总结和展望
总结本次BLE设备通讯的学习:
在这次学习中深入了关于TL给出的要求,然后对蓝牙GATT PROFILE 的认识更加深入,但是仅仅还只是在java代码的层面上对这些内容进行了总结,并没有对GattServic中相关内容做分析,需要继续学习,可能还需要对JNI部分的代码进行一定的分析,所以还需要深入对GATT 通讯过程中的流程做更进一步的分析。
关于对网上一些说法的看法,首先是关于对蓝牙通讯的安全性问题的分析,由于蓝牙服务和数据获取UUID的方便性,就目前代码貌似是无法完成安全要求的。因此,我觉得这一问题,可能会成为一个比较重要的问题。
然后是关于和其他的平台的对比的问题
Zigbee的自组网技术也可以实现和蓝牙类似的功能,并且是一个强有力的竞争对手。但是鉴于蓝牙的低功耗,还是有一定的优势的。
wifi mesh也可以实现室内定位等功能。
基于这次学习做展望:
对于蓝牙,前段时间有智能穿戴设备搞的风风火火,现在蓝牙用到智能家庭中的想法也是可以预想的。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:38447次
积分:1975
积分:1975
排名:第15855名
原创:149篇
转载:69篇问题:安卓蓝牙40连接成功后,discoverServices后没有进入回调函数
我的程序,连接成功之后,进行mBluetoothGatt.discoverServices(),但是却没有进入回调函数。
以下是调试结果:
显示discoverServices已经开始了,之后就停住了,没有进入回调函数。这是为什么,怎么解决?
相关代码:
连接,discovService部分://&由扫描后传过来的地址,调用getRemoteDevice方法获取代表远程的蓝牙BluetoothDevice&&&&&
&&&&&&&&&&&&&tagetbluetooth&=&mybluetooth.getRemoteDevice(address);
&&&&&&&&&&&&&//获取BluetoothGatt
&&&&&&&&&&&&&mBluetoothGatt&=&tagetbluetooth.connectGatt(this,&false,&mGattCallback);
&&&&&&&&&&&&&//调用BluetoothGatt的连接方法connect()
&&&&&&&&&&&&&if(mBluetoothGatt.connect()){
&&&&&&&&&&&& &Toast.makeText(this,&"连接成功",Toast.LENGTH_LONG).show();
&&&&&&&&&&&& &c />
&&&&&&&&&&&& &//连接成功后,再进行discoverServices()
&&&&&&&&&&&& &//并在其回调函数中执行getService(),获得BluetoothGattService
&&&&&&&&&&&& &if(mBluetoothGatt.discoverServices()){
&&&&&&&&&&&&
&Log.i(TAG,&"discoverServices已经开始了");
&&&&&&&&&&&& &}else{
&&&&&&&&&&&&
&Log.i(TAG,&"discoverServices没有开始");
&&&&&&&&&&&& &}
&&&&&&&&&&&&&}
&&&&&&&&&&&&&else{
&&&&&&&&&&&& &Toast.makeText(this,&"未连接成功,请再尝试",&Toast.LENGTH_LONG).show();
&&&&&&&&&&&& &c />
&&&&&&&&&&&&&}
回调函数部分:@Override
&&&&&&&&public&void&onServicesDiscovered(BluetoothGatt&gatt,&int&status)&{
&&&&&&&&&&&&//discoverServices()函数的回调函数
&&&&&&&& if&(status&==&BluetoothGatt.GATT_SUCCESS)&{
Log.i(TAG,&"discoverServices完成");
//&&&&&&&&&&&&&&&&Toast.makeText(MainActivity.this,&"discover成功",&Toast.LENGTH_LONG).show();
//discover成功,进行getService,获得mBluetoothGattService
mBluetoothGattService=gatt.getService(UUID.fromString(MY_SERVICE_UUID));
//还需要进行判断是否为null
if(mBluetoothGattService==null)
Log.i(TAG,&"getService未成功");
Log.i(TAG,&"getService成功");
//再通过mBluetoothGattService获得BluetoothGattCharacteri
mBluetoothGattCharacteristic=
mBluetoothGattService.getCharacteristic(UUID.fromString(MY_CHAR1_UUID));
//还需要在进行判断是否为null
if(mBluetoothGattCharacteristic==null)
Log.i(TAG,&"getCharacteristic未成功");
Log.i(TAG,&"getCharacteristic成功");
&&&&&&&&&&&&}&else&{
&&&&&&&&&&&& Log.i(TAG,&"discoverServices未完成");
//&&&&&&&&&&&& Toast.makeText(MainActivity.this,&"discover不成功,请再尝试",&Toast.LENGTH_LONG).show();
&&&&&&&&&&&& //这里还需要添加差错控制
&&&&&&&&&&&&}
以上介绍了“安卓蓝牙40连接成功后,discoverServices后没有进入回调函数”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:/itwd/686264.html
上一篇: 下一篇:

我要回帖

更多关于 i have discovered 的文章

 

随机推荐