2011-02-24 22 views
12

trato de establecer una conexión Bluetooth de la siguiente manera:Android Bluetooth problema de conexión

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); 
    } 
} 

La conexión parece estar bien, consigo este registro:

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** 

El BluetoothSocket.connect() retorno sin errores.

Entonces administrar la conexión con esto:

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); 

    } 
} 

y recibo este error:

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)** 

El error viene claramente cuando estoy haciendo esto:

bytes = mmInStream.read(buffer); 

Lo estoy haciendo mal? Estoy trabajando en este error durante una semana y no puedo pasar ...

¡Cualquier ayuda sería muy apreciada!

+0

puede ayudarle en este asunto http://stackoverflow.com/questions/40559549/android-bluetooth-java-io-ioexception-bt-socket-closed-read-return-1? noredirect = 1 # comment68358423_40559549 – Achin

Respuesta

17

que tenía un problema muy similar hace algunos días ...

Trate de añadir este cheque a su código:

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

Esto fija mi problema ...

buena suerte;)

+0

¡Gracias, funciona! = D – Laurent

+0

Agradable, exactamente el problema que estaba teniendo. –

+5

En realidad, agregar este código evita la excepción, pero en el caso de que la conexión realmente se pierda, evita que el hilo se reinicie y se arregle. Entonces, aunque estoy de acuerdo con la respuesta, finalmente decidí no usarla. –

-1

Así es como resolví el problema: implementando algún tipo de tiempo de espera. en mi caso 3 segundos. El código no es mío, pero funciona muy bien. Lo que básicamente ocurre es que hay un segundo bucle esperando que algo ingrese en el inputStream. cuando hay algo en InputStream, continúa y lo lee. De esta forma, debe evitar el bloqueo en el método mmInputstream.read().

Creo que es una gran solución. Funcionó bien para mí: yo no soy el autor.

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; 
        } 
       } 

El tiempo (verdadero) se puede cambiar, dependiendo de lo que esperas recibir. En mi caso, me quedo sin tiempo cuando recibo un 0xFF o 255. Espero que ayude.

En cuanto a la escritura a la flujoSalida que utilizó la siguiente:

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); 
    } 
} 

Por favor marque la respuesta correcta como si ayuda :)

Cuestiones relacionadas