Android之低功耗蓝牙的基本使用

作者简介  创微信公众号郭霖 WeChat ID: guolin_blog

早上好,五一放假回来的第二天,相信大家已经回到工作状态了吧,那么我们今天继续分享干货。

本篇来自Xanthuim的投稿,介绍了蓝牙常见的使用方式,并分享了自己的项目,希望对大家有所帮助。

Xanthuim的博客地址:

http://blog.csdn.net/qq_15003505

前言

最近在工作中使用到蓝牙的功能,当然我们这个蓝牙时跟蓝牙芯片结合使用的,而不是手机跟手机连接通信的。其实本质时差不多的,只是设备不一样罢了。在这里我不会贴出蓝牙那些协议等等复杂的名词解释,因为这个不是一两句话能解释的清楚,在我们先不太了解蓝牙的这些专业名词之前,我们先掌握它的基本使用就可以了,后续如果想深入了解的话,我们再花时间去学习。本文介绍的低功耗的蓝牙,是 Android 4.3 才开始支持的,而要使用传统蓝牙和高版本的蓝牙请参照官方文档,有中文介绍哦。

官方蓝牙文档

https://developer.android.google.cn/guide/topics/connectivity/bluetooth.html

官方不同版本蓝牙示例(有3个):

https://github.com/googlesamples?utf8=%E2%9C%93&q=bluetooth&type=&language=

蓝牙基本使用流程


从图上可以看出我这个例子只是单方面的通信,即手机只接收数据而不发送数据。

蓝牙关键类

BluetoothManager:蓝牙管理服务,如果对Android基本框架熟悉的话,你会发现蓝牙也属于最底层的驱动模块里,那么要使用蓝牙的东西就需要使用 (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE) 来获取了。不过看是把图贴一下。


BluetoothAdapter:表示本地设备蓝牙适配器。 BluetoothAdapter 允许您执行基本的蓝牙任务,例如启动设备发现,查询已绑定(配对)设备的列表,使用已知MAC地址实例化 BluetoothDevice,并创建一个 BluetoothServerSocket 以监听来自其他设备的连接请求,并启动扫描蓝牙LE设备。这个类时关键类,后面会大量使用到它。

BluetoothAdapter.LeScanCallback:用于提供LE扫描结果的回调界面。这个类就是扫描的回调接口,不过在 Android 5.0以上 使用抽象类 ScanCallback。

BluetoothLeScanner:该类提供了对蓝牙LE设备执行扫描相关操作的方法。应用程序可以使用 ScanFilter 扫描特定类型的蓝牙LE设备。它还可以请求不同类型的回调来传递结果。不过这个类是在 Android 5.0(API21)以上才出现的,也就是对于Android 4.3的以上我们只会使用 BluetoothAdapter 来进行扫描等操作,当然如果是5.0以上的可以使用这个类来代替的。

ScanCallback:蓝牙LE扫描回调,使用这些回调报告扫描结果。这个是抽象类与 BluetoothLeScanner 配套使用。

BluetoothDevice:表示远程蓝牙设备,BluetoothDevice 允许您创建与相应设备的连接或关于它的查询信息,例如名称,地址,类和绑定状态。

BluetoothProfile:配置文件代理。每个公共配置文件实现这个接口。它有几个直接子类,每个子类再不同场景中使用,如 BluetoothA2dp, BluetoothGatt, BluetoothGattServer, BluetoothHeadset, BluetoothHealth。在当前例子中使用到的是 BluetoothGatt。

BluetoothGatt:该类提供蓝牙GATT功能,以实现与蓝牙智能或智能就绪设备的通信。后续使用该类做连接、断开、关闭等操作。

BluetoothGattCallback:文档没有直接的解释,只说了被用在连接设备时候的回调。虽然文档没有详细说明,但是这个回调会在后续的连接、断开、通信中起到关键作用。

好了,主要的几个类介绍的差不多了。接下来我们使用这几个类练习一下。

1、获取蓝牙管理服务和适配器


获取了适配器后,我们可以通过适配器是否为null来判断是否支持蓝牙功能(想必现在的手机应该都支持吧)。另外适配器还提供了以下的方法:


上面的就是启用、关闭、扫描、停止的几个方法。需要注意的是在启用蓝牙的时候在不同手机会弹出启用对话框,比如魅族。那么这个时候你需要通过 isEnabled方法 来判断是否启用了,如果没有启用则使用 startActivity 来启用,然后通过 Activity 或者 Fragment 的 onActivityResult 回调方法来做余下的操作了。

startActivityForResult(newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE),REQUEST_ENABLE);

好了,使用上面的扫描方法就可以扫描到蓝牙设备了,是不是很简单啊。再说明一下,上面的 leScanCallback 就是上面提到的 BluetoothAdapter.LeScanCallback,你需要实现它就可以了。

2、权限配置

不过使用蓝牙也是要配置权限的,如果你没有在 Manifest 中配置,在 Android Studio 中使用上面的方法的时候它会报错要求你加入权限。我在这里列一下我使用到的权限:


是的,你会发现使用蓝牙还需要位置权限?我开始也觉得一个蓝牙也要位置权限,后来在翻看官方文档的时候才知道的,不然你在5.0以上的手机上扫不出蓝牙的!详情请翻阅官方文档:

https://developer.android.google.cn/guide/topics/connectivity/bluetooth-le.html#user-permission

3、连接设备

有了蓝牙设备后接下来我们连接下,然后发发数据看看。连接设备其实也很简单,就是通过扫描到的蓝牙设备对象来连接即可。蓝牙设备就是上面提到的 BluetoothDevice,这个类有一个方法:


第一个 Context 就不说了;第二个参数 autoConnect 的解释是“是否直接连接到远程设备(false)或一旦远程设备可用即可自动连接(true)”;第三个参数也是上面提到的抽象类,这个类在连接过程中起到关键作用。最后方法会返回一个 BluetoothGatt 对象,后续我们通过这个对象可以重连、断开、关闭设备。贴下我例子中的连接方法:


抽象类:



这个类里面有很多方法,不过都被这个类实现了,我们根据自己的情况来重写。解释下上面列出的方法:

onConnectionStateChange:监测蓝牙设备的连接、断开、读取设备信号强度值、发现服务(翻译的好别扭)。连接和断开可以通过 newState参数 来判断,注意是和 BluetoothProfile 的常量值来对比的,这个类也是上面提到过的。其实这个类提供了4个状态值,只不过在使用过程中只有 连接(状态值2)和 断开(状态值0),其他的没用到。


至于后面的读取设备信号强度值、发现服务这两个分别用在获取信号强度和通信的。怎么解释?要知道蓝牙也是无线传输的,既然是无线就跟移动网、WIFI一样都存在信号强弱的情况,那么通过这个就可以获取了。信号强度值是负数,负数越大信号越好(最大理论值是0),单位是dBm。而发现服务,我们在成功连接后调用 gatt.discoverServices() 方法既可以获取与连接的设备进行通信了,最后回调 onServicesDiscovered 方法。

onServicesDiscovered:这个方法里面我们需要做的就是使用蓝牙的 UUID 获取服务、特征、描述等对象,然后就可以给手机发送数据了。这里需要注意的是 UUID 不能随便写,而是设备厂商或者通用的 UUID,否则你是无法使用的。说到这个 UUID,其实我也比较迷惑的,很多文章在介绍 UUID 的时候都是一笔带过或者直接拿来用根本不解释这是干嘛的,而且也没找到一个比较全面介绍蓝牙协议等专业文档(谁找到了,麻烦给我留一个地址)。其实说到这,里面提到的特征、描述等对象,我也没详细去说请原谅。

onCharacteristicChanged:远程特性通知,回调触发。就是上面执行完后,只要连接的设备触发某些动作(比如我的蓝牙芯片按钮按下、抬起),这个方法就会被调用了。然后我们在这个方法中就可以获取远程设备发过来的信息。

好了,其实写到我这个例子基本的使用已经差不多了,剩下的无法就是蓝牙的断开、连接、关闭(释放资源)


最后,贴下我的例子截图以及我使用的蓝牙芯片,是不是感觉高大上啊,哈哈~




好了,我这个蓝牙芯片在连接之前的LED指示灯是一闪一闪的,而连接成功后就会常亮的。上图的3个按钮也是对应芯片的按键的。不够在这里说明一下,由于为了保密,我这里不会放出与蓝牙芯片的例子,而是单独写了一个简单的例子,不过底层的东西是不变的。另外这个是单方面的通信交互,如何做到双向通信呢?由于本例子只需要单向通信,所以就没涉及到,不够也是上面的例子的范畴,大家可以自己去研究下。另外说明下官方提供的低功耗的例子在使用“发现服务”的那个回调方法存在问题(连接了接收不到数据),我这里跟官方的例子还是不一样的。

另外说明下,我的 Android Studio 版本是2.4 preview 3版本,对应的 gradle 版本是 gradle-3.4.1-all,所有低版本的自行修改配置。

GitHub地址:

https://github.com/Xanthuim/BluetoothSample


文章原创作者GuoLin 书籍推荐

郭林大神原创android 书籍:《第一行代码 android》

淘宝链接: https://s.click.taobao.com/t?e=m%3D2%26s%3DgKUfuKdAZKocQipKwQzePOeEDrYVVa64K7Vc7tFgwiHjf2vlNIV67p2n%2BQBNMyE6Rku8%2Bpj6eJall3bs%2B3NRhNHnsKI%2BqxhyM0iVZhTFBom4YIorMPnmg8G0g2OJi%2FzmXHfenomYtn5EW9vzeG8LzfPUwktUBEmkxg5p7bh%2BFbQ%3D&pvid=10_106.6.161.154_3367_1490163222155

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,544评论 25 707
  • 蓝牙 注:本文翻译自https://developer.android.com/guide/topics/conn...
    RxCode阅读 8,453评论 11 99
  • 初识低功耗蓝牙 Android 4.3(API Level 18)开始引入Bluetooth Low Energy...
    JBD阅读 111,652评论 46 342
  • Guide to BluetoothSecurity原文 本出版物可免费从以下网址获得:https://doi.o...
    公子小水阅读 7,608评论 0 6
  • 在高铁上坐晚车回津,徐州东站停完开车后,突然看到乘务员推着我的箱子过去。喊,这是我的箱子。她们停下来说,是的,有位...
    炬焱阅读 345评论 0 0