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

Android蓝牙自动连接指定RSSI范围内同APP设备问题排查

蓝牙连接失败及设备自发现问题排查

核心问题分析

1. 设备无法自发现

Android蓝牙系统默认不会扫描到自身设备,这是系统层面的设计限制,属于正常现象,无需额外处理。

2. 连接逻辑时序错误

在BroadcastReceiver的onReceive方法中,刚调用connectToDevice就立刻启动文件传输,存在两个致命问题:

  • bluetoothSocket.connect()是阻塞操作,在主线程执行会直接导致ANR(应用无响应)
  • 未确认连接是否成功就初始化文件传输,大概率会使用未连接的bluetoothSocket引发空指针或IO异常

3. 服务器监听逻辑不完善

startServer方法中仅执行一次serverSocket.accept(),接受一个连接后线程就终止,无法持续监听后续连接;且未对接收到的客户端连接做任何传输处理,导致客户端发起连接后无响应。

4. 错误使用wait()方法

wait(10000)属于Object的线程等待方法,调用时必须持有该对象的锁,当前代码未加同步锁,会直接抛出IllegalMonitorStateException;且在主线程调用会卡死UI。

5. 清理逻辑触发过早

在onReceive中连接后立刻调用cleanup(),会直接注销广播接收器、关闭服务器Socket,导致后续无法扫描其他设备或接受新连接,同时文件传输可能未完成就被强制中断。

6. 权限隐患

虽然添加了@SuppressLint("MissingPermission"),但Android 12+需要BLUETOOTH_SCAN、BLUETOOTH_CONNECT权限,Android 11及以下需要ACCESS_FINE_LOCATION权限,未动态申请会导致扫描或连接失败。


代码修复建议

1. 异步执行连接与传输逻辑

将连接和文件传输移至子线程,避免阻塞主线程:

private final BroadcastReceiver receiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE);

            Log.d(TAG, "Device found: " + device.getName() + " RSSI: " + rssi);

            if(rssi > -75) {
                new Thread(() -> {
                    connectToDevice(device);
                    if (bluetoothSocket != null && bluetoothSocket.isConnected()) {
                        BluetoothFileTransfer bluetoothFileTransfer = new BluetoothFileTransfer(bluetoothSocket, context);
                        File fileToSend = new File(context.getFilesDir(), "contact.json");
                        File fileToRecieve = new File(context.getFilesDir(), "recievedContact.json");
                        bluetoothFileTransfer.startFileTransfer(fileToSend,fileToRecieve);
                        // 建议通过BluetoothFileTransfer的回调判断传输完成,再关闭连接
                        closeConnection();
                    }
                }).start();
            }
        }
    }
};

2. 完善服务器持续监听

让服务器线程循环监听连接,每接收到一个连接就启动子线程处理传输:

public void startServer() {
    new Thread(() -> {
        try {
            serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(APP_NAME, APP_UUID);
            Log.d(TAG, "Server started");
            while (!Thread.currentThread().isInterrupted()) {
                BluetoothSocket clientSocket = serverSocket.accept();
                Log.d(TAG, "Server accepted connection");
                new Thread(() -> handleClientConnection(clientSocket)).start();
            }
        } catch (IOException e) {
            Log.e(TAG, "Failed to start server", e);
        }
    }).start();
}

private void handleClientConnection(BluetoothSocket socket) {
    try {
        BluetoothFileTransfer bluetoothFileTransfer = new BluetoothFileTransfer(socket, context);
        File fileToRecieve = new File(context.getFilesDir(), "recievedContact.json");
        File fileToSend = new File(context.getFilesDir(), "contact.json");
        bluetoothFileTransfer.startFileTransfer(fileToSend, fileToRecieve);
        socket.close();
    } catch (IOException e) {
        Log.e(TAG, "Client connection error", e);
    }
}

3. 修正清理逻辑调用时机

将cleanup()移至应用生命周期结束时调用(比如Activity的onDestroy),而非在单次连接后触发:

// 在宿主Activity中
@Override
protected void onDestroy() {
    super.onDestroy();
    if (bluetoothConnectionManager != null) {
        bluetoothConnectionManager.cleanup();
    }
}

4. 补充权限申请

在Manifest中添加权限:

<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />

并在运行时动态申请上述权限,确保扫描和连接功能正常。


内容的提问来源于stack exchange,提问作者Ladle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 00:45:12