You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android蓝牙串口连接失败求助:无法读取ASCII数据

Hey there, let's dig into this Bluetooth serial connection headache you're dealing with! I’ve seen this exact issue pop up with Android 7.x devices and Bluetooth SPP devices, so let’s break down the problems and fix them step by step.

First, let’s clarify the scanner’s behavior

That scanner you’re testing is likely running in HID (Human Interface Device) mode—think of it like a wireless keyboard. That’s why it auto-populates your EditText without any code from you, and why the system settings have a "Use as input device" toggle. The third-party app works because it supports both SPP serial connections and listens for HID input events. Your original code is targeting SPP (the standard serial UUID 00001101-0000-1000-8000-00805F9B34FB), but the scanner might not have SPP enabled by default.

For the scanner: Skip the BluetoothSocket entirely

Since it’s acting as a HID input device, you don’t need to establish a serial connection. Just listen for the input directly:

  1. Use a TextWatcher on your EditText: This is the simplest way, since the scanner will type data into it like a keyboard.
EditText scanEditText = findViewById(R.id.your_scan_edit_text);
scanEditText.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public void afterTextChanged(Editable s) {
        String rawScanData = s.toString().trim();
        // Most scanners append a newline/carriage return—strip that if needed
        if (rawScanData.endsWith("\n") || rawScanData.endsWith("\r")) {
            rawScanData = rawScanData.substring(0, rawScanData.length() - 1);
        }
        // Do your processing here!
    }
});
  1. If you don’t want an EditText visible, you can use a hidden one, or register a broadcast receiver for input events—but the EditText method is far more reliable.

Fixing the SPP connection failure for your older devices

The java.io.IOException: read failed, socket might closed, read ret: -1 error is super common on Android 7.x, especially when connections that used to work break. Here’s how to fix it:

1. Fix the BluetoothManager initialization

Your log shows W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback—that means you’re not initializing the Bluetooth adapter correctly. Use BluetoothManager instead of getDefaultAdapter():

BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();

2. Cancel discovery before connecting

Bluetooth discovery blocks connection attempts. Always cancel it right before you try to connect:

if (mBluetoothAdapter.isDiscovering()) {
    mBluetoothAdapter.cancelDiscovery();
}

3. Improve the reflected Rfcomm connection

Your current reflection only tries channel 1, but some devices use different channels. Try looping through channels 1-10 to find the right one:

// Replace your existing reflection code with this
boolean connected = false;
for (int channel = 1; channel <= 10; channel++) {
    try {
        mmSocket = (BluetoothSocket) mmDevice.getClass()
                .getMethod("createRfcommSocket", int.class)
                .invoke(mmDevice, channel);
        mmSocket.connect();
        connected = true;
        break; // Exit loop once connected
    } catch (Exception e) {
        // Ignore failed channel, try next one
        continue;
    }
}
if (!connected) {
    // Handle connection failure here
}

4. Double-check permissions (even if you think they’re set)

On Android 6.0+, some devices require ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION to connect to Bluetooth devices—even if you’re not scanning. Add these to your manifest:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

And don’t forget to ask for them dynamically at runtime, since they’re dangerous permissions.

5. Clean up old connections

Always close existing sockets before trying a new connection:

if (mmSocket != null) {
    try {
        mmSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    mmSocket = null;
}

Quick troubleshooting steps

  • Restart your device’s Bluetooth adapter (disable then re-enable)
  • Forget the paired device in system settings, then re-pair it
  • Test with another SPP Bluetooth device to rule out hardware issues

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

火山引擎 最新活动