段时间,公司项目用到了手机APP和蓝牙设备的通讯开发,这里也正好对低功耗蓝牙(蓝牙4.0及以后标准)的开发,做一个总结。

蓝牙技术联盟在2010年6月30号公布了蓝牙4.0标准,4.0标准在蓝牙3.0+HS标准的基础上增加了对低功耗蓝牙(BLE)的支持。相比原有的普通蓝牙和高速蓝牙,BLE最大的特点就是低功耗,低延时,快速的搜索和连接速度,但数据传输速度相比传统蓝牙低。接下去将从BLE的概念以及代码两个方面介绍Android下的BLE。

先来说说基本概念:

1.BLE相关概念

1.1 GATT、Service、Characteristic、Descriptor

BLE开发,经常会与四个概念发生关系:GATT、Service、Characteristic、Descriptor

  • GATT:是蓝牙4.0特有的Profile通用规范,BLE应用的Profile均基于GATT。Gatt定义了一个服务框架规范,该框架包括对蓝牙服务(Service)和服务特性(Characteristic)的定义和规范,和其中读写、通知的特性等。可以将GATT理解成BLE框架,我们在GATT上面实现BLE功能。
  • Service:是完成一个特定功能的数据和行为集合。在Gatt中,一个Service可能包含Service引用以及强制或者可选的Characteristic。
  • Characteristic:也叫特征值,一个Characteristic的定义包含了Characteristic本身,数值以及描述(Descriptor)的声明。Characteristic是完成BLE具体功能的基本单位。
  • Descriptor:Descriptor定义了Characteristic中数据的具体含义。

  总的来说,一个蓝牙4.0的终端可以包含多个Service,一个Service可以包含多个Characteristic,一个Characteristic包含一个Value和多个Descriptor,一个Descriptor包含一个Value

 

1.2 中央(Central)与周边(Periphery)

在BLE协议中,有两个角色,周边(Periphery)和中央(Central):

周边是数据提供者,中央是数据使用/处理者;在iOS SDK里面,可以把一个iOS设备作为一个周边,也可以作为一个中央;但是在Android SDK里面,Android手机只能作为中央来使用和处理数据;那数据从哪儿来?从BLE设备来,现在的很多可穿戴设备都是用BLE来提供数据的。

一个中央可以同时连接多个周边,但是一个周边某一时刻只能连接一个中央。

那么问题来了,如何定义周边和中央?

关于周边和中央,涉及到四个类:

  • BluetoothGattServer:作为周边来提供数据
  • BluetoothGattServerCallback:返回周边的状态
  • BluetoothGatt:作为中央来使用和处理数据
  • BluetoothGattCallback:返回中央的状态和周边提供的数据。、

关系如图下:

2. 开发Ble

了解了那些基础概念后,我们就正式开始开发ble。

Ble的Android开发,主要是以下的几个步骤:

1、添加权限

2、扫描Ble设备

3、连接Ble设备

4、数据通讯

那么现在,开始一步步来完成。

2.1 添加权限:

在AndroidManifest.xml中添加Ble需要的权限,其实就两个:

<!-- 应用使用蓝牙的权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 扫描蓝牙设备或者操作蓝牙设置 -->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

2.2 检查是否设备是否支持蓝牙,并打开蓝牙

检查设备是否支持蓝牙

     /**
* 检查该设备是否支持蓝牙
*/
public void isBle(Context context) {
//手机硬件支持蓝牙
if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
ViewUtils.getInstance().showToast("该设备不支持BLE,即将离开改页面");
}
}

打开手机蓝牙开关

    private BluetoothAdapter mBluetoothAdapter;//蓝牙适配器

    //打开蓝牙权限
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, What.Bluetooth.bluetoothEnable);
}

2.3 扫描设备

开始扫描和停止扫描,只需要调用对应的startLeScan()和stopLeScan()即可,但是需要将LeScanCallBack作为参数:

    // 超时时间
private static final long SCAN_PERIOD = 10000;
...
private void scanLeDevice(final boolean enable) {
if (enable) {
// 达到超时时间,停止扫描
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
//开始扫描
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
//停止扫描
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
...
}

LeScanCallBack的实现:

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() {
// TODO: 2017/9/18
}
});
}
};

上面的代码中:

  • SCAN_PERIOD:扫描时长,毫秒数,需要注意的是,蓝牙设备扫描很耗电,这个时间不易设置太长,在扫描成功后就要停止设备扫描。
  • BluetoothDevice:蓝牙设备的相关类,通过他,可以获取蓝牙设备的很多信息

如果只想扫描指定类型的外围设备,你可以调用startLeScan(UUID[], BluetoothAdapter.LeScanCallback),提供一个指定了你app支持的GATT服务的UUID数组对象。

2.3 连接GATT服务端

与BLE设备通讯的前提就是连接GATT服务端,GATT概念之前已经讲过了,调用connectGatt()就可以了,不过需要三个参数:这个方法需要三个参数,一个Context对象,autoConnect(一个指示是否自动连接到BLE设备--当它一旦可用的时候--的布尔值),和一个 BluetoothGattCallback的引用:

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

这个方法会返回一个BluetoothGatt,用它可以对GATT进行操作。

具体怎么操作呢?下篇博客再说。


这是我的个人微信公众号:感兴趣的可以关注一下,里面分享一些搞机视频,程序员嘛!学会骚,很重要:

