❶ android 蓝牙开发(一)
普通蓝牙设备官方文档
Android 平台包含蓝牙网络堆栈支持 ,凭借此支持,设备能以无线方式与其他蓝牙设备交换数据。应用框架提供了通过 Android Bluetooth API 访问蓝牙功能的途径。使用 Bluetooth API Android 应用可以执行下面的操作:
传统蓝牙适用于电池使用强度较大的操作,例如 Android 设备之间的流传输和通信等。针对具有低功耗要求的蓝牙设备,Android 4.3(API 18)中引入了面向低功耗蓝牙的 API 支持。
使用 Android Bluetooth API 来完成使用蓝牙进行通信的四项主要任务: 设置蓝牙 、 查找局部区域内的配对设备或可用设备 、 连接设备 ,以及在 设备之间传输数据 。
关于蓝牙的 API 在 android.bluetooth 包中,下面介绍一下和蓝牙相关的主要类:
在 BluetoothProfile IPC 客户端连接到服务(即,运行特定配置文件的内部服务)或断开服务连接时向其发送通知的接口。
使用蓝牙必须声明权限 BLUETOOTH 才可以执行蓝牙通信。
1、获取蓝牙适配器
例如:我们可以查询所有已配对的设备,然后使用 ArrayAdapter 向用户显示每台设备的名称:
要发起连接仅需要知道目标蓝牙设备的 Mac 地址就可以了。
注意 执行 discovery 对于蓝牙适配器来说是一个非常繁重的过程,并且会消耗大量资源。在找到要连接的设备后, 要确保使用 cancelDiscovery() 来停止发现,然后尝试连接 。如果您已经和某台设备进行连接,那么这个时候执行发现操作会大幅度的减少此连接可用的带宽!因此不应该在处于连接状态的时候执行发现操作!
例如:
在连接之前如果两个设备没有配对,则系统会自动发出配对请求。
服务器套接字接受连接的基本过程
放在子线程中去执行。
例子:
客户端连接的基本过程
调用 connect() 的时候要确保客户端没有执行发现操作。如果执行了会大幅度降低连接的速度,增加失败的可能。
例子
在连接之前调用 cancleDiscovery() 在进行连接之前应该始终调用这个方法,而且调用的时候无需检测是否正在扫描。
过程:
从 Android 3.0 开始, Bluetooth API 便支持使用蓝牙配置文件。蓝牙配置文件是适用于设备间蓝牙通信的无线接口规范。
1、蓝牙配置文件就是设备间通信(蓝牙设备)的一种规范
免提配置文件便是一个示例,对于连接到无线耳机的手机,两台设备都必须支持免提配置文件。我们也可以通过实现接口 BluetoothProfile 来写入自己的类来支持特定的蓝牙配置文件。Android API 提供了以下的几种蓝牙配置文件的实现:
2、使用配置文件的基本步骤
创建 HDP 应用:
关于普通蓝牙设备和普通蓝牙设备之间的连接通信
关于蓝牙设备和蓝牙仪器(蓝牙耳机、电子秤等等类似产品)
这种之间的通信是通过配置文件代理来实现的。
都有一个对应的配置文件代理类。具体的操作是通过这个对象来完成。
参考: https://mp.weixin.qq.com/s?__biz=MzU5NzA2NjQzMg==&mid=2247484128&idx=1&sn=&scene=21#wechat_redirect
❷ Android蓝牙开发——实现蓝牙聊天
与蓝牙开发主要的相关类是以下四个
知道对应API后就可以进行对应的蓝牙开发,这里以获取蓝牙设备为例子
}
搜索设备的回调则需要通过注册广播的形式来获取
定义广播
之后就可以进行个人的一些操作
要实现蓝牙聊天则涉及到蓝牙之间的传输通信,前面也说到了,这里肯定就是用到BluetoothServerSocket以及BluetoothSocket。
蓝牙传输通信相当于服务器端与客户端之间的通信,只不过不同是这里每一个蓝牙设备本身自己 既充当服务器端也充当客户端 ,大致的关系就是
注意,这些连接都是阻塞式的,都要放在线程里去执行。
可以看到,当BluetoothServerSocket监听到有设备连接的时候,就会调用dataTransfer开启一个数据传输。
需要一个ConnectThread来发起
之后建立连接之后就会调用dataTransfer来进行数据传输,同样也需要一个线程来维护数据传输
蓝牙聊天则是基于上面三个线程来进行实现,同样,对于蓝牙文件间的传输也是同个道理,通过输入输出流来进行处理。之后的操作就比较容易处理了
蓝牙聊天
Android 蓝牙开发基本流程
❸ Android开发之蓝牙(Bluetooth)
在上一篇中有介绍了Wifi与网络连接处理
Android开发之WiFi与网络连接处理
下面,来继续说说Android中蓝牙的基本使用。
Bluetooth是目前使用的最广泛的无线通讯协议之一,主要针对短距离设备通讯(10米),常用于连接耳机、鼠标和移动通讯设备等。
值得一提的是:
android4.2新增了部分新功能,但是对于Bluetooth熟悉的人或许开始头疼了,那就是Android4.2引入了一个新的蓝牙协议栈针BLE。谷歌和Broadcom之间的合作,开发新的蓝牙协议栈,取代了基于堆栈的Bluez。因此市场上出现了老设备的兼容问题,很多蓝牙设备在android4.2手机上不能正常使用。
BluetoothAdapter简单点来说就是代表了本设备(手机、电脑等)的蓝牙适配器对象。
first:we need permission
要操作蓝牙,先要在AndroidManifest.xml里加入权限
**下面来看看如何使用蓝牙。 **↓↓↓****
Demo已就绪:
返回值:如果设备具备蓝牙功能,返回BluetoothAdapter 实例;否则,返回null对象。
打开蓝牙设备的方式:
1.直接调用函数enable()去打开蓝牙设备 ;
2.系统API去打开蓝牙设备,该方式会弹出一个对话框样式的Activity供用户选择是否打开蓝牙设备。
注意: 1.如果蓝牙已经开启,不会弹出该Activity界面。2.在目前大多数Android手机中,是不支持在飞行模式下开启蓝牙的。如果蓝牙已经开启,那么蓝牙的开关 ,状态会随着飞行模式的状态而发生改变。
1. 搜索蓝牙设备
使用BluetoothAdapter的startDiscovery()方法来搜索蓝牙设备
startDiscovery()方法是一个异步方法,调用后会立即返回。该方法会进行对其他蓝牙设备的搜索,该过程会持续12秒。该方法调用后,搜索过程实际上是在一个System Service中进行的,所以可以调用cancelDiscovery()方法来停止搜索(该方法可以在未执行discovery请求时调用)。
系统开始搜索蓝牙设备
^( *  ̄(oo) ̄ ) ^ 系统会发送以下三个广播:
2.扫描设备
3.定义广播接收器接收搜索结果
4.注册广播
获取附近的蓝牙设备
第一步建立连接:首先Android sdk(2.0以上版本)支持的蓝牙连接是通过BluetoothSocket建立连接,服务端BluetoothServerSocket和客户端(BluetoothSocket)需指定同样的UUID,才能建立连接,因为建立连接的方法会阻塞线程,所以服务器端和客户端都应启动新线程连接。
(这里的服务端和客户端是相对来说的)
两个蓝牙设备之间的连接,则必须实现服务端与客户端的机制。
当两个设备在同一个RFCOMM channel下分别拥有一个连接的BluetoothSocket,这两个设备才可以说是建立了连接。
服务端设备与客户端设备获取BluetoothSocket的途径是不同的。
1,服务端设备是通过accepted一个incoming connection来获取的,
2,客户端设备则是通过打开一个到服务端的RFCOMM channel来获取的。
服务端
通过调用BluetoothAdapter的(String, UUID)方法来获取BluetoothServerSocket(UUID用于客户端与服务端之间的配对)
客户端
调用BluetoothService的(UUID)方法获取BluetoothSocket(该UUID应该同于服务端的UUID)。
调用BluetoothSocket的connect()方法(该方法为block方法),如果UUID同服务端的UUID匹配,并且连接被服务端accept,则connect()方法返回。
数据传递,通过以上操作,就已经建立的BluetoothSocket连接了,数据传递无非是通过流的形式
获取流
该类就是关于远程蓝牙设备的一个描述。通过它可以和本地蓝牙设备---BluetoothAdapter连接通信。
好多东西我也不知道怎么描述,下面给出Demo:
刚好有刚学习的小伙伴问我ListView怎么用,那我就用ListView。
源码:
RairDemo
GitHub: https://github.com/Rairmmd/android-demo
Coding: https://coding.net/u/Rair/p/RairDemo/git
❹ Android蓝牙开发(二)经典蓝牙消息传输实现
上篇文章中,我们主要介绍了蓝牙模块,传统/经典蓝牙模块BT和低功耗蓝牙BLE及其相关的API,不熟悉的可以查看 Android蓝牙开发(一)蓝牙模块及核心API 进行了解。
本篇主要记录用到的经典蓝牙开发流程及连接通讯。
蓝牙连接前,给与相关系统权限:
安卓6.0以上系统要动态请求及获取开启GPS内容:
蓝牙核心对象获取,若获取对象为null则说明设备不支持蓝牙:
判断蓝牙是否开启,没有则开启:
蓝牙扫描:
取消扫描:
蓝牙监听广播,监听蓝牙开关,发现设备,扫描结束等状态,定义状态回调接口,进行对应操作,例如:监听到蓝牙开启后,进行设备扫描;发现设备后进行连接等。
客户端,与服务端建立长连接,进行通讯:
服务端监听客户端发起的连接,进行接收及通讯:
客户端连接及服务端监听基类,用于客户端和服务端之前Socket消息通讯,进行消息或文件的发送、接收,进行通讯关闭操作等:
我这里只是简单记录了项目中用到的蓝牙通讯,两个设备之间不通过配对进行连接、通讯。
相关详细内容及使用请查看Github项目: https://github.com/MickJson/BluetoothCS
蓝牙配对操作及其它内容,可以详细查看我下面的参考资料,写的十分详细,比如设备通过MAC地址,可以通过BluetoothAdapter获取设备,再通过客户端connect方法去进行连接等。
连接中遇到问题:read failed, socket might closed or timeout, read ret: -1。
通过改UUID,反射等方法都还是会出现错误。连接时,要确保服务端及客户端都处于完全断开状态,否则连接就会出现以上问题,但偶尔还是会有问题,期待有什么好的方法可留言告诉我。
参考资料:
Android-经典蓝牙(BT)-建立长连接传输短消息和文件
Android蓝牙开发—经典蓝牙详细开发流程
欢迎点赞/评论,你们的赞同和鼓励是我写作的最大动力!
❺ 如何使用android原生BLE蓝牙进行操作
之前的涉及的物联网项目中使用的: BLE 低功耗蓝牙(蓝牙4.0), 支持android 4.3以上的手机
主从关系: BLE低功耗蓝牙只能做从端设备 ,一个蓝牙主端设备,可同时与7个蓝牙从端设备进行通讯
1)低功耗
低功耗的原理:
1低功耗蓝牙仅使用了3个广播通道,传统蓝牙技术采用 16~32 个频道
2每次广播开启时间也由传统的 22.5ms 减少到 0.6~1.2ms(毫秒)
2)传输距离极大提高
传统蓝牙传输距离为 2~10m,而蓝牙4.0的有效传输距离可达到 60~100m
3)安全性
使用AES-128 CCM加密算法进行数据包加密和认证。
更多BLE蓝牙的解析参考博客 : BLE4.0教程一 蓝牙协议连接过程与广播分析
添加权限
打开蓝牙
1.先拿到BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
2.再拿到BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
判断是否打开蓝牙
未打开弹出 系统弹框 ,除了 魅族手机 是打开系统设置
设备/手机都是蓝牙信号
在回调方法中:
一般在扫描的过程中,我们还会设置 设备过滤原则 (因为我只想要搜索到我们想要的设备,忽略无关设备)
如:从 scanRecord -- beacon -- beacon.type == 0xFF代表Manufacture,通过与嵌入式软件定义 自己的 Manufacture值即可
用BluetoothDevice得到BluetoothGatt:
断连:
关键问题:连接后一般要做什么事?
( 必须在刚连接成功后2秒内app写一个值给设备,否则会被设备断开连接)
主要是读写 characteristic
gatt.wirteCharacteristic(mCurrentcharacteristic);
gatt.readCharacteristic(characteristic);
bluetoothGatt.setCharacteristicNotification(data, true);
真实工作中使用的蓝牙库BlueToothKit请参考我的另一篇博客:
android蓝牙入门知识和优秀蓝牙第三方库BluetoothKit的使用
❻ 安卓手机如何用beats耳机怎么连蓝牙
按下beats耳机“开关”按钮,安卓手机“设置”里开启“蓝牙”,选择beats耳机蓝牙名称打开,输入配对秘钥即可。
工具/材料:以beats耳机、vivo X9i手机为例。
1、首先按下beats耳机“开关”按钮,打开蓝牙功能。
注意事项:
beats耳机没有单独的蓝牙按键,打开开关键后,耳机的蓝牙功能自动开启。
❼ Android-Ble蓝牙开发Demo示例–扫描,连接,发送和接收数据,分包解包(附源码)
万物互联的物联网时代的已经来临,ble蓝牙开发在其中扮演着举重若轻的角色。最近刚好闲一点,抽时间梳理下这块的知识点。
涉及ble蓝牙通讯的客户端(开启、扫描、连接、发送和接收数据、分包解包)和服务端(初始化广播数据、开始广播、配置Services、Server回调操作)整个环节以及一些常见的问题即踩过的一些坑。
比如
1、在Android不同版本或不同手机的适配问题,扫描不到蓝牙设备
2、如何避免ble蓝牙连接出现133错误?
3、单次写的数据大小有20字节限制,如何发送长数据
蓝牙有传统(经典)蓝牙和低功耗蓝牙BLE(Bluetooth Low Energy)之分,两者的开发的API不一样,本文主讲Ble蓝牙开发,传统蓝牙不展开,有需要的可以自行了解。
相对传统蓝牙,BLE低功耗蓝牙,主要特点是快速搜索,快速连接,超低功耗保持连接和数据传输。
客户端
服务端
Android4.3(API Level 18)开始引入BLE的核心功能并提供了相应的 API。应用程序通过这些 API 扫描蓝牙设备、查询 services、读写设备的 characteristics(属性特征)等操作。
BLE蓝牙协议是GATT协议, BLE相关类不多, 全都位于android.bluetooth包和android.bluetooth.le包的几个类:
android.bluetooth.
.BluetoothGattService 包含多个Characteristic(属性特征值), 含有唯一的UUID作为标识
.BluetoothGattCharacteristic 包含单个值和多个Descriptor, 含有唯一的UUID作为标识
.BluetoothGattDescriptor 对Characteristic进行描述, 含有唯一的UUID作为标识
.BluetoothGatt 客户端相关
.BluetoothGattCallback 客户端连接回调
.BluetoothGattServer 服务端相关
.BluetoothGattServerCallback 服务端连接回调
android.bluetooth.le.
.AdvertiseCallback 服务端的广播回调
.AdvertiseData 服务端的广播数据
.AdvertiseSettings 服务端的广播设置
.BluetoothLeAdvertiser 服务端的广播
.BluetoothLeScanner 客户端扫描相关(Android5.0新增)
.ScanCallback 客户端扫描回调
.ScanFilter 客户端扫描过滤
.ScanRecord 客户端扫描结果的广播数据
.ScanResult 客户端扫描结果
.ScanSettings 客户端扫描设置
BLE设备分为两种设备: 客户端(也叫主机/中心设备/Central), 服务端(也叫从机/外围设备/peripheral)
客户端的核心类是 BluetoothGatt
服务端的核心类是 BluetoothGattServer 和 BluetoothLeAdvertiser
BLE数据的核心类是 BluetoothGattCharacteristic 和 BluetoothGattDescriptor
下面详细讲解下客户端和服务端的开发步骤流程
安卓手机涉及蓝牙权限问题,蓝牙开发需要在AndroidManifest.xml文件中添加权限声明:
在搜索设备之前需要询问打开手机蓝牙:
注意: BLE设备地址是动态变化(每隔一段时间都会变化),而经典蓝牙设备是出厂就固定不变了!
通过扫描BLE设备,根据设备名称区分出目标设备targetDevice,下一步实现与目标设备的连接,在连接设备之前要停止搜索蓝牙;停止搜索一般需要一定的时间来完成,最好调用停止搜索函数之后加以100ms的延时,保证系统能够完全停止搜索蓝牙设备。停止搜索之后启动连接过程;
BLE蓝牙的连接方法相对简单只需调用connectGatt方法;
参数说明
与设备建立连接之后与设备通信,整个通信过程都是在BluetoothGattCallback的异步回调函数中完成;
BluetoothGattCallback中主要回调函数如下:
上述几个回调函数是BLE开发中不可缺少的;
当调用targetdDevice.connectGatt(context, false, gattCallback)后系统会主动发起与BLE蓝牙设备的连接,若成功连接到设备将回调onConnectionStateChange方法,其处理过程如下:
判断newState == BluetoothGatt.STATE_CONNECTED表明此时已经成功连接到设备;
mBluetoothGatt.discoverServices();
扫描BLE设备服务是安卓系统中关于BLE蓝牙开发的重要一步,一般在设备连接成功后调用,扫描到设备服务后回调onServicesDiscovered()函数,函数原型如下:
BLE蓝牙开发主要有负责通信的BluetoothGattService完成的。当且称为通信服务。通信服务通过硬件工程师提供的UUID获取。获取方式如下:
具体操作方式如下:
开启监听,即建立与设备的通信的首发数据通道,BLE开发中只有当客户端成功开启监听后才能与服务端收发数据。开启监听的方式如下:
BLE单次写的数据量大小是有限制的, 通常是20字节 ,可以尝试通过requestMTU增大,但不保证能成功。分包写是一种解决方案,需要定义分包协议,假设每个包大小20字节,分两种包,数据包和非数据包。对于数据包,头两个字节表示包的序号,剩下的都填充数据。对于非数据包,主要是发送一些控制信息。
监听成功后通过向 writeCharacteristic写入数据实现与服务端的通信。写入方式如下:
其中:value一般为Hex格式指令,其内容由设备通信的蓝牙通信协议规定;
若写入指令成功则回调BluetoothGattCallback中的onCharacteristicWrite()方法,说明将数据已经发送给下位机;
若发送的数据符合通信协议,则服务端会向客户端回复相应的数据。发送的数据通过回调onCharacteristicChanged()方法获取,其处理方式如下:
通过向服务端发送指令获取服务端的回复数据,即可完成与设备的通信过程;
当与设备完成通信之后之后一定要断开与设备的连接。调用以下方法断开与设备的连接:
源码上传在CSDN上了,有需要的可以借鉴。
=====> Android蓝牙Ble通讯Demo示例源码–扫描,连接,发送和接收数据,分包解包
BLE单次写的数据量大小是有限制的,通常是20字节,可以尝试通过requestMTU增大,但不保证能成功。分包写是一种解决方案,需要定义分包协议,假设每个包大小20字节,分两种包,数据包和非数据包。对于数据包,头两个字节表示包的序号,剩下的都填充数据。对于非数据包,主要是发送一些控制信息。
总体流程如下:
1、定义通讯协议,如下(这里只是个举例,可以根据项目需求扩展)
2、封装通用发送数据接口(拆包)
该接口根据会发送数据内容按最大字节数拆分(一般20字节)放入队列,拆分完后,依次从队列里取出发送
3、封装通用接收数据接口(组包)
该接口根据从接收的数据按协议里的定义解析数据长度判读是否完整包,不是的话把每条消息累加起来
4、解析完整的数据包,进行业务逻辑处理
5、协议还可以引入加密解密,需要注意的选算法参数的时候,加密后的长度最好跟原数据长度一致,这样不会影响拆包组包
一般都是Android版本适配以及不同ROM机型(小米/红米、华为/荣耀等)(EMUI、MIUI、ColorOS等)的权限问题
蓝牙开发中有很多问题,要静下心分析问题,肯定可以解决的,一起加油;
❽ android蓝牙BLE(三) —— 广播
在蓝牙开发中,有些情况是不需要连接的,只要外设广播自己的数据即可,例如苹果的 ibeacon 。自 Android 5.0 更新蓝牙API后,手机可以作为外设广播数据。
广播包有两种:
其中 广播包是每个外设都必须广播的,而响应包是可选的 。每个广播包的长度必须是 31个字节 ,如果不到 31个字节 ,则剩下的全用 0 填充 补全,这部分的数据是无效的
广播包中包含若干个广播数据单元,广播数据单元也称为 AD Structure 。
广播数据单元 = 长度值Length + AD type + AD Data。
长度值 Length 只占 一个字节 ,并且位于广播数据单元的 第一个字节 。
概念的东西有些抽象,先看看下面的广播报文:
0x代表这串字符串是十六进制的字符串。 两位十六进制数代表一个字节 。因为两个字符组成的十六进制字符串最大为 FF ,即255,而Java中byte类型的取值范围是-128到127,刚好可以表示一个255的大小。所以两个十六进制的字符串表示一个字节。
继续查看报文内容,开始读取第一个广播数据单元。读取 第一个 字节: 0x07 ,转换为十进制就是7,即表示后面的7个字节是这个广播数据单元的数据内容。超过这7个字节的数据内容后,表示是一个新的广播数据单元。
而第二个广播数据单元,第一个字节的值是 0x16 ,转换为十进制就是22,表示后面22个字节为第二个广播数据单元。
在广播数据单元的 数据部分 中, 第一个字节 代表 数据类型 (AD type),决定数据部分表示的是什么数据。(即广播数据单元第二个字节为AD type)
AD Type 的类型如下:
这bit 1~7分别代表着发送该广播的蓝牙芯片的物理连接状态。当bit的值为1时,表示支持该功能。
例:
蓝牙广播的数据格式大致讲了一下,有助于下面的广播操作的理解。
先看看广播设置( AdvertiseSettings )如何定义:
(1)、通过 AdvertiseSettings.Builder#setAdvertiseMode() 设置广播模式。其中有3种模式:
(2)、通过 AdvertiseSettings.Builder#setAdvertiseMode() 设置广播发射功率。共有4种功率模式:
(3)、通过 AdvertiseSettings.Builder#setTimeout() 设置持续广播的时间,单位为毫秒。最多180000毫秒。当值为0则无时间限制,持续广播,除非调用 BluetoothLeAdvertiser#stopAdvertising() 停止广播。
(4)、通过 AdvertiseSettings.Builder#setConnectable() 设置该广播是否可以连接的。
之前说过,外设必须广播广播包,扫描包是可选。但添加扫描包也意味着广播更多得数据,即可广播62个字节。
可见无论是广播包还是扫描包,其广播的内容都是用 AdvertiseData 类封装的。
(1)、 AdvertiseData.Builder#setIncludeDeviceName() 方法,可以设置广播包中是否包含蓝牙的名称。
(2)、 AdvertiseData.Builder#setIncludeTxPowerLevel() 方法,可以设置广播包中是否包含蓝牙的发射功率。
(3)、 AdvertiseData.Builder#addService UUID (Parcel UUID ) 方法,可以设置特定的 UUID 在广播包中。
(4)、 AdvertiseData.Builder#addServiceData(Parcel UUID ,byte[]) 方法,可以设置特定的 UUID 和其数据在广播包中。
(5)、 AdvertiseData.Builder#addManufacturerData(int,byte[]) 方法,可以设置特定厂商Id和其数据在广播包中。
从 AdvertiseData.Builder 的设置中可以看出,如果一个外设需要在不连接的情况下对外广播数据,其数据可以存储在 UUID 对应的数据中,也可以存储在厂商数据中。但由于厂商ID是需要由Bluetooth SIG进行分配的,厂商间一般都将数据设置在厂商数据。
另外可以通过 BluetoothAdapter#setName() 设置广播的名称
先看一个例子,我们分别在 广播包 和 扫描包 中设置 AdvertiseData.Builder 的 每一种广播报文参数 ,得到一下报文内容:
(1)、Type = 0x01 表示设备LE物理连接。
(2)、Type = 0x09 表示设备的全名
(3)、Type = 0x03 表示完整的16bit UUID 。其值为0xFFF7。
(4)、Type = 0xFF 表示厂商数据。前两个字节表示厂商ID,即厂商ID为0x11。后面的为厂商数据,具体由用户自行定义。
(5)、Type = 0x16 表示16 bit UUID 的数据,所以前两个字节为 UUID ,即 UUID 为0xF117,后续为 UUID 对应的数据,具体由用户自行定义。
最后继承 AdvertiseCallback 自定义广播回调。
初始化完毕上面的对象后,就可以进行广播:
广播主要是通过 BluetoothLeAdvertiser#startAdvertising() 方法实现,但在之前需要先获取 BluetoothLeAdvertiser 对象。
BluetoothLeAdvertiser 对象存在两个情况获取为Null:
所以在调用 BluetoothAdapter#getBluetoothLeAdvertiser() 前,需要先调用判断蓝牙已开启,并判断在 BluetoothAdapter 中获取的 BluetoothLeAdvertiser 是否为空(测试过某些华为手机 mBluetoothAdapter.() 为 false , 但是能发送ble广播)。
与广播成对出现就是 BluetoothLeAdvertiser.stopAdvertising() 停止广播了,传入开启广播时传递的广播回调对象,即可关闭广播:
虽然通过广播告知外边自身拥有这些Service,但手机自身并没有初始化Gattd的Service。导致外部的中心设备连接手机后,并不能找到对应的 GATT Service 和 获取对应的数据。
Service类型有两个级别:
创建 BluetoothGattService 时,传入两个参数: UUID 和Service类型:
我们都知道Gatt中, Service 的下一级是 Characteristic , Characteristic 是最小的通信单元,通过对 Characteristic 进行读写操作来进行通信。
特征属性表示该 BluetoothGattCharacteristic 拥有什么功能,即能对 BluetoothGattCharacteristic 进行什么操作。其中主要有3种:
权限属性用于配置该特征值所具有的功能。主要两种:
Characteristic 下还有 Descriptor ,初始化 BluetoothGattDescriptor 时传入: Descriptor UUID 和 权限属性
为 Service 添加 Characteristic ,为 Characteristic 添加 Descriptor :
通过蓝牙管理器 mBluetoothManager 获取 Gatt Server ,用来添加 Gatt Service 。添加完 Gatt Service 后,外部中心设备连接手机时,将能获取到对应的 GATT Service 和 获取对应的数据
定义 Gatt Server 回调。当中心设备连接该手机外设、修改特征值、读取特征值等情况时,会得到相应情况的回调。
最后开启广播后,用nRF连接后看到的特征值信息如下图所示:(加多了一个只能都的特征值)
android蓝牙BLE(一) —— 扫描
android蓝牙BLE(二) —— 通信
android蓝牙BLE(三) —— 广播
android蓝牙BLE(四) —— 实战
❾ Android 蓝牙开发(三)-蓝牙的详细介绍
前面的两篇文章,主要是在 Android 官网关于蓝牙介绍的基础上加上自己的理解完成的。主要针对的是 Android 开发中的一些 API 的使用。
第一篇文章 Android 蓝牙开发(一) 主要是介绍了普通的蓝牙在 Android 开发中的运用。
第二篇文章 Android 蓝牙开发(二) 主要是介绍了低功耗蓝牙的开发。
这篇文章主要介绍的是蓝牙的历史和一些关于蓝牙的通用知识,还有广播包的知识。要想彻底了解蓝牙开发,这些基础的知识也是需要的,就像网络协议一样,这些都是基础的内容。我们的 API 的调用都是以这个为基础的,了解这些,开发过程中遇到问题,才可以知道什么怎么一回事。
下篇文章主要讲的就是实际开发中的一些坑。
蓝牙其实就是一种近距离无线通信技术。
从下到上分别为:控制器(Controller)-->主机(host)-->应用(Application)
详细介绍各个层的含义:
BLE 应用可以分为两大类:基于非连接的和基于连接的
意思就是外设和周边设备不发生连接,主要靠扫描到的广播来获取信息。发送广播的一方叫做 broadcaster 监听广播的一方叫做 oberver 在 GAP 层有对应的角色定义。
网络拓扑图:
这种方式就是广播设备不断的向外发送广播(含有特定的信息),然后观察者接受到广播按照两者之间约定好的协议进行解析拿到有用的信息。例如:iBeacon,通过这种设备我们可以实现室内定位。
其实这些设备的角色可以即使广播者又是观察者。接收到广播后作出了处理,然后又发送广播。这样就形成了双向的网络,类似于因特网,这就是蓝牙 Mesh 组网。
广播数据包格式:
每个广播数据包由 31 byte 组成。分为有效数据和无效数据两部分。
例子:
这里是扫描的数据包(转换成了 16 进制,两个代表一个字节),第一个字节是 02 表示后面的两个字节是数据部分,然后第二个字节是 01 表示了数据的类型。后面一个字节就是真正的数据了。这个广播数据单元就分析完了。下面就是另一个数据单元了。依次类推,关于数据类型的解释,官网有。
这是数据类型对应的含义表。
网络拓扑图:
一个中心设备可连接多个外设,但是一个外设只能连接一个中心(外设连接成功后就会停止对外广播,别人就发现不了它了)。其中一个中心设备的连接外设的数量也是有限的。
链接: https://mp.weixin.qq.com/s?__biz=MzU5NzA2NjQzMg==&mid=2247484141&idx=1&sn=&scene=21#wechat_redirect