Android Studio蓝牙服务发现:无法搜索运行pybluez服务的电脑
Android端搜索PyBluez广播的蓝牙服务实现指南
一、配置必要权限
首先在AndroidManifest.xml中添加蓝牙相关权限,不同Android版本权限要求不同:
<!-- 基础蓝牙权限 --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- Android 6.0+ 搜索蓝牙需要位置权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Android 12+ 新增的蓝牙扫描/连接权限 --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- 声明蓝牙功能 --> <uses-feature android:name="android.hardware.bluetooth" android:required="true" />
注意:Android 6.0+ 需要动态申请ACCESS_FINE_LOCATION权限;Android 12+ 需单独申请BLUETOOTH_SCAN和BLUETOOTH_CONNECT权限。
二、初始化蓝牙适配器
先获取蓝牙适配器实例,确保蓝牙已开启:
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter == null) { // 设备不支持蓝牙 return; } if (!bluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); }
三、搜索设备并匹配目标服务
Android的蓝牙服务发现核心是通过UUID匹配——你需要提前知晓PyBluez端广播的服务UUID(比如PyBluez中用BluetoothService注册的UUID),然后通过以下两种方式匹配:
方式1:扫描设备后主动查询服务UUID
注册广播接收器监听设备发现和UUID查询结果:
private final BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); // 发现蓝牙设备 if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // 主动查询该设备的服务UUID device.fetchUuidsWithSdp(); } // 获取设备的UUID列表 else if (BluetoothDevice.ACTION_UUID.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); Parcelable[] uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID); if (uuidExtra != null) { for (Parcelable uuid : uuidExtra) { UUID serviceUuid = (UUID) uuid; // 匹配PyBluez端的服务UUID if (serviceUuid.equals(YOUR_PYBLUEZ_SERVICE_UUID)) { // 找到目标设备,可发起连接 connectToDevice(device, serviceUuid); // 停止扫描节省资源 bluetoothAdapter.cancelDiscovery(); break; } } } } } }; // 注册广播接收器 IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_FOUND); filter.addAction(BluetoothDevice.ACTION_UUID); registerReceiver(bluetoothReceiver, filter); // 开始扫描设备 bluetoothAdapter.startDiscovery();
方式2:直接通过UUID连接目标设备
如果你已知目标设备的MAC地址,可跳过扫描直接通过UUID创建RFCOMM套接字连接:
private void connectToDevice(BluetoothDevice device, UUID serviceUuid) { try { // 创建RFCOMM套接字,匹配服务UUID BluetoothSocket socket = device.createRfcommSocketToServiceRecord(serviceUuid); // 发起连接(注意不能在主线程执行) new ConnectThread(socket).start(); } catch (IOException e) { e.printStackTrace(); } } // 后台连接线程 private static class ConnectThread extends Thread { private final BluetoothSocket mmSocket; public ConnectThread(BluetoothSocket socket) { mmSocket = socket; } public void run() { try { mmSocket.connect(); // 连接成功,可进行数据读写 } catch (IOException connectException) { try { mmSocket.close(); } catch (IOException closeException) { closeException.printStackTrace(); } return; } } public void cancel() { try { mmSocket.close(); } catch (IOException e) { e.printStackTrace(); } } }
四、Android蓝牙服务发现核心机制说明
- Android通过
fetchUuidsWithSdp()触发SDP(服务发现协议)查询,获取设备上的所有蓝牙服务UUID; - 当查询完成后,系统会发送
BluetoothDevice.ACTION_UUID广播,携带设备的UUID列表; - 你只需在广播接收器中匹配PyBluez端预先定义的服务UUID,即可定位到目标服务;
- 若使用RFCOMM套接字直接指定UUID连接,Android会自动完成SDP匹配,无需手动查询所有UUID。
注意事项
- 扫描蓝牙设备会消耗较多资源,找到目标设备后需立即调用
bluetoothAdapter.cancelDiscovery()停止扫描; - 蓝牙连接操作必须在子线程中执行,不能阻塞主线程;
- 确保PyBluez端的服务UUID与Android端完全一致(注意UUID的格式,比如大小写、分隔符)。
内容的提问来源于stack exchange,提问作者Sime Dev
相关产品推荐
相关产品推荐

