作者:Bgwan
链接:https://zhuanlan.zhihu.com/p/23679793
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

置顶:此文转载CSDN博客文章,原文地址:http://blog.csdn.net/poltroon/article/details/36652481

一、关键概念:

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的描述,例如范围、计量单位等。

Service

Characteristic的集合。例如一个service叫做“Heart Rate Monitor”,它可能包含多个Characteristics,其中可能包含一个叫做“heart rate measurement"的Characteristic。

二、角色和职责:

Android设备与BLE设备交互有两组角色:

中心设备和外围设备(Central vs. peripheral);

GATT server vs. GATT client.

Central vs. peripheral:

中心设备和外围设备的概念针对的是BLE连接本身。Central角色负责scan advertisement。而peripheral角色负责make advertisement。

GATT server vs. GATT client:

这两种角色取决于BLE连接成功后,两个设备间通信的方式。

举例说明:

现有一个活动追踪的BLE设备和一个支持BLE的Android设备。Android设备支持Central角色,而BLE设备支持peripheral角色。创建一个BLE连接需要这两个角色都存在,都仅支持Central角色或者都仅支持peripheral角色则无法建立连接。

当连接建立后,它们之间就需要传输GATT数据。谁做server,谁做client,则取决于具体数据传输的情况。例如,如果活动追踪的BLE设备需要向Android设备传输sensor数据,则活动追踪器自然成为了server端;而如果活动追踪器需要从Android设备获取更新信息,则Android设备作为server端可能更合适。

三、权限及feature:

和经典蓝牙一样,应用使用蓝牙,需要声明BLUETOOTH权限,如果需要扫描设备或者操作蓝牙设置,则还需要BLUETOOTH_ADMIN权限:

<uses-permission android:name="android.permission.BLUETOOTH"/>

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

除了蓝牙权限外,如果需要BLE feature则还需要声明uses-feature:

<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

按时required为true时,则应用只能在支持BLE的Android设备上安装运行;required为false时,Android设备均可正常安装运行,需要在代码运行时判断设备是否支持BLE feature:

// 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();

}

四、启动蓝牙:

在使用蓝牙BLE之前,需要确认Android设备是否支持BLE feature(required为false时),另外要需要确认蓝牙是否打开。

如果发现不支持BLE,则不能使用BLE相关的功能。如果支持BLE,但是蓝牙没打开,则需要打开蓝牙。

打开蓝牙的步骤:

1、获取BluetoothAdapter

BluetoothAdapter是Android系统中所有蓝牙操作都需要的,它对应本地Android设备的蓝牙模块,在整个系统中BluetoothAdapter是单例的。当你获取到它的示例之后,就能进行相关的蓝牙操作了。

获取BluetoothAdapter代码示例如下:

// Initializes Bluetooth adapter.

final BluetoothManager bluetoothManager =

(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

mBluetoothAdapter = bluetoothManager.getAdapter();

注:这里通过getSystemService获取BluetoothManager,再通过BluetoothManager获取BluetoothAdapter。BluetoothManager在Android4.3以上支持(API level 18)。

2、判断是否支持蓝牙,并打开蓝牙

获取到BluetoothAdapter之后,还需要判断是否支持蓝牙,以及蓝牙是否打开。

如果没打开,需要让用户打开蓝牙:

private BluetoothAdapter mBluetoothAdapter;

...

// Ensures Bluetooth is available on the device and it is enabled. If not,

// displays a dialog requesting user permission to enable Bluetooth.

if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {

Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

}

五、搜索BLE设备:

通过调用BluetoothAdapter的startLeScan()搜索BLE设备。调用此方法时需要传入BluetoothAdapter.LeScanCallback参数。

因此你需要实现 BluetoothAdapter.LeScanCallback接口,BLE设备的搜索结果将通过这个callback返回。

由于搜索需要尽量减少功耗,因此在实际使用时需要注意:

1、当找到对应的设备后,立即停止扫描;

2、不要循环搜索设备,为每次搜索设置适合的时间限制。避免设备不在可用范围的时候持续不停扫描,消耗电量。

搜索的示例代码如下:

/**

* Activity for scanning and displaying available BLE devices.

*/

public class DeviceScanActivity extends ListActivity {

private BluetoothAdapter mBluetoothAdapter;

private boolean mScanning;

private Handler mHandler;

// Stops scanning after 10 seconds.

private static final long SCAN_PERIOD = 10000;

...

private void scanLeDevice(final boolean enable) {

if (enable) {

// Stops scanning after a pre-defined scan period.

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);

}

...

}

...

}

如果你只需要搜索指定UUID的外设,你可以调用 startLeScan(UUID[], BluetoothAdapter.LeScanCallback)方法。

其中UUID数组指定你的应用程序所支持的GATT Services的UUID。

BluetoothAdapter.LeScanCallback的实现示例如下:

private LeDeviceListAdapter mLeDeviceListAdapter;

...

// Device scan callback.

private 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();

}

});

}

};

注意:搜索时,你只能搜索传统蓝牙设备或者BLE设备,两者完全独立,不可同时被搜索。

六、连接GATT Server:

两个设备通过BLE通信,首先需要建立GATT连接。这里我们讲的是Android设备作为client端,连接GATT Server。

连接GATT Server,你需要调用BluetoothDevice的connectGatt()方法。此函数带三个参数:Context、autoConnect(boolean)和BluetoothGattCallback对象。调用示例:

mBluetoothGatt = device.connectGatt(this, false, mGattCallback);

