2011-02-24 142 views
12

我尝试建立蓝牙连接如下:Android的蓝牙连接问题

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

什么我做错了吗?我在这个错误工作了一个星期,我不能通过...

任何帮助将是非常apreciated!

+0

你能在这个问题上需要帮助http://stackoverflow.com/questions/40559549/android-bluetooth-java-io-ioexception -bt-socket-closed-read-return-1?noredirect = 1#comment68358423_40559549 – Achin 2016-11-12 07:39:30

回答

17

我有一个非常类似的问题,前几天...

尝试增加这个检查你的代码:

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

这个固定我的问题......

好运;)

+0

谢谢,它的工作原理! = D – Laurent 2011-09-12 07:27:19

+0

不错,正是我遇到的问题。 – 2011-09-26 17:05:33

+5

实际上,添加此代码确实可以防止发生异常,但在连接实际上丢失的情况下,它会阻止线程重新启动并得到修复。所以虽然我同意答案,但我最终决定不使用它。 – 2011-09-26 17:42:50

-1

这就是我解决问题的方法:通过实现某种超时。在我的情况下3秒。代码不是我的,但它很好用。 基本上发生的事情是,有第二个循环等待输入流中的东西。当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; 
        } 
       } 

的,而(真),可以根据你希望收到什么样的改变。在我的情况下,当我收到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); 
    } 
} 

请注明的答案是正确的,如果有帮助:)