Android应用中bluetoothSocket!!.connect()连接Adafruit Bluefruit失败求助
Hey there, let's dig into why your custom Android app can't connect to the Adafruit Bluefruit when nRF Connect works flawlessly. I've wrestled with BLE connection bugs plenty of times, so here are the most common fixes and things to check:
nRF Connect handles permissions automatically behind the scenes, but your app needs to explicitly request them—especially on newer Android versions. Double-check your AndroidManifest.xml has these:
<!-- For Android 12 (API 31) and above --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- For older Android versions (below API 31) --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
And don't forget to request these permissions dynamically in your activity before attempting to connect—just adding them to the manifest isn't enough for runtime permissions.
Adafruit Bluefruit uses dedicated BLE services (like the UART service with UUID 6E400001-B5A3-F393-E0A9-E50E24DCCA9E). nRF Connect auto-discovers these, but your app needs to target them explicitly. Also, BLE connections are callback-driven—don't try to do everything synchronously in your AsyncTask:
- First, connect to the device using
device.connectGatt(context, false, gattCallback) - Wait for
onConnectionStateChangein yourBluetoothGattCallbackto confirm you're connected - Then call
gatt.discoverServices()and wait foronServicesDiscoveredto access Bluefruit's services/characteristics
This is where most people trip up. If you don't properly implement the callback, you'll never know if you connected successfully or why it failed. Here's a minimal working example:
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { super.onConnectionStateChange(gatt, status, newState); if (newState == BluetoothProfile.STATE_CONNECTED) { // Now we can discover services gatt.discoverServices(); } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { // Handle disconnect logic here } } @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { super.onServicesDiscovered(gatt, status); if (status == BluetoothGatt.GATT_SUCCESS) { // Find Bluefruit's UART service and characteristics here BluetoothGattService uartService = gatt.getService(UUID.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")); if (uartService != null) { // Success! You're connected and ready to communicate } } } };
Also, AsyncTask isn't the best tool for BLE work—since BLE uses async callbacks, using coroutines (if you're using Kotlin) or a Handler to update the UI from the callback is more reliable.
Fire up Logcat and filter for BluetoothGatt or BluetoothAdapter logs. Look for error codes:
- Status 133: Connection timeout (often due to missing permissions or device out of range)
- Permission denied messages: You forgot to request runtime permissions
- Service discovery failures: Your callback isn't handling
onServicesDiscoveredcorrectly
If you've tried connecting multiple times, old BluetoothGatt instances might be hanging around and blocking new connections. Always call gatt.disconnect() and gatt.close() when you're done with a connection, before trying to reconnect.
内容的提问来源于stack exchange,提问作者Rike

