You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 07:05:32