函数成功,返回BluetoothGatt对象,它是GATT profile的封装。通过这个对象,我们就能进行GATT Client端的相关操作。BluetoothGattCallback用于传递一些连接状态及结果。

BluetoothGatt常规用到的几个操作示例:

connect() :连接远程设备。

discoverServices() : 搜索连接设备所支持的service。

disconnect():断开与远程设备的GATT连接。

close():关闭GATT Client端。

readCharacteristic(characteristic) :读取指定的characteristic。

setCharacteristicNotification(characteristic, enabled) :设置当指定characteristic值变化时,发出通知。

getServices() :获取远程设备所支持的services。

等等。

注:

1、某些函数调用之间存在先后关系。例如首先需要connect上才能discoverServices。

2、一些函数调用是异步的,需要得到的值不会立即返回,而会在BluetoothGattCallback的回调函数中返回。例如discoverServices与onServicesDiscovered回调,readCharacteristic与onCharacteristicRead回调,setCharacteristicNotification与onCharacteristicChanged回调等。

Android5.0(Lollipop) BLE蓝牙4.0+浅析概念(四)的更多相关文章

  1. Android5.0(Lollipop) BLE蓝牙4.0+浅析demo连接(三)

    作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23363591来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...

  2. Android5.0(Lollipop) BLE蓝牙4.0+浅析code(二)

    作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23347612来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Android5.0(L ...

  3. android5.0 BLE 蓝牙4.0+浅析demo搜索(一)

    作者:Bgwan链接:https://zhuanlan.zhihu.com/p/23341414来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者:Bgwan 莳萝花 ...

  4. Android ble 蓝牙4.0 总结

    本文介绍Android ble 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用,如果手机系统版本API level < 18,也是用不了蓝牙4.0的哦 ...

  5. Android ble 蓝牙4.0 总结一

    本文介绍Android ble 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用,如果手机系统版本API level < 18,也是用不了蓝牙4.0的哦 ...

  6. IOS BLE蓝牙4.0

    前言: 自己做的项目里面有这么一个功能,总结归纳一下. 先导入必要的框架  CoreBluetooth.framework 在要用到蓝牙的文件里面导入以下头文件 #import <CoreBlu ...

  7. android5.0(Lollipop) BLE Peripheral牛刀小试

    转载请表明作者:http://blog.csdn.net/lansefeiyang08/article/details/46468743 知道Android L对蓝牙对了一些改进.包含加入A2dp s ...

  8. android5.0(Lollipop) BLE Central牛刀小试

    转载请表明作者:http://blog.csdn.net/lansefeiyang08/article/details/46482073 昨天写了android L BLE Peripheral的简单 ...

  9. android5.0(Lollipop) BLE Peripheral深入理解系统篇之提高篇

    上一篇文章讲到了广播之前系统需要进行的准备工作,那接下来我们就来真正的启动广播. 首先还是先看一下上一篇文章结束的地方: @Override public void onClientRegistere ...

随机推荐

  1. Autoencoders and Sparsity(二)

    In this problem set, you will implement the sparse autoencoder algorithm, and show how it discovers ...

  2. Oracle 11g win7 64位【桌面类 && 服务器类】安装过程

    Oracle 11g  win7  64位[桌面类 && 服务器类]安装过程  一.首先,根据自己的操作系统位数(32位或64位),到官网下载相应的安装程序,如下图所示.       ...

  3. chkconfig---检查设置系统服务

    chkconfig命令   chkconfig命令检查.设置系统的各种服务.这是Red Hat公司遵循GPL规则所开发的程序,它可查询操作系统在每一个执行等级中会执行哪些系统服务,其中包括各类常驻服务 ...

  4. 从excel 获取内容 模块:xlrd

    import xlrd # 获取表的对象 excel = xlrd.open_workbook(‘a.excel’) # 获取所有excel里的所有表 table_list = excel.sheet ...

  5. chrome模拟手机功能

    在搭建好web側环境之后.能够使用chrome来模拟手机的功能 直接上图吧: 图1是直接模拟一个通用的界面 图2里面能够选择不同的手机型号,还是比較全的! 选择一个查看一下,和手机是一样的效果,非常赞 ...

  6. 旧知识打造新技术--AJAX学习总结

    AJAX是将旧知识在新思想的容器内进行碰撞产生的新技术:推翻传统网页的设计技术,改善用户体验的技术. 学习AJAX之初写过一篇<与Ajax的初次谋面>.当中都仅仅是一些自己浅显的理解.这次 ...

  7. mysql 表设计时的update_time自动更新

    11.3.5 Automatic Initialization and Updating for TIMESTAMP and DATETIME 原文地址:https://dev.mysql.com/d ...

  8. 错误 make: Nothing to be done for 'default'

    Makefile书写格式非常严格,all:<TAB缩进>make -C $(KDIR) M=$(PWD) $(EXTRA_CFLAGS) modulesdefault:<TAB缩进& ...

  9. 在Linux下用CANopenSocket协议模拟CAN总线通讯

    一.参考文档 https://github.com/CANopenNode/CANopenSocket //下载 CANopenSocket 的源码 http://elinux.org/Can-uti ...

  10. MySQL 5.7 多实例安装部署实例

    1. 背景  MySQL数据库的集中化运维,可以通过在一台服务器上,部署运行多个MySQL服务进程,通过不同的socket监听不同的服务端口来提供各自的服务.各个实例之间是相互独立的,每个实例的dat ...