Проблема с подключением Bluetooth для Android

Я пытаюсь настроить соединение Bluetooth следующим образом:

private class ConnectThread extends Thread { private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; BluetoothSocket connection = null; public ConnectThread(BluetoothDevice device) { mmDevice = device; // Get a BluetoothSocket for a connection with the // given BluetoothDevice try { if(D) Log.i(TAG, "createRfcommSocket"); Method m = mmDevice.getClass().getMethod("createRfcommSocket",new Class[] { int.class }); connection = (BluetoothSocket) m.invoke(mmDevice, 1); Utils.pause(100); } catch (Exception e) { Log.e(TAG, "create() failed", e); } if(D) Log.i(TAG,"Bluetooth socket initialised"); mmSocket = connection; } public void run() { if(D) Log.i(TAG, "BEGIN mConnectThread on Device : " + mmDevice); setName("ConnectThread"); if (mmSocket != null) { // Always cancel discovery because it will slow down a connection if(mAdapter.isDiscovering()) { if(D) Log.i(TAG, "stop discovering before trying to connect"); mAdapter.cancelDiscovery(); } // Make a connection to the BluetoothSocket try { // This is a blocking call and will only return on a // successful connection or an exception if(D) Log.i(TAG, "start Bluetooth socket connection"); mmSocket.connect(); if(D) Log.i(TAG, "end of Bluetooth socket connection"); } catch (Exception e1) { Log.e(TAG, "connect failed", e1); connectionFailed(); // Reset the socket resetConnection(mmSocket); // Start the service over to restart listening mode if(D) Log.i(TAG, "restart connection"); BluetoothConnectionService.this.start(); if(D) Log.i(TAG, "return"); return; } // Start the connected thread if(D) Log.i(TAG, "The device is considered as connected, call connected thread"); connected(mmSocket, mmDevice); } else { if(D) Log.i(TAG, "connection fail"); connectionFailed(); BluetoothConnectionService.this.start(); } } public void cancel() { if(D) Log.i(TAG,"connect thread cancel"); resetConnection(mmSocket); } } 

Соединение кажется ОК, я получаю этот журнал:

 DEBUG/BluetoothConnectionService(3439): **connect to: 00:18:E4:21:8B:5E** INFO/BluetoothConnectionService(3439): createRfcommSocket INFO/BluetoothConnectionService(3439): Bluetooth socket initialised INFO/BluetoothConnectionService(3439): BEGIN mConnectThread on Device : 00:18:E4:21:8B:5E INFO/BluetoothConnectionService(3439): **start Bluetooth socket connection** INFO/BluetoothConnectionService(3439): setState() 1 -> 2 INFO/ProtectionService(3439): MESSAGE_STATE_CHANGE: 1 DEBUG/ProtectionService(3439): STATE_CHANGED to STATE_LISTEN INFO/ProtectionService(3439): MESSAGE_STATE_CHANGE: 2 DEBUG/abtfilt(2772): **Conn complete** INFO/bluetoothd(2776): link_key_request (sba=24:21:AB:F4:69:25, dba=00:18:E4:21:8B:5E) INFO/bluetoothd(2776): link_key_request (sba=24:21:AB:F4:69:25, dba=00:18:E4:21:8B:5E) INFO/BluetoothConnectionService(3439): **end of Bluetooth socket connection** INFO/BluetoothConnectionService(3439): **The device is considered as connected, call connected thread** 

BluetoothSocket.connect() возвращается без ошибок.

Затем я управляю соединением с этим:

