Does Bluetooth SPP get some packet packet that might get lost or?

I am using Android example code to modify. Just want to get the package but my code changes here only

private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_STATE_CHANGE: if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1); switch (msg.arg1) { case BluetoothChatService.STATE_CONNECTED: mTitle.setText(R.string.title_connected_to); mTitle.append(mConnectedDeviceName); mConversationArrayAdapter.clear(); break; case BluetoothChatService.STATE_CONNECTING: mTitle.setText(R.string.title_connecting); break; case BluetoothChatService.STATE_LISTEN: case BluetoothChatService.STATE_NONE: mTitle.setText(R.string.title_not_connected); break; } break; case MESSAGE_WRITE: byte[] writeBuf = (byte[]) msg.obj; // construct a string from the buffer String writeMessage = new String(writeBuf); mConversationArrayAdapter.add(writeMessage); break; 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); //String readMessage = BytesTrans_fill.bytesToHexString(readBuf); Log.d("read", BytesTrans.bytes2HexString(readBuf,msg.arg1)); String readMessage = BytesTrans.bytes2HexString(readBuf,msg.arg1); ppV.setText(ppV.getText().toString() + readMessage + "★"); break; case MESSAGE_DEVICE_NAME: // save the connected device name mConnectedDeviceName = msg.getData().getString( DEVICE_NAME); Toast.makeText(getApplicationContext(), "Connected to " + mConnectedDeviceName, Toast.LENGTH_SHORT).show(); break; case MESSAGE_TOAST: Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), Toast.LENGTH_SHORT).show(); break; } } }; 

and BluetoothChatService

  public void run() { Log.i(TAG, "BEGIN mConnectedThread"); 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(BluetoothChat.MESSAGE_READ, bytes, -1, buffer) .sendToTarget(); } catch (IOException e) { Log.e(TAG, "disconnected", e); connectionLost(); break; } } } 

and add this function

 package com.example.android.BluetoothChat; public class BytesTrans { public static String byte2HexString(byte b) { String ret = ""; String hex = Integer.toHexString(b & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } ret += hex.toUpperCase() + " "; return ret; } public static String bytes2HexString(byte[] b, int count) { String ret = ""; for (int i = 0; i < count; i++) { String hex = Integer.toHexString(b[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } ret += hex.toUpperCase() + " "; } return ret; } /*public static String String2byte(String b) { String[] ttt; for (int i = 0; i < b.length(); i++) { for (int j= i; j<=i+1; j++) { ttt[i] = b; } } String ttmp = ""; String tmp = ""; ret += tmp; }*/ public static int hexToTen(String b) { int D2 = Integer.parseInt(b,16); return D2; } } 

but this program sometimes even displays my sending package

I send the package as follows:

aa072108200012021409343900000000000000000000000000000000000000000000000297c0fe6b

but someday get the package:

aa000297c0fe6b02131452470000000000000000000000000000000000000000000297c0fe6b

how can i change my code to get a full frame packet

+4
source share
2 answers

You did not enter any code for your Bluetooth interface. However, if this is strongly related to the BluetoothChat example, then there is a simple problem with the BluetoothChat example: in principle, when read() is created from a Bluetooth socket and placed in an array of bytes, this array link is sent to the user interface using Handler , as you do . The actual problem is that if the BluetoothChat example is used to receive data at a speed of something faster than typing speed, then you start to see that the characters disappear or become messy, because the subsequent read() overwrites the array while the user interface is all it remains to read the array to retrieve the last group of characters received.

So, if your MESSAGE_WRITE object contains a reference to the array into which you insert read() sockets, then this is probably why you are losing characters. So try sending a copy of the array using Arrays.copyOf() in Message . Or maybe there is a circular buffer that you could use.

I had exactly this problem when I used the BluetoothChat example as the basis for my project. What I personally did to get around the problem (and eliminate the need to copy buffers, etc.) was to implement a mechanism by which I would talk about the Bluetooth connection stream (the stream that contains the blocking socket .read() ), by calling the method, how many bytes I expect from the response (fortunately, the protocol I'm dealing with allows you to find out the length of the response). The connection thread then sends a Message when a full response is received, instead of sending multiple Message with response fragments to the user interface.

+2
source

Here is my solution using the Android Chat sample code. This is only a possible solution. I get messages ending in \n . I use this stream to read messages from Arduino related Bluetooth. On Arduino, I can guarantee that every message ends with \n using Serial.println( buffer ); .

Everything I got is added to the existing line ( queue variable). When I have a whole line on this large line, I send it to the action and remove it from the queue variable.

  public void run() { Log.i(TAG, "BEGIN mConnectedThread"); byte[] buffer = new byte[1024]; int bytes, pos; StringBuilder queue = new StringBuilder(""); String temp; // Keep listening to the InputStream while connected while (true) { try { bytes = mmInStream.read(buffer); if (bytes > 0) { String readMessage = new String(buffer, 0, bytes); queue.append(readMessage); pos = queue.indexOf("\n"); while (pos >= 0) { // Log.d("Temperatura", "indexOf() #" + pos); temp = queue.substring(0, pos - 1); queue.delete(0, pos + 1); mHandler.obtainMessage(Constants.MESSAGE_READ, 0, 0, temp).sendToTarget(); pos = queue.indexOf("\n"); } } } catch (IOException e) { Log.e(TAG, "disconnected", e); connectionLost(); // Start the service over to restart listening mode BluetoothChatService.this.start(); break; } } } 
0
source

Source: https://habr.com/ru/post/1396330/


All Articles