首先,android设备与蓝牙连接有两种方式。不同的连接,代码是不一样的,应该是uuid不一样。

1. android设备 与android设备连接。

2. android设备 与非android设备连接。

如下图

android与蓝牙通讯记录_第1张图片


android与蓝牙通讯记录_第2张图片


android与蓝牙通讯记录_第3张图片


我做的是与非android蓝牙设备相关的通讯,以下全为非android蓝牙设备的相关内容。

蓝牙目前可以分为2种。

经典蓝牙(Classic)

低功耗蓝牙(BLE   android4.3以上支持ble)

这两种蓝牙从扫描到连接到数据的传输api完全不一样,因此拿到蓝牙设备之后,要确认好蓝牙种类。

关于BLE蓝牙,可参考谷歌官方demo

https://github.com/googlesamples/android-BluetoothLeGatt

由于这个官方代码是很久之前的,因此,在android6.0以及以上的系统需要加上权限的相关设置。

并且这里只有读,没有写入数据的操作。

写入的操作,我是参考的这个。

https://github.com/Jasonchenlijian/FastBle


经典蓝牙,参考了这个demo,连接的时候有一个选项,不要选与android设备相连,选另一个。

https://github.com/akexorcist/Android-BluetoothSPPLibrary

我是在这个demo的基础上进行修改。

Android-BluetoothSPPLibrary应该是在官方demo的基础上修改的。

https://github.com/googlesamples/android-BluetoothChat


目前是使用经典蓝牙串口调试通讯(ble蓝牙只做了扫描、连接到读写数据等)。

使用SSCOM5.12(pc端软件)这个串口调试工具。当android设备与蓝牙连接之后,通过app发送命令,电脑上就可以收到数据(蓝牙要通过线连接到电脑)。

期间遇到的问题:

未断开的情况下重连,要先做断开操作,然后在断开后要加一定的延时再进行重新连接,否则容易报错。

Android-BluetoothSPPLibrary 的代码中数据的发送与接收那里在断开与重连的过程中容易报错,改成跟 android-BluetoothChat一样就不会报错了。

根据Android-BluetoothSPPLibrary 修改的代码,蓝牙断开后4.4直接崩溃。未断开的情况下重连 7.0不会报错,5.0以及6.0会无法连接,要断开后再连接才可以连接上。

解决完蓝牙的连接问题之后,下面来看看通讯问题。

蓝牙串口是什么。

首先看串口的解释:

https://zh.wikipedia.org/wiki/%E4%B8%B2%E8%A1%8C%E7%AB%AF%E5%8F%A3

串口包括RS-232-C、RS-422、RS485、USB等。

这里串口指的是usb接口。

蓝牙开发板上的usb接口通过线接到pc的usb接口。

串口是指利用串行方式传输数据的接口,它是一大类接口,USB接口、RS232接口、网线RJ45接口、RS485接口、SATA接口等等都属于串口。各种串口之间的通讯协议、接口电平等并不完全相同,因此有一种串口得到另一种串口时需要转换。

一般来说,串口默认是指RS232接口,所谓的USB转串口实际上就是USB转RS232装置。

https://zhidao.baidu.com/question/340354937.html



蓝牙模块也称蓝牙串口通讯模块

android与蓝牙通讯记录_第4张图片

http://www.shaoguoji.cn/2016/04/16/usage-of-bluetooth-model/

蓝牙的真正作用就是代替了那根tx ,rx的数据线。

蓝牙通讯也有相关协议。

蓝牙协议相关:

https://langw.gitbooks.io/blesummary-/content/lan_ya_xie_yi_zhan_fen_xi.html

http://www.cnblogs.com/zjutlitao/p/4742428.html

可以粗略的看下,不必深入。


因此,蓝牙串口就是蓝牙开发板通过串口连接(这里是usb接口连接,实际应用中是可以自行封装串口通讯协议?通讯的本质是?协议?),进行通讯。

那么这里是怎么进行通讯的?

1.当android设备与蓝牙连接之后,app就可以发生数据到蓝牙模块。