  private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket; private final InputStream mmInStream; private final OutputStream mmOutStream; public ConnectedThread(BluetoothSocket socket) { if(D) Log.d(TAG, "create ConnectedThread"); mmSocket = socket; // Get the BluetoothSocket input and output streams try { if(D) Log.i(TAG, "Get input stream"); tmpIn = socket.getInputStream(); if(D) Log.i(TAG, "Get output stream"); tmpOut = socket.getOutputStream(); if(D) Log.i(TAG, "isConnected = true"); isConnected = true; } catch (IOException e) { Log.e(TAG, "Input and Output sockets not created", e); isConnected = false; } mmInStream = tmpIn; mmOutStream = tmpOut; } public void run() { if(D) Log.i(TAG, "BEGIN mConnectedThread"); byte[] buffer = new byte[1024]; //buffer store for the stream int bytes; //bytes returned from read() // Keep listening to the InputStream until an exception occurs while(true) { try { // Read from the InputStream if(D) Log.i(TAG, "start read mmInStream"); bytes = mmInStream.read(buffer); if(D) Log.i(TAG, "Bytes read : "+bytes); // Send the obtained bytes to the UI Activity mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget(); } catch (IOException e) { Log.e(TAG, "ConnectedThread : disconnected", e); break; } } } /** * Write to the connected OutStream. * * @param buffer * The bytes to write */ public void write(byte[] buffer) { try { mmOutStream.write(buffer); // Share the sent message back to the UI Activity mHandler.obtainMessage(MESSAGE_WRITE, -1, -1, buffer).sendToTarget(); // mmOutStream.flush(); } catch (IOException e) { Log.e(TAG, "Exception during write", e); connectionFailed(); } } public void cancel() { if(D) Log.i(TAG,"connected Thread cancel"); resetConnection(mmSocket); } } 

И я получаю эту ошибку:

 DEBUG/BluetoothConnectionService(3439): create ConnectedThread INFO/BluetoothConnectionService(3439): Get input stream INFO/BluetoothConnectionService(3439): Get output stream INFO/BluetoothConnectionService(3439): isConnected = true INFO/BluetoothConnectionService(3439): BEGIN mConnectedThread INFO/BluetoothConnectionService(3439): start read mmInStream INFO/BluetoothConnectionService(3439): setState() 2 -> 3 INFO/ProtectionService(3439): MESSAGE_STATE_CHANGE: 3 DEBUG/ProtectionService(3439): connectionEstablished **ERROR/BluetoothConnectionService(3439): ConnectedThread : disconnected ERROR/BluetoothConnectionService(3439): java.io.IOException: Software caused connection abort ERROR/BluetoothConnectionService(3439): at android.bluetooth.BluetoothSocket.readNative(Native Method) ERROR/BluetoothConnectionService(3439): at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:307) ERROR/BluetoothConnectionService(3439): at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96) ERROR/BluetoothConnectionService(3439): at java.io.InputStream.read(InputStream.java:133)** INFO/ProtectionService(3439): Send Bluetooth message **ERROR/BluetoothConnectionService(3439): Exception during write ERROR/BluetoothConnectionService(3439): java.io.IOException: Transport endpoint is not connected ERROR/BluetoothConnectionService(3439): at android.bluetooth.BluetoothSocket.writeNative(Native Method) ERROR/BluetoothConnectionService(3439): at android.bluetooth.BluetoothSocket.write(BluetoothSocket.java:317)** 

Ошибка возникает, когда я это делаю:

 bytes = mmInStream.read(buffer); 

Что я делаю не так ? Я работаю над этой ошибкой в ​​течение недели, и я не могу пройти …

Любая помощь будет очень оценена!

    Несколько дней назад у меня была очень похожая проблема …

    Попробуйте добавить эту проверку в свой код:

     if(mmInStream.available() > 0){ bytes = mmInStream.read(buffer); mHandler.obtainMessage(MESSAGE_WRITE, -1, -1, buffer).sendToTarget(); } 

    Это устранило мою проблему …

    Удачи 😉

    Вот как я решил проблему: реализовав какой-то тайм-аут. В моем случае 3 секунды. Код не мой, но он отлично работает. Что в основном происходит, так это то, что есть второй цикл, ожидающий чего-то, что можно получить в inputStream. Когда в inputStream есть что-то, оно идет вперед и читает его. Таким образом, вы должны избегать блокировки в методе mmInputstream.read ().

    Я думаю, что это отличное решение. Это сработало хорошо для меня: я не автор.

     ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.reset(); while (true) { treshHold = 0; try { try { while (mmInStream.available() == 0 && treshHold < 3000) { // if there is something in the inputStream or after 3 seconds Thread.sleep(1); treshHold++; } } catch (IOException e1) { e1.printStackTrace(); } catch (InterruptedException e1) { e1.printStackTrace(); } if (treshHold < 3000) { // if less than 3 seconds timeout treshHold = 0; b = mmInStream.read(); readBytes++; } else { break; } baos.write(b); Thread.sleep(1); if (b == 255) { break; // this is how I know I have got the whole response } } catch (IOException e) { e.printStackTrace(); break; } catch (InterruptedException e) { e.printStackTrace(); break; } } 

    Значение while (true) может быть изменено в зависимости от того, что вы ожидаете получить. В моем случае я ухожу, когда получаю 0xFF или 255. Надеюсь, что это поможет.

    Что касается записи в outputStream, я использовал следующее:

     if(mmOutStream !=null) { try { mmOutStream.flush(); } catch (IOException e1) { // log here ... e1.printStackTrace(); } try { mmOutStream.write(send, 0, sendLength); } catch (IOException e) { // log here ... setState(STATE_NONE); } } 

    Пожалуйста, отметьте ответ правильно, если это поможет 🙂