0

BTシリアル接続から受信するデータは次のとおりです。

0
1
2
3
.
.
.
27
28
29
0
1
2
3
.
.
.
etc

しかし、私が実際に得ているのは、一部のデータが切り取られていることです。このような:

11
12
1
3
14
15
1
6
1
7
18
19
2
0 

BTSerialService.java内

/ ** *このスレッドは、リモートデバイスとの接続中に実行されます。*すべての着信および発信送信を処理します。* /

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

public void run() {
    Log.i(TAG, "BEGIN mConnectedThread");
    byte[] buffer = new byte[1024];
    //final 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(FinalSetting.MESSAGE_READ, bytes, -1, buffer).sendToTarget();

            } catch (IOException e) {
            Log.e(TAG, "disconnected", e);
            connectionLost();
            break;
        }
    }
}

次に、FinalSetting.javaの ケースメッセージで次のように読みます。

case MESSAGE_READ:
                int i;

                byte[] readBuf = (byte[]) msg.obj; 


             // construct a string from the valid bytes in the buffer
                String readMessage = new String(readBuf, 0, msg.arg1);
                Log.i(LOG_TAG, readMessage);

                mTextView.setText(readMessage);
                String [] numbers = readMessage.split("\n");
                int [] intNumber = new int[numbers.length];

                for (String number : numbers) {
                    if(number.trim().length()>0){

                       try{
                           for (i=0;i<numbers.length;i++){
                                intNumber[i] = Integer.valueOf(number.trim());
                                if (intNumber[i]<0 || intNumber[i]>95){
                                    //some action
                                }
                            }
                       } catch (NumberFormatException e){
                        Log.i(LOG_TAG, "Unable to parse integer" + e);
                       }    
                    }

                }

                break;

そして、LogCatが示すもの:

    05-06 17:28:07.079: I/HBAS(15090): 10

05-06 17:28:07.079: I/HBAS(15090): 11

05-06 17:28:07.079: I/HBAS(15090): 12

05-06 17:28:07.969: I/HBAS(15090): 1
05-06 17:28:08.029: I/HBAS(15090): 3

05-06 17:28:09.019: I/HBAS(15090): 14

05-06 17:28:09.979: I/HBAS(15090): 1
05-06 17:28:10.029: I/HBAS(15090): 5

05-06 17:28:10.989: I/HBAS(15090): 16

05-06 17:28:12.009: I/HBAS(15090): 17

05-06 17:28:12.999: I/HBAS(15090): 18

05-06 17:28:13.999: I/HBAS(15090): 19

05-06 17:28:14.999: I/HBAS(15090): 20

05-06 17:28:16.009: I/HBAS(15090): 21

だから誰もがこれを解決する方法を知っていますか?前もって感謝します..

4

1 に答える 1

2

データをもう一度見てください。実際にはすべてを受信して​​います。送信したのと同じサイズのチャンクでデータを受信するという無効な仮定を行っただけです。

05-06 17:28:07.079: I/HBAS(15090): 11
05-06 17:28:07.079: I/HBAS(15090): 12
05-06 17:28:07.969: I/HBAS(15090): 1
05-06 17:28:08.029: I/HBAS(15090): 3

あなたがあなたの「13」を手に入れたのを見てください-それだけが「1」そして次に「3」として入って来ました。

それは完全に許可されており、非常に頻繁に発生すると予想されることがあります。データを再グループ化し、有用な部分に分割するためのいくつかの手段を導入する必要があります。

あなたは送るようなことをすることができます

0011
0012
0013

など、解析を試みる前に常に4バイトのチャンクをアセンブルします。トランスポートが保証されている場合、これは実際に機能しますが、危険を感じます。同期が外れた場合、システムがリセットされるか、ランダムに再びオンになるまで、同期がとれなくなります。しかし、トランスポートが何もドロップまたは再注文しないことが保証されている場合(少なくともそれがあることを警告することなく)、理論的には(エラーハンドラーの外では)おそらく表示されません。

もう1つの一般的なアイデアは、たとえば、データでは発生しない区切り文字を導入することです。

11\n
12\n
13\n

そして、解析を試みる前に、終了する改行を探してください。これには、文字化けしたものを破棄して、見つけた次の改行に同期することで回復できるという利点があります。

最後に、データ内ですべての値が可能である場合があるため、区切り文字/ターミネーター用に1つを予約することはできません。その場合、特別な意味のシーケンスの前にあるエスケープ文字として1つを予約し、それらの特別なシーケンスの1つにエスケープ文字の文字通りの出現を表すようにするのが一般的です。 n "は改行を意味し、"\\"はリテラル\を意味します

編集:ああ、ユーモア、私はそれらを表示させるために二重の円記号をエスケープする必要がありましたが、円記号はありませんn

于 2012-05-07T15:25:46.000 に答える