2011-09-23 6 views
7

私は今Android用ブルートゥースアプリをしばらく使っています。私がBluetoothのサービスクラスでmySocket.connect();をプリフォームすると、ときどき無期限にブロックされます。私はBluetoothSocket.close()のドキュメントを読んで、次のように書いています。AndroidでBluetooth:私のSocket.connect()が永久にブロックされ、Socket.closeがブロック解除されない

すぐにこのソケットを閉じて、関連するすべてのリソースを解放してください。

他のスレッドのこのソケットでブロックされた呼び出しをすぐに引き起こします。 IOExceptionをスローします。

しかし、これは私にとってはうまくいかないようです。ここで私のタイマーを設定し、次に接続しようとしているコードです。

//code for starting timer and connecting 
    MyRunnable runner = new MyRunnable(mySocket); 
    Thread countThread = new Thread(runner); 
    countThread.start(); 

    mySocket.connect(); 
    runner.setSocketConnected(); 


//code for MyRunnable 
    private class MyRunnable implements Runnable{ 
     private boolean didSocketConnect = false; 
     private boolean socketConnectFailed = false; 
     private BluetoothSocket socket; 

     public MyRunnable(BluetoothSocket socket){ 
      this.socket = socket; 
     } 

     public void run() { 
      long start = System.currentTimeMillis(); 
      while(ESTABLISH_TIMEOUT + start >= System.currentTimeMillis() && !didSocketConnect && !socketConnectFailed){ 

      } 
      if(!didSocketConnect && !socketConnectFailed){ 
       Log.v(TAG,"Reached Timeout and socket not open. Look for #"); 
       try { 
        socket.close(); 
        Log.v(TAG,"#THIS CALL SHOULD BE MADE AFTER REACHED TIMEOUT AND SOCKET NOT OPEN"); 
       } catch (IOException e) { 
        Log.v(TAG,"Closing the socket connection fail--", e); 
       } 
      }else{ 
       Log.v(TAG, "Connected or Failed Before Timeout Thread Hit"); 
      } 
     } 

     public void setSocketConnected(){ 
      didSocketConnect = true; 
     } 

     public void setSocketFailed(){ 
      socketConnectFailed= true; 
     } 
    } 

私は無期限()に近い、それもブロックを呼び出して、Connect()の呼び出しはBluetoothSocket.close()のドキュメントにもかかわらず、IOExceptionが投げたことがないとき。 connect()とclose()が無期限にブロックされないようにするにはどうすればよいでしょうか?

注:私はこのプロジェクトでAndroid 2.2を使用しています。

+1

この問題の原因と解決方法を見つけたことはありますか?私は同じことに遭遇していますが、私は2つのスレッド、接続スレッドとclose()を呼び出す別のスレッドを使用しています。 –

+0

私はここで同じ問題があります。 Mainthreadは近いうちに電話してきますが、必ずしもそうではありませんが、時にはうまくいくこともあります。 – NikkyD

答えて

2

BluetoothSocket.connect() - documentationから:

リモートデバイスへの接続を試みます。このメソッドは、 接続が行われるか、接続が失敗するまでブロックされます。このメソッドが例外なしで を返した場合、このソケットは現在接続されています。

BluetoothSocket.connect()の呼び出しがブロックを終了するには、接続を行う必要があります。これは設計によるもので、考えたいと思えば、接続したいBluetoothデバイスのアドレスを取得し、.connect()を呼び出し、接続されるまでブロックしてください。これが、別々のスレッドを必要とする理由です。

.close()を呼び出す限り、.connect()の問題を解決するには、.close()を使用する必要があります。

thisをお読みください。基本的には、「接続」(.connect())と「connected」(InputStream.read())という別のスレッドが必要です。この方法であなたのUIはブロックされません。

例(上記のリンクから)。 ConnectThreadが接続を開始します。 ConnectedThreadは接続を管理します(データの読み書きなど)。

private class ConnectThread extends Thread { 
    private final BluetoothSocket mmSocket; 
    private final BluetoothDevice mmDevice; 

    public ConnectThread(BluetoothDevice device) { 
     // Use a temporary object that is later assigned to mmSocket, 
     // because mmSocket is final 
     BluetoothSocket tmp = null; 
     mmDevice = device; 

     // Get a BluetoothSocket to connect with the given BluetoothDevice 
     try { 
      // MY_UUID is the app's UUID string, also used by the server code 
      tmp = device.createRfcommSocketToServiceRecord(MY_UUID); 
     } catch (IOException e) { } 
     mmSocket = tmp; 
    } 

    public void run() { 
     // Cancel discovery because it will slow down the connection 
     mBluetoothAdapter.cancelDiscovery(); 

     try { 
      // Connect the device through the socket. This will block 
      // until it succeeds or throws an exception 
      mmSocket.connect(); 
     } catch (IOException connectException) { 
      // Unable to connect; close the socket and get out 
      try { 
       mmSocket.close(); 
      } catch (IOException closeException) { } 
      return; 
     } 

     // Do work to manage the connection (in a separate thread) 
     manageConnectedSocket(mmSocket); 
    } 

    /** Will cancel an in-progress connection, and close the socket */ 
    public void cancel() { 
     try { 
      mmSocket.close(); 
     } catch (IOException e) { } 
    } 
} 


private class ConnectedThread extends Thread { 
    private final BluetoothSocket mmSocket; 
    private final InputStream mmInStream; 
    private final OutputStream mmOutStream; 

    public ConnectedThread(BluetoothSocket socket) { 
     mmSocket = socket; 
     InputStream tmpIn = null; 
     OutputStream tmpOut = null; 

     // Get the input and output streams, using temp objects because 
     // member streams are final 
     try { 
      tmpIn = socket.getInputStream(); 
      tmpOut = socket.getOutputStream(); 
     } catch (IOException e) { } 

     mmInStream = tmpIn; 
     mmOutStream = tmpOut; 
    } 

    public void run() { 
     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 
       bytes = mmInStream.read(buffer); 
       // Send the obtained bytes to the UI Activity 
       mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer) 
         .sendToTarget(); 
      } catch (IOException e) { 
       break; 
      } 
     } 
    } 

    /* Call this from the main Activity to send data to the remote device */ 
    public void write(byte[] bytes) { 
     try { 
      mmOutStream.write(bytes); 
     } catch (IOException e) { } 
    } 

    /* Call this from the main Activity to shutdown the connection */ 
    public void cancel() { 
     try { 
      mmSocket.close(); 
     } catch (IOException e) { } 
    } 
} 
関連する問題