Android低功耗蓝牙(蓝牙4.0)——BLE开发(上)的更多相关文章

  1. 蓝牙4.0 BLE 开发

    在BLE开发中的一些随记,供大家参考: 凡事皆有状态 低功耗蓝牙背后有个基本的概念:任何事务都有状态.状态可以是任何东西:当前的温度,设备里电池的状态,设备名称或者对测量温度的地点的描述.它通过属性服 ...

  2. 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体解释

    转载请注明来源: http://blog.csdn.net/kjunchen/article/details/50909410 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体 ...

  3. 蓝牙4.0——Android BLE开发官方文档翻译

    ble4.0开发整理资料_百度文库 http://wenku.baidu.com/link?url=ZYix8_obOT37JUQyFv-t9Y0Sv7SPCIfmc5QwjW-aifxA8WJ4iW ...

  4. 【转】蓝牙4.0——Android BLE开发官方文档翻译

    原文网址:http://ricardoli.com/2014/07/31/%E8%93%9D%E7%89%9940%E2%80%94%E2%80%94android-ble%E5%BC%80%E5%8 ...

  5. 【原创】Android 5.0 BLE低功耗蓝牙从设备应用

    如果各位觉得有用,转载+个出处. 现如今安卓的低功耗蓝牙应用十分普遍了,智能手环.手表遍地都是,基本都是利用BLE通信来交互数据.BLE基本在安卓.IOS两大终端设备上都有很好支持,所以有很好发展前景 ...

  6. Android蓝牙BLE开发,扫描、连接、发送和读取信息;

    1.BLE开发权限 Android蓝牙BLE开发须打开蓝牙权限和6.0位置权限: <uses-permission android:name="android.permission.B ...

  7. Android 蓝牙 BLE 开发笔记

    最近公司头戴换了一块蓝牙4.0 BLE模块,所以我们Android组要适配 BLE.Android BLE 需要 4.3 以上系统,api 还是非常简单的, 第一步就是扫描, 扫描到设备后就可以连接了 ...

  8. 【转】Android低功耗蓝牙应用开发获取的服务UUID

    原文网址:http://blog.csdn.net/zhangjs0322/article/details/39048939 Android低功耗蓝牙应用程序开始时获取到的蓝牙血压计所有服务的UUID ...

  9. Android低功耗蓝牙(BLE)使用详解

    代码地址如下:http://www.demodashi.com/demo/13390.html 与普通蓝牙相比,低功耗蓝牙显著降低了能量消耗,允许Android应用程序与具有更严格电源要求的BLE设备 ...

随机推荐

  1. Java 学习之路 -- day00

    Java 学习之路 -- day00 Typora 快捷键操作 标题:#+空格 2. *斜体* 3. **加粗** 4. **斜体加粗*** 5. ~~删除线~~ 6. > 引用 7. ···分 ...

  2. chrome标签记录——关于各类性能优化

    概述 详情 概述 平时经常浏览各大博客,总感觉要学习和需要学习的内容太多太多,而自己的个人能力还不足够写出一些好的文章出来,就只能通过学习他人的东西不断提升自己的实力,然后就会记录收藏各种优秀的博客资 ...

  3. linux yum rpm 和 apt-get dpkg 安装、卸载软件

      一般来说著名的linux系统基本上分两大类:   1.RedHat系列:Redhat.Centos.Fedora等   2.Debian系列:Debian.Ubuntu等   RedHat 系列  ...

  4. php之魔术方法 __set(),__get(),__isset(),__unset()

    __set()与__get() 当一个类里面,属性被设置为私有属性时,这个属性是不能在外部被访问的.那么当我们又想在外部访问时该怎么办呢,我们可以用方法来实现.举例如下: 1 class Test 2 ...

  5. WPF 之 INotifyPropertyChanged 接口的使用 (一)

    一.INotifyPropertyChanged 的基本概念 ​ INotifyPropertyChanged 的作用:通知客户端属性值已经更改.详细信息见:INotifyPropertyChange ...

  6. Pytest(7)自定义用例顺序pytest-ordering

    前言 测试用例在设计的时候,我们一般要求不要有先后顺序,用例是可以打乱了执行的,这样才能达到测试的效果. 有些同学在写用例的时候,用例写了先后顺序, 有先后顺序后,后面还会有新的问题(如:上个用例返回 ...

  7. Inceptor查询语句

    -- MySQL中的语句都能用,不再一一描述,只记录一些不同 详情见Inceptor 6.0文档 3.4.4查询语句这节 -- 查询语句 SELECT开头,可以通过添加多种从句从Inceptor中的表 ...

  8. The Department of Redundancy Department

    Write a program that will remove all duplicates from a sequence of integers and print the list of un ...

  9. HDU-6703 array (线段树)

    题意 一个长度为n的排列a,\(\forall i\in [1,n] ,1\le a_i \le n\) , m次操作,每次操作: (1,pos),把 \(a_{pos}\) 变为\(a_{pos} ...

  10. 【noi 2.6_1808】最长公共子序列(DP)

    题意:给2个字符串求其最大公共子序列的长度.解法:这个和一般的状态定义有点不一样,f[i][j]表示 str 前i位和 str2 前j的最大公共子序列的长度,而不是选 str 的第i位和 str2 的 ...