0

Bluetooth の問題/Bluetooth タイムアウトに関する多くの質問を見ましたが、どれも役に立ちませんでした。

別の Bluetooth デバイスとの間でデータを送受信するアプリに取り組んでいます。1秒間に約3回送信しています。応答がどのように見えるかを知っています ([FC ... FF] のようなバイト配列)。

BluetoothChat デモに基づいてアプリを構築していますが、BluetoothChatService クラスのコードをほとんど変更しました。

私がしたことは、boolean を返す新しいメソッドを実装することでした (boolean readWrite(byte[] data) と呼びました)。このメソッドでは、最初に出力ストリームに書き込み、次に入力ストリームから読み取ります。書き込みがうまくいった場合はブール値を true に設定し、読み取りがうまくいった場合は別のブール値を true に設定し、応答バイト配列を文字列に変換して、この文字列を応答として設定します。書き込み/読み取りがうまくいかない場合、私のメソッドは false を返します。

ConnectedThread の run() メソッドには、この readWrite メソッドを使用している while(true) ループがあります。次に、String 応答を取得し、応答に応じて別のデータを readWrite() します。

私が実際に何をしているかを理解できるように、ここにいくつかのコードを投稿します。このようにして、ソケットのタイムアウトを取り除き、読み取り/書き込みがうまくいかない場合は接続をリセットしようとしています。以下のようなエラーが表示されますが、それは私のデバイスでしょうか?

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

    public ConnectedThread(BluetoothSocket socket) {
        Log.d(TAG, "create ConnectedThread");
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;
        // Get the BluetoothSocket input and output streams
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
            Log.e(TAG, "temp sockets not created", e);
        }
        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    private boolean readWrite(byte[] data) {
        byte[] read = null;
        int bytes = 0;
        String bc;
        String packet;
        boolean readPacket = false;
        boolean writing = false
        boolean reading = false; 

        try {
            // Log.d(TAG, "write to the device");
            mmOutStream.write(data);
            writing = true; 
        } catch (IOException e) {
            Log.e(TAG, "Exception occurred during write: " + e.getMessage());
            setState(STATE_NONE);
            writing = false; 
        }
        // if writing goes ok 
        if(writing){
            read = new byte[64];
            // the response packet should be a byte array like [FC ... FF]
            while(!readPacket)
            try {
                // Read from the InputStream
                bytes = mmInStream.read();
                bc = String.format("%02x", (0xFF & bytes)).toUpperCase();
                    if(bc.equalsIgnoreCase("fc"))
                    {
                        packet = "";
                        packet += bc;
                    }
                    else if(bc.equalsIgnoreCase("ff"))
                    {
                        readPacket = true;
                        packet += bc; // finish the response packet
                        Log.d(TAG, "read packet -> to UI: " + packet);
                        reading = true;
                        read = null;
                        myBluetoothService.this.setReceivedMessage(packet);
                        packet = "";
                    }
                    else{
                        packet += bc;
                    }
            }
            catch (IOException e) {
                reading = false;
                connectionLost();
                break;
            }
        }
        else return false;
        return (reading&&writing);
    }

    public void run() {
        setName("ConnectedThread");         
        byte[] buffer = new byte[64];
        String globalString = "";
        String requestCommand = "request";          
        buffer = requestCommand.getBytes();

        // Keep listening to the InputStream until an exception occurs
        while (true) {              
            Log.d(TAG, "in the LOOP");
            if(readWrite(buffer))
            {
                // get response from the remoteDevice
                globalString = getReceivedMessage();
                String key = globalString.substring(18, 20); //substract the key pressed on the device
                int keyNum = HexString2Int(key); // convert the string to int
                switch (keyNum) {
                    case 1:
                        // code here
                        break;
                    case 2:
                        // code here
                        break;
                    default:
                        break;
                }
            }else {
                try {
                    Log.d(TAG, "else JOIN - in the LOOP");
                    resetConnection();
                    Thread.currentThread().join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }               
            // pause between the loops
            try {Thread.sleep(300);Log.d(TAG, "300 sleeping time");} catch (InterruptedException e) {e.printStackTrace();}
        } // out of while loop
        try {
            resetConnection();
            Thread.currentThread().join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    } // end run()

    private void resetConnection() {
        setState(STATE_NONE);
        Log.d(TAG, "reset connection");
        if (mmInStream != null) {
            try {mmInStream.close();} catch (Exception e) {Log.d(TAG,"exception in closing inputstream - "  + e.getMessage());}
        }
        if (mmOutStream != null) {
            try {mmOutStream.close();} catch (Exception e) {Log.d(TAG,"exception in closing outputstream - " + e.getMessage());}
        }
        if (mmSocket != null) {
            try {mmSocket.close();} catch (Exception e) {Log.d(TAG,"exception in closing socket - " + e.getMessage());}
        }
    }

    public void cancel() {
        try {
            // close connection socket
            mmSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "close() of connect socket failed - ConnectedThread cancel()", e);
        }
    }
}

これはすべて正常に機能しますが、数分後 (最大 30 分) に次のエラーが発生することがあります。

09-20 10:44:31.270: W/bt-btif(883): dm_pm_timer expires
09-20 10:44:31.270: W/bt-btif(883): dm_pm_timer expires 0
09-20 10:44:31.290: W/bt-btif(883): proc dm_pm_timer expires
09-20 10:44:31.310: E/bt-btif(883): bta_dm_pm_btm_status  hci_status=36

なぜそれが起こるのか誰にも考えがありますか?本当にイライラします。私のデバイスは Android 4.3、ビルド番号 JWR66V の Nexus 7 です。Android 2.3.3 を搭載した別のデバイスでこのアプリをテストしました。ログは異なりますが、ほぼ同じ種類のエラーだと思います。

助けてください!

4

1 に答える 1

2

これと同じ問題があり、0.3 秒ごとにソケットで 1 バイトのデータを送信するキープ アライブ スレッドを作成することで解決しました。更新する前にこの問題は発生していなかったので、問題は新しい Android 4.3 にあると思います..

public class KeepAlive extends Thread{
private ConnectedThread connectedThread;
private final String TAG = "KeepAlive";
private volatile boolean running = true;

public KeepAlive(ConnectedThread connectedThread) {
    this.connectedThread = connectedThread;
    running = true;
}

public synchronized void run() {
    Log.d(TAG,"KeepAlive Thread starting");
    while(running) {

        try {
            wait(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        connectedThread.write('!');
    }
    Log.d(TAG,"KeepAlive Thread closing");
}

public void setRunning(boolean running) {
    this.running = running;
}

}

于 2013-10-02T00:18:23.497 に答える