5

BluetoothSocketカスタム デバイス (双方向) と通信している があります。ときどき (これは、300 バイトのチャンクで 8 Mb のデータを転送するときに 4 回に 1 回発生します)、ファイル転送の途中で、Bluetooth がデータの送信を停止します。約 100 ~ 200 個のデータ チャンク (正確な量はわかりません) についてOutputStream.write(byte[], int, int)は、呼び出しのたびに正常に戻り続けます。例外は生成されません。その後、OutputStream.write(byte[], int, int)locks を呼び出します。

コードは ASUS eee 変圧器 Pad TF101 でテストされました。

ローコードにアクセスして、OutputStream何が起こっているのかを確認してデバッグすることはできません。私の推測では、バッファがいっぱいになっているが空になっていないということです。バッファがいっぱいにwriteなると、ロックされます。

何が起こっているのか誰にも分かりますか?

サンプルコードは次のとおりです。

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

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

        setName( "BT Connected Thread" );

        // Get the BluetoothSocket input and output streams
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } 
        catch (IOException e) 
        {
            Log.e( "BT GetStreams", e.getMessage() );
            e.printStackTrace();
        }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run() {

        byte[] buffer = new byte[1024];

        int bytes;

        // Keep listening to the InputStream while connected
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);

                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage( FirmwareHandler.COMMAND_READ, bytes, -1, buffer.clone() ).sendToTarget();

            } catch (IOException e) 
            {
                connectionLost();
                break;
            }
        }
    }

    public void write(byte[] buffer, int size) {
        try {
            Log.d(this.getClass().getSimpleName(), "Before Write, size = " + size + ", mmOutStream.toString() = " + mmOutStream.toString() + ", mmSocket..toString() = " + mmSocket.toString());

            mmOutStream.write(buffer, 0, size); // This is the call that locks.
            Log.d(this.getClass().getSimpleName(), "After Write");
            mmOutStream.flush(); // Make sure the command is sent entirely immediately
            Log.d(this.getClass().getSimpleName(), "After Flush");


        } catch (IOException e) 
        {
            e.printStackTrace();
        }
    }

    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) 
        {
            e.printStackTrace();
        }
    }
}

編集:

ロックが発生したら、リモート デバイスの電源をオフにしてからオンにBluetoothすると、IO 例外でソケットのロックが解除されます。次に、Bluetoothデバイスに接続しようとすると、Bluetooth java.IOException:Service discovery failed. 元に戻す唯一の方法Bluetoothは、タブレットを再起動することです。

編集#2:

このようなロックが発生した後に手動でソケットを切断すると、例外なく返されます。リモート デバイスの接続ステータスは接続されたままです。ただし、任意のデバイスに接続しようとすると (接続されていたデバイスの電源がオフになっていても、必ずしもロックされたデバイスであるとは限りません)、次の例外が発生します。

09-13 09:34:45.342: E/BT Connection Assert(1864): Service discovery failed
09-13 09:34:45.342: W/System.err(1864): java.io.IOException: Service discovery failed
09-13 09:34:45.342: W/System.err(1864):     at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:397)
09-13 09:34:45.342: W/System.err(1864):     at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:207)
09-13 09:34:45.342: W/System.err(1864):     at com.brioconcept.hit001.communication.bluetooth.BluetoothService$ConnectThread.run(BluetoothService.java:177)

回復する唯一の方法は、タブレットを再起動することのようです。

4

0 に答える 0