Как читать все байты вместе через Bluetooth?

У меня есть приложение, которое использует bluetooth для приема некоторых данных (байтов) с другого устройства. Все идет хорошо, но у меня есть небольшая проблема по получению байтов. После получения байтов я показываю их на тосте только для их проверки. Когда другое устройство отправляет 10 байтов вместе (например, «ABCDEFGHIJ»), программа будет принимать только первый байт «А» и показывать его на тосте, затем перейти ко второй итерации и прочитать остальные 9 байтов и показать « BCDEFGHIJ "на тосте. Вот мой код:

byte[] buffer = new byte[1024]; // Read 1K character at a time. int bytes = 0; // Number of bytes. while(true) { try { // Read from the InputStream. bytes = bInStream.read(buffer); // Send the obtained bytes to the MainActivity. mainActivityHandler.obtainMessage(MainActivity.MESSAGE_READ, bytes, -1, buffer).sendToTarget(); } catch(IOException e) { connectionLost(); break; } } 

В MainActivity у меня есть:

 // The Handler that gets information back from the BluetoothManager. private final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch(msg.what) { case MESSAGE_READ: byte[] readBuf = (byte[]) msg.obj; // construct a string from the valid bytes in the buffer. String readMessage = new String(readBuf, 0, msg.arg1); Toast.makeText(MainActivity.this, readMessage, Toast.LENGTH_SHORT).show(); break; // ... } } }; 

Как я могу получить все байты вместе?

Solutions Collecting From Web of "Как читать все байты вместе через Bluetooth?"

Ммм, скорее всего, виновник находится в том, как вы отправляете сообщения. У вашего получателя нет проблем, он будет получать столько байтов (до вашего 1024), сколько написано.

Если у вас нет контроля над тем, как отправляются сообщения, вы, вероятно, можете читать по одному байту за раз, а затем отправлять сообщение обработчика вам, когда вы нажимаете предопределенный терминатор. Пример: «ABCDEFGHIJ #», где # – это терминатор.

 String msg = ""; byte ch; while((ch=mInStream.read())!='#') { bytes++; msg+=ch; } 

Соединение Bluetooth основано на потоке, а не на базе пакетов. Нет гарантии или попытки сохранить пакетирование. Таким образом, любое количество записей может привести к любому количеству чтений, только поток байтов гарантированно будет правильным. Если вам нужно обнаружить пакеты, вам необходимо предоставить свою собственную структуру пакетов, чтобы обернуть ваши данные. Например, добавьте поле длины перед каждым пакетом данных, чтобы вы могли восстановить на принимающей стороне.

Принятый ответ от @broody правильный. Но если сами данные содержат «#», может быть сложно получить данные. Таким образом, лучший подход по моему мнению заключается в добавлении '\ n', за которым следует '\ r' (или любые другие символы, которые вряд ли будут отображаться как данные, см. Таблицу ASCII ) на устройстве, которое отправляет данные в ваше приложение для Android. Он просто действует как фид строки и отмечает конец данных.

Например: ABCDEFGH \ n \ r

Тогда ваш код может выглядеть примерно так:

 byte[] buffer = new byte[1024]; while (true) { // Read from the InputStream buffer[bytes] = (byte) mmInStream.read(); // Send the obtained bytes to the UI Activity if ((buffer[bytes] == '\n')||(buffer[bytes]=='\r')) { mHandler.obtainMessage(MainActivity.MESSAGE_READ, bytes, -1, buffer).sendToTarget(); bytes=0; } else bytes++; } 

Надеюсь, это поможет

Способ обработки сообщений с более длинным буфером (может быть опасным, потому что может занимать вашу память, если он не очищается) – обрабатывать их в кусках:

 String inString = ""; byte[] buffer = new byte[1024]; // buffer store for the stream int bytes; // bytes returned from read() while (true) { try { bytes = mmInStream.read(buffer); String chunk = new String(buffer, 0, bytes); if(chunk.contains(";")) { inString += chunk.substring(0,chunk.indexOf(';')); Message msg = new Message(); msg.obj = inString; handler.sendMessage(msg); inString = chunk.substring(chunk.indexOf(';')); } else { inString += chunk; } } catch (IOException e) { break; } }