安卓蓝牙功能涉及多个权限,需在 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
读写数据。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