2.蓝牙模块接收到命令之后,通过串口(这里是usb接口)传输给电脑,使用 SSCOM5.12软件读出数据。这里主要就是 SSCOM5.12这个软件的作用了。 使用SSCOM5.12串口调试助手的时候,注意设置波特率。

使用SSCOM5.12注意以下几处。


android与蓝牙通讯记录_第5张图片


整个发送数据的流向是:

app--->android 设备蓝牙 -->非android设备蓝牙模块-->pc端--> 使用SSCOM5.12解析数据。

实际使用中非android设备蓝牙模块后面不会接到pc端,而是别的串口,这里只是前期调试。

实际使用如下


android与蓝牙通讯记录_第6张图片


当app的蓝牙连接到非android设备的蓝牙模块时,会收到一条指令。

IM_CONN:0,683E344FA855,0100,0,490

01 00这个数据是发送数据时需要用到的。0100要反过来。00 01  。注意句柄(handle

https://www.zhihu.com/question/22950899)。

发送数据:

41 54 3E 01 01 08 00 00 01 31 32 33 34 35 36 0d


android与蓝牙通讯记录_第7张图片


成功发送数据会返回ok,否则是error。

[15:24:22.762]发→◇AT>���\0\0�123456□

[15:24:22.767]收←◆

OK

蓝牙断开显示

[15:24:50.336]收←◆

IM_DISC:0100,0


以上就是经典蓝牙相关的。

------------------------------BLE----------------

下面来看看ble的。

ble相关概念看这篇,很详细。

Android 上的低功耗蓝牙实践

https://www.race604.com/android-ble-in-action/


BLE 的协议栈

作为 Android 开发者,我们不必理解 BLE 的协议栈每个细节,这里大概介绍一下协议架构。我们都知道,协议一般都是分层设计的。BLE 协议栈也不例外。我们来看一下这个图。整个协议栈大致分为三部分,从下到上分别为,控制器(Controller)→主机(Host)→应用(Applications)。

控制器:它是协议栈的底层的实现,直接与硬件相关,一般直接集成在 SoC 中,由芯片厂商实现,包括物理层和链路层。 主机:这是协议栈的上层实现,是硬件的抽象,与具体的硬件和厂家无关。 应用层:就是使用 Host 层提供的 API,开发的应用。

android与蓝牙通讯记录_第8张图片

下面具体围绕这张图进行分析。

android与蓝牙通讯记录_第9张图片


android与蓝牙通讯记录_第10张图片


ATT与GATT


[翻译]ATT和GATT概述

http://legendmohe.net/2015/01/16/%E7%BF%BB%E8%AF%91att%E5%92%8Cgatt%E6%A6%82%E8%BF%B0/


ATT,即属性协议

GATT,全称叫做通用属性配置文件

上图 中的Host 部分,属性协议,即 ATT,它是 BLE 通信的基础。ATT 把数据封装,向外暴露为“属性”,提供“属性”的为服务端,获取“属性”的为客户端。ATT 是专门为低功耗蓝牙设计的,结构非常简单,数据长度很短。

接下来我们看一下 GATT,全称叫做通用属性配置文件,它是建立在前面说的 ATT 的基础上,对 ATT 进行进一步的逻辑封装,定义数据的交互方式和含义。

这是我们做 BLE 开发的时候直接接触的概念。

GATT 按照层级定义了三个概念:服务(Service)、特征(Characteristic)和描述(Descriptor)。他们的包含关系如右边这个图所表示的:一个 Service 包含若干个 Characteristic,一个 Characteristic 可以包含若干 Descriptor。而 Characteristic 定义了数值和操作。

Characteristic 的操作这几种权限:读、写、通知等权限。我们说的 BLE 通信,其实就是对 Characteristic 的读写或者订阅通知。

还有最外面一层,Profile配置文件,把若干个相关的 Service 组合在一起,就成为了一个 Profile,Profile 就是定义了一个实际的应用场景。

android与蓝牙通讯记录_第11张图片


详细的图:

android与蓝牙通讯记录_第12张图片

那么如何操作Characteristic ,关键在于UUID。

Service、Characteristic 还有 Descriptor 都是使用 UUID 唯一标示的。

下面来看看什么是uuid。

关于 UUID 有一些规范,为了避免冲突,一般都不会自己手动去定义。例如 Android 中提供了 UUID.randomUUID() 来生成一个随机的 UUID。我们也看到,UUID 有点太长了,在低功耗蓝牙中这种数据长度非常受限的情况下,使用起来肯定不方便,所以蓝牙又使用了所谓的 16 bit 或者 32 bit 的 UUID。其实本质上并没有什么 16bit 或者 32 bit UUID,蓝牙 SIG 定义了一个基础的UUID(Bluetooth Base UUID),形式如下。除了 XXXX 那几位意外,其他都是固定,所以说,其实 16 bit UUID 是对应了一个 128 bit 的 UUID。这样一来,UUID 就大幅减少了,例如 16 bit uuid 只有有限的 65536 个,所以 16 bit UUID 并不能随便使用。SIG 已经预先定义了一些 UUID,如果你想添加一些自己的 16 bit 的 UUID,可以花钱买。

16*16*16*16 = 65536 

android与蓝牙通讯记录_第13张图片




android与蓝牙通讯记录_第14张图片


BLE 应用可以分为两大类:基于非连接的和连接的。


基于非连接的,这种应用就是依赖 BLE 的广播,也叫作 Beacon。这里有两个角色,发送广播的一方叫做 Broadcaster,监听广播的一方叫 Observer。

基于连接的,就是通过建立 GATT 连接,收发数据。这里也有两个角色,发起连接的一方,叫做中心设备—Central,被连接的设备,叫做外设—Peripheral。

我这里做的是连接式的应用。

这里总结一下扫描中一些建议。


1、首先,尽可能使用新的 API,功能更强大;

2、尽可能少地扫描,因为毕竟扫描是一个比较重的操作,耗电,也会减慢 BLE 连接速度;

3、扫描的时候,尽量设置 ScanFilter,只扫描那些你感兴趣的设备,而不是全盘扫描;

4、正确使用 API,特别是合理停止扫描,防止资源泄漏。



这里有一个中心设备和外设的概念。

android与蓝牙通讯记录_第15张图片


可以尽量遵循如下一些原则:尽量少的连接数量,尽量短的连接时间,尽量少的扫描,至于尽量少的 ClientIf,如果在 APP 中多个模块中都要扫描或者连接,应该做尽可能的合并。尽量少的广播数据,尽量少的并行请求,在回调中要做尽量少的工作。

以上大部分文字都是抄的,这里只是做个记录。


具体代码分析可以看这里,可对照谷歌官方源码去参照。

Android BLE 蓝牙开发入门

https://www.jianshu.com/p/3a372af38103







BLE的坑:Android蓝牙4.0 BLE开发坑总结

参考连接:

https://www.mianbaoban.cn/blog/post/133095

更多相关文章

  1. android读写串口
  2. Android 蓝牙4.0代码解析
  3. android跨进程通讯一:android中跨进程通讯的4种方式
  4. android 获取手机通讯录信息
  5. Android 使用非阻塞的方式读写串口
  6. Android蓝牙开发浅析
  7. android蓝牙BLE(一) —— 扫描
  8. Android studio 中NDK的配置和JNI实现的完整过程SerialPort andr
  9. android通讯录解析源码

随机推荐

  1. 什么是积分墙?
  2. 【Android】Fragment懒加载和ViewPager的
  3. 关于Android长按出现复制粘贴栏在顶部占
  4. Android性能优化之过渡绘制
  5. Android - 软件自动更新的实现
  6. Android 中activity的启动方式和一些特定
  7. android将tab选项卡放在底部
  8. 资源—— 读取assets目录下的文件详细介
  9. Android 收集崩溃信息并上传
  10. Android 中 ListView 分页加载数据