Comment lire tous les octets ensemble via Bluetooth?

j'ai une application qui utilise le bluetooth pour recevoir des données (bytes) d'un autre périphérique. tout va bien, mais j'ai une petite question sur la réception des octets tous ensemble. Après avoir reçu les bytes je les montre sur un Toast juste pour les tester. Lorsque l'autre périphérique envoie 10 octets ensemble (par exemple:" ABCDEFGHIJ"), le programme va prendre le premier octet" A "seulement et le montrer sur un Toast, puis aller à la deuxième itération et lire les 9 autres octets et afficher" BCDEFGHIJ " sur le Toast. Voici mon code:

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

dans la MainActivity, j'ai:

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

            // ...
        }
    }
};

Comment puis-je recevoir tous les octets ensemble?!

10
demandé sur Eng.Fouad 2012-02-10 20:56:45

5 réponses

Mmm très probablement le coupable est dans la façon dont vous envoyez les messages. Votre receive n'a aucun problème, il recevra autant d'octets (jusqu'à votre 1024) qu'il est écrit.

si vous n'avez aucun contrôle sur la façon dont les messages sont envoyés, vous pouvez probablement lire un byte à la fois et ensuite envoyer un message handler vous lorsque vous frappez un terminator prédéfini. Ex: "ABCDEFGHIJ#" où # est le terminator.

String msg = "";
byte ch;
while((ch=mInStream.read())!='#') {
    bytes++;
    msg+=ch;
}
7
répondu broody 2012-02-10 17:36:05

la connexion bluetooth est basée sur le flux, pas sur le paquet. Il n'y a pas de garantie ou de tentative de préserver la packétisation. Donc, n'importe quel nombre d'écritures peut résulter en un nombre quelconque de lecture, le flux d'octets sont garantis d'être corrects. Si vous avez besoin de détecter des paquets, vous devez fournir votre propre structure de paquet pour envelopper vos données. Par exemple, ajoutez un champ de longueur Avant chaque paquet de données pour que vous puissiez reconstruire du côté de la réception.

5
répondu TJD 2012-02-10 18:36:59

la réponse acceptée de @broody est correcte. Mais si les données lui-même contenant '#', il pourrait être difficile de récupérer les données. Ainsi, la meilleure approche selon moi est d'ajouter '\n 'suivi de ' \R' (ou tout autre caractère qui sont peu susceptibles d'apparaître comme des données Refer ASCII Table) dans l'Appareil qui envoie des données à votre application Android. Il agit simplement comme ligne d'alimentation et marque la fin des données.

Eg: ABCDEFGH\n\r

alors votre code peut être quelque chose comme ceci :

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

j'Espère que ça aide Ce qui concerne

3
répondu trueblue 2014-11-29 08:08:49

À lire tous les octets ensemble, vous avez besoin de séparer les données par "\n" ou "\r" ou "\r\n" dans votre code..

par exemple: si vous souhaitez envoyer des données D'Arduino à L'application Android via Bluetooth:

(code Arduino):

    int count =0;
    int sensorPin = 0;

    void setup()
    {
      Serial.begin(9600);
    }

    void loop()
    {
    int val= analogRead(sensorPin);
      if(val<threshold){ 
         a++; 
      }
      else{
        delay(2);
        count = count + 1;
        Serial.print(count);
        Serial.print("\n");
          }

Et maintenant, pour lire les données envoyées (valeur de la variable 'nombre'), voici le code d'Android Studio:

 private class ConnectedThread extends Thread {
        private final InputStream mmInStream;

        public ConnectedThread(BluetoothSocket socket) {
            InputStream tmpIn = null;

            // Get the input streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream(); // opens the input stream in order to retrieve InputStream objects
            } catch (IOException e) {
            }

            mmInStream = tmpIn;
        }

     public void run() {
        int bytes; // bytes returned from read()
        int availableBytes = 0;

        // Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                availableBytes = mmInStream.available();
                if(availableBytes>0){
                    byte[] buffer = new byte[availableBytes];  // buffer store for the stream
                    // Read from InputStream
                    bytes = mmInStream.read(buffer); // Get number of bytes and message in "buffer"
                    if (bytes>0){
                        h.obtainMessage(RECEIVE_MESSAGE, bytes, -1, buffer).sendToTarget();     // Send to message queue Handler
                    }
                   }
                } catch (IOException e) {
                break;
                        }
        }
    }

Et ça:(dans onCreate () (méthode):

mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
// The Handler that gets information back
 h = new Handler() { // Handler-->used to communicate b/w UI & BG Thread
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                    case RECEIVE_MESSAGE:// if receive message
                        byte[] readBuf = (byte[]) msg.obj;
                       String strIncom = new String(readBuf, 0, msg.arg1); // create string from bytes array

                        sb.append(strIncom);                                                // append string
                        int endOfLineIndex = sb.indexOf("\n");                            // determine the end-of-line
                        if (endOfLineIndex > 0) {                                            // if end-of-line,
                            String sbprint = sb.substring(0, endOfLineIndex);               // extract string
                            sb.delete(0, sb.length());// and clear
                            Toast.makeText(ledControl.this,sbprint,Toast.LENGTH_SHORT).show();
                            footSteps.setText(sbprint);            // update TextView
                        }
                        break;
                }}};
1
répondu Vivek Thakkar 2018-04-02 17:44:33

un moyen de gérer les messages plus longs que le tampon (peut être dangereux car il peut prendre votre mémoire s'il n'est jamais effacé) est de les traiter en morceaux:

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;
    }
}
-1
répondu d.popov 2014-05-20 17:59:35