上一篇
安卓关于蓝牙的api
- 行业动态
- 2025-04-23
- 8
Android蓝牙API基于BluetoothAdapter,需权限声明,支持设备扫描、连接及数据传输,兼容经典与B
安卓蓝牙 API 详解
权限管理
安卓蓝牙功能涉及多个权限,需在 AndroidManifest.xml
中声明,并在运行时动态申请(Android 6.0+)。
权限 | 用途 | 是否需要动态申请 |
---|---|---|
BLUETOOTH |
基础蓝牙功能(如开启/关闭蓝牙) | 否 |
BLUETOOTH_ADMIN |
修改蓝牙配置(如配对、绑定) | 否 |
ACCESS_FINE_LOCATION |
扫描蓝牙设备(Android 6.0+ 强制要求) | 是 |
ACCESS_COARSE_LOCATION |
扫描蓝牙设备(可选替代 ACCESS_FINE_LOCATION ) |
是 |
BLUETOOTH_CONNECT |
建立蓝牙连接(Android 12+ 新增) | 是(Android 12+) |
BLUETOOTH_SCAN |
扫描蓝牙设备(Android 12+ 新增) | 是(Android 12+) |
NEARBY_DEVICES |
允许应用发现附近设备(Android 12+) | 是(Android 12+) |
动态权限申请示例:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE); }
核心类与功能
类名 | 用途 | 关键方法 |
---|---|---|
BluetoothAdapter |
蓝牙功能入口(代表本地蓝牙设备) | getDefaultAdapter() , isEnabled() , enable() , disable() , startDiscovery() |
BluetoothDevice |
代表远程蓝牙设备 | getAddress() , getName() , connectGatt() , createBond() , getType() |
BluetoothGatt |
BLE 连接与通信(GATT 客户端) | connect() , disconnect() , readCharacteristic() , writeCharacteristic() |
BluetoothClass |
描述蓝牙设备的服务类型(如音频、设备分类) | getDeviceClass() , isServiceAvailable(int serviceClass) |
BluetoothLeScanner |
BLE 设备扫描(Android 5.0+) | startScan(ScanCallback) , stopScan(ScanCallback) |
BluetoothProfile.ServiceListener |
监听蓝牙服务状态(如开启/关闭) | onServiceConnected() , onServiceDisconnected() |
蓝牙设备扫描
传统蓝牙扫描(通过
startDiscovery()
):- 调用
BluetoothAdapter.startDiscovery()
开始扫描。 - 需注册
BroadcastReceiver
监听BluetoothDevice.ACTION_FOUND
事件。 - 缺点:扫描耗时长,无法过滤特定设备。
- 调用
BLE 扫描(通过
BluetoothLeScanner
):- 创建
BluetoothLeScanner
实例,调用startScan(ScanCallback)
。 - 优势:支持自定义扫描参数(如低功耗、平衡模式),可过滤设备。
- 示例代码:
BluetoothLeScanner scanner = adapter.getBluetoothLeScanner(); ScanCallback callback = new ScanCallback() { @Override public void onScanResult(ScanResult result) { // 处理扫描结果 } }; scanner.startScan(callback);
- 创建
蓝牙连接与通信
传统蓝牙(经典蓝牙):
- 通过
BluetoothDevice.createRfcommSocketToServiceRecord(UUID)
创建 socket。 - 调用
socket.connect()
建立连接,通过InputStream
和OutputStream
传输数据。 - 示例:
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(MY_UUID); socket.connect(); OutputStream output = socket.getOutputStream(); inputStream = socket.getInputStream();
- 通过
BLE 通信(基于 GATT):
- 调用
BluetoothDevice.connectGatt(Context, boolean autoConnect, BluetoothGattCallback)
。 - 通过
BluetoothGatt
的readCharacteristic
、writeCharacteristic
读写数据。 - 自动连接(autoConnect):
true
:系统自动重连(需在onConnectionUpdate
中处理)。false
:仅本次连接有效,需手动重连。
- 调用
常见问题与解决方案
问题 | 原因与解决方案 |
---|---|
无法扫描到设备 | 未申请位置权限(Android 6.0+)。 蓝牙未开启或设备不支持 BLE。 扫描频率过高导致系统限制。 |
连接失败 | 设备未配对或不支持目标服务。 权限不足(如未声明 BLUETOOTH_CONNECT )。设备距离过远或干扰。 |
数据传输异常 | 未在主线程处理回调。 特征值(Characteristic)未正确配置。 连接断开后未重连。 |
相关问题与解答
问题 1:如何判断设备是否支持蓝牙?
解答:通过 BluetoothAdapter.getDefaultAdapter()
获取本地适配器,若返回值为 null
则表示设备不支持蓝牙。
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter == null) { // 设备不支持蓝牙 }
问题 2:BLE 连接时 autoConnect
参数有何作用?
解答:
autoConnect = true
:系统会尝试自动重连设备(如设备信号恢复后)。autoConnect = false
:仅建立一次性连接,断开后需手动重新连接。
建议:若需要持续连接(如心率监测),设为true
;若只需单次通信,设为false