【Android】Bluetooth(蓝牙)连接与数据传输(一)
目录
- 简介
- 权限声明
- 蓝牙扫描
- 开始扫描
- 取消扫描
- 获取蓝牙信息
- 蓝牙配对
- 配对
- 取消配对
- 获取已配对蓝牙
- 最终效果
简介
蓝牙技术是一种无线数据和语音通信开放的全球规范,它是基于低成本的近距离无线连接,为固定和移动设备建立通信环境的一种特殊的近距离无线技术(使用2.4~2.485GHz的ISM波段的UHF无线电波)连接。
蓝牙类型 | 描述 |
---|---|
经典蓝牙(Classic Bluetooth) | 功耗高,传输数据量大,传输距离短(10米) |
低功耗蓝牙(Bluetooth Low Energy) | 功耗低,传输数据量小,传输距离较经典蓝牙远 |
蓝牙模块 | 描述 |
---|---|
单模蓝牙 | 有一种蓝牙版本,运行一种蓝牙协议栈的模块,常用在低功耗蓝牙(Bluetooth Low Energy),如手环。 |
双模蓝牙 | 内置两个蓝牙版本,运行两套协议栈的蓝牙模块,支持经典蓝牙与低功耗蓝牙,如手机。 |
权限声明
Android 11(API 30)及以下的Android版本,只需声明android.permission.BLUETOOTH
与android.permission.ACCESS_FINE_LOCATION
,如果是Android 9(API 28)及以下的Android版本,则需要将android.permission.ACCESS_FINE_LOCATION
更换为android.permission.ACCESS_COARSE_LOCATION
。以下权限则是Android 12(API 31)及以上你可能会使用到的权限。
<!-- 允许应用程序连接到配对的蓝牙设备 -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<!-- 需要能够发现和配对附近的蓝牙设备 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
<!-- 允许应用程序发现和配对蓝牙设备 -->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!-- 需要能够连接到配对的蓝牙设备 -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<!-- 允许应用程序在没有用户交互的情况下配对蓝牙设备,并允许或禁止电话簿访问或消息访问 -->
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED"tools:ignore="ProtectedPermissions" />
<!-- 需要能够向附近的蓝牙设备做广告 Android 12 -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/><uses-permission android:name="com.google.android.things.permission.MANAGE_BLUETOOTH" />
<!-- 获得定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
这里展示了七个与蓝牙相关的权限,其中的android.permission.BLUETOOTH_SCAN
、android.permission.BLUETOOTH_CONNECT
、android.permission.BLUETOOTH_ADVERTISE
、android.permission.ACCESS_FINE_LOCATION
权限属于危险权限,需要另外写代码去动态申请。
蓝牙扫描
开始扫描
蓝牙扫描接收扫描结果使用BroadcastReceiver
进行接收,而BroadcastReceiver
需要写代码去触发,执行startDiscovery()
扫描蓝牙前应加上registerReceiver(BroadcastReceiver receiver,IntentFilter filter)
注册一个广播接收者,同时加上IntentFilter
过滤掉那些用不到的intent
,只取我们用得到的Intent
。
val filter = IntentFilter()
// 找到设备
filter.addAction(BluetoothDevice.ACTION_FOUND)
// 远程设备的绑定状态发生变化
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED)
// 第一次检索远程设备的友好名称,或自上次检索后更改
filter.addAction(BluetoothDevice.ACTION_NAME_CHANGED)
// 远程设备的蓝牙类已更改
filter.addAction(BluetoothDevice.ACTION_CLASS_CHANGED)
// 用于在获取远程设备后将其UUID 作为ParcelUuid远程设备的包装进行广播
filter.addAction(BluetoothDevice.ACTION_UUID)
// 操作配对请求
filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST)
// 蓝牙状态改变
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED)
// 开始搜索蓝牙
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED)
// 蓝牙搜索完成
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
// 本地Adapter的蓝牙扫描模式发生了变化
filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)
// 本地蓝牙适配器更改蓝牙名称
filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)
// 请求本地蓝牙可被其它蓝牙扫描到
filter.addAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE)
// 显示请求可发现模式的系统活动
filter.addAction(BluetoothAdapter.ACTION_REQUEST_ENABLE)
// 连接状态改变
filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)
继承了BroadcastReceiver
的类,实现其onReceive(Context context, Intent intent)
方法,就可以在onReceive(Context context, Intent intent)
里加上if语句去判断当前BroadcastReceiver
是否接收到了上述的Action
,当接收到Intent
的Action
与上述IntentFilter.addAction(String action)
相符,意味着是时候该执行与对应Action
相关的操作了。
当识别到设备需要将其返回到Activity
时,则可使用EventBus
来进行传输。
执行上述操作后,当前手机开启了蓝牙,其它的蓝牙设备却扫描不到当前手机蓝牙时,也许是因为没有启用允许其它蓝牙发现当前手机蓝牙的功能(Android系统默认情况下无法扫描到当前手机蓝牙),关于这一点,应在扫描蓝牙前就加上允许其它蓝牙发现当前手机蓝牙的代码,如下:
val enabler = Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE)
startActivity(enabler)
执行代码,弹出申请是否允许其它设备发现本设备功能弹框,点击允许后,在接下来的120秒内(上限为300秒),其它的蓝牙可在规定时间内扫描到当前手机蓝牙。
取消扫描
取消蓝牙扫描时应先判断是否为null
、是否正在扫描蓝牙后再取消扫描,同时注销掉广播。
if (bluetoothAdapter != null && bluetoothAdapter!!.isDiscovering) {bluetoothAdapter!!.cancelDiscovery()context.unregisterReceiver(bluetoothReceiver)
}
获取蓝牙信息
找到蓝牙设备后可得到一个任意类型T
,将其转换为BluetoothDevice
,就可以通过这一个类来获取蓝牙的相关信息,下图中使用到的方法如下:
Methods | Describe |
---|---|
getName() | 获取蓝牙名称 |
getType() | 获取蓝牙类型 |
getBondState() | 获取蓝牙的绑定状态 |
getAddress() | 获取蓝牙设备的硬件地址 |
getUuids() | 返回远程设备支持的功能 (UUID) |
其效果如下:
其它获取蓝牙相关信息方法见:BluetoothDevice
蓝牙配对
配对
蓝牙的配对使用BluetoothDevice.createBond()
进行配对,createBond()
有一个返回值,但千万不要以为他返回true
意味着蓝牙配对成功,返回true
只是意味着它开始申请配对,届时双方的蓝牙都会弹出如下对话框提示是否配对,此刻点击取消才是真正的取消配对,即配对失败。
部分蓝牙,如蓝牙耳机、部分手机蓝牙,配对成功后就直接连接上了,不需要再执行连接的操作。关于连接、数据传输的操作会在下一章进行讲解,博主暂时还缺乏能够进行数据传输的蓝牙设备,还请见谅。
取消配对
蓝牙配对与取消配对的方法createBond()
,removeBond()
都在BluetoothDevice
里面,但调用方式却有着天壤之别。
createBond()
可通过BluetoothDevice
类的实例直接进行调用,removeBond()
通过BluetoothDevice
实例来进行调用是行不通的,这一切的始作俑者,都是因为removeBond()
的@SystemApi
注解导致的。
但这并不意味无法调用removeBond()
方法,针对这种情况,可以使用反射来强制调用removeBond()
方法,如下所示:
try {val method = BluetoothDevice::class.java.getMethod("removeBond")val b = method.invoke(device) as Boolean} catch (e: Exception) {e.printStackTrace()}
获取已配对蓝牙
获取已经配对的蓝牙设备,得拿到BluetoothAdapter
类的实例,调用getBondedDevices()
即可获得一个Set<BluetoothDevice>
类型的已配对蓝牙数据。
val bondedDevices: Set<BluetoothDevice> get() = getBluetoothAdapter()!!.bondedDevices
最终效果
由于
注意事项:
1、低功耗蓝牙不能兼容(连接)经典蓝牙,只能兼容双模蓝牙、低功耗蓝牙。
2、BluetoothAdapter.getDefaultAdapter()
方法在API 31 中已废弃,可使用BluetoothManager.getAdapter()
代替。
3、本项目目前只做到蓝牙扫描与配对,数据的传输因缺少对应的蓝牙设备而暂时停滞,后期有相关设备后将会补上数据传输相关的文章。
点击前往下载源码
参考文档:
1、Android Bluetooth 连接
2、Android Developers —— Bluetooth overview(蓝牙概述)
3、Android Developers —— Bluetooth permissions(蓝牙权限)
4、Android Developers —— Manifest.permission(蓝牙清单权限)
5、Android Developers —— Find Bluetooth devices(查找蓝牙设备)
6、Android Developers —— Connect Bluetooth devices(连接蓝牙设备)
【Android】Bluetooth(蓝牙)连接与数据传输(一)相关推荐
- Android 设备蓝牙连接扫描枪获取扫描内容
Android 设备蓝牙连接扫描枪获取扫描内容 标签(空格分隔): 未分类 条形扫描枪主要可以扫描条形码和二维码等,扫描速度比手机扫描设备快得多,本文简单介绍android 通过蓝牙监听蓝牙连接,当扫 ...
- Android Bluetooth蓝牙开发:发现Bluetooth蓝牙设备(1)
Android Bluetooth蓝牙开发:发现Bluetooth蓝牙设备(1) Android Bluetooth蓝牙作为设备,要与其他蓝牙设备互联,那么先决条件就是已经被发现,本文先简介An ...
- Android Bluetooth蓝牙enable过程
Android Bluetooth蓝牙enable过程 Android Bluetooth框架 enable的追踪从settings app开始,一直到最底层的driver,基本按照上图的框架,把函数 ...
- android bluetooth——蓝牙的开启、搜索、配对与连接
android 的blt仅仅支持api 18 android4.3以上,有的功能甚至需要api 19 android4.4: 所以我们在做blt项目之前一定要清楚可用的版本范围. 我要讲述的是打开bl ...
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信例子_Android支持蓝牙4.0版本_BLE开发
一.Android Bluetooth现状 在android官网可以了解到android4.2新增了部分新功能,但是对于BT熟悉的人或许开始头疼了,那就是Android4.2引入了一个新的蓝牙协议栈针 ...
- Android bluetooth 蓝牙开发/蓝牙协议/蓝牙通信
一.Android Bluetooth现状 在android官网可以了解到android4.2新增了部分新功能,但是对于BT熟悉的人或许开始头疼了,那就是Android4.2引入了一个新的蓝牙协议栈针 ...
- Android Bluetooth蓝牙开发\蓝牙协议\蓝牙通信
一.Android Bluetooth现状 在android官网可以了解到android4.2新增了部分新功能,但是对于BT熟悉的人或许开始头疼了,那就是Android4.2引入了一个新的蓝牙协议栈针 ...
- BlueTooth: 蓝牙基带数据传输机理分析
蓝牙基带数据传输机理分析 蓝牙(Bluetooth)是一种新型.开放.低成本.短距离的无线连接接技术,可取代短距离的电缆,实现话音和数据的无线传输.这种有效.廉价的无线连 接技术可以方便地将计算机及外 ...
- 【Android】蓝牙连接使用
本文实现蓝牙连接,使用的GitHub开源库实现,调用封装好的API. 1.依赖 implementation 'com.vise.xiaoyaoyou:baseble:2.0.6' 2.权限申请 // ...
- Android手机蓝牙连接热敏打印机 打印票据
手机蓝牙连接热敏打印机 打印票据 话不多说上代码: 项目地址:可直接作为项目依赖 引用 allprojects {repositories {...maven { url 'https://jitpa ...
最新文章
- Linux常用的50个命令
- 500个爆文标题_美食爆文大放送 | 烹饪技巧从细节着手,夏日消暑美食最为应时...
- 控制台怎么查看错误的详细信息_js错误处理,quot;try..catchquot;
- fetchxml 汇总_Dynamic CRM 2013学习笔记(十七)JS读写各种类型字段方法及技巧
- hive数据的导入导出方式
- Python算术运算符目录
- 如何插入一条记录获取插入后的自动增长ID列的方法.
- Linux系统编程——vfork() 函数详解
- 搜狗输入法linux版 rpm,opensuse 制作搜狗输入法rpm包
- Java多线程编程实战指南(核心篇)读书笔记(一)
- Java查询返回值为树形结构
- 机器学习算法工程师--实习面经
- [SpringCould篇]之服务消费方式Ribbon+RestTemplate
- matlab期末题库,Matlab-期末考试题库(共12套卷)
- Win11 22H2四个你不知道的隐藏功能
- float a=1.0f 中的“f”代表什么
- Win Server 系统远程桌面连接失败解决办法
- 部署https证书的端口是什么意思
- Motion Based Multi-Sensor Extrinsic Calibration源码配置与学习记录
- 最新电脑版微信可以刷朋友圈啦