Autore Topic: Funzione read bluetooth incompleta  (Letto 792 volte)

Offline ste9206

  • Nuovo arrivato
  • *
  • Post: 23
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy S4
  • Sistema operativo:
    Windows 8
Funzione read bluetooth incompleta
« il: 17 Dicembre 2014, 11:09:04 CET »
0
Ciao a tutti, sono nuovo nel forum. Devo implementare la comunicazione tra un dispositivo android e un dispositivo bluetooth. Il dispositivo invia una sequenza di stringhe, io volevo far visualizzare tutte le stringhe in una textview o comunque in una casella di testo che mi faccia visualizzare tutte le stringhe. Io la funzione l'ho implementata cosi, tuttavia mi visualizza solo la prima stringa e non quelle successive (ogni secondo il dispositivo invia una stringa, e sul cellulare mi vede solo la prima). L'implementazione è questa:
Codice (Java): [Seleziona]
public void Ricevi (View v)
{
 byte[] buffer = new byte[1024];
     int bytes;
     String s = null;
     s= "Received message: ";
         try
         {
             do
             {
                 bytes = mIn.read(buffer); //mIn è l'inputstream
                 if (bytes != -1)
                 {
                     s = new String(buffer, 0, bytes);
                     tx2.setText(s + "\n");
                     tx2.setTextColor(Color.BLUE);
                     }
             } while(s== null);

         }
         catch(IOException e) {}

     }
}

avevo provato con un while (true) ma l'applicazione si blocca non appena premo il pulsante "Ricevi".
Cosa devo modificare in modo che mi visualizzi tutte e quante le stringhe che riceve?

Offline tonno16

  • Utente storico
  • *****
  • Post: 1184
  • Respect: +57
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:Funzione read bluetooth incompleta
« Risposta #1 il: 17 Dicembre 2014, 11:55:29 CET »
0
Penso devi usare un thread e non un whle(true)

Offline ste9206

  • Nuovo arrivato
  • *
  • Post: 23
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy S4
  • Sistema operativo:
    Windows 8
Re:Funzione read bluetooth incompleta
« Risposta #2 il: 17 Dicembre 2014, 12:29:22 CET »
0
Grazie per la risposta, volevo chiedere: cosa cambia tra un thread e un while (true)? siccome sono alle prime armi non avevo ben capito perchè dovevo usare un thread (ho preso esempio dalla bluetoothchat)...

Offline tonno16

  • Utente storico
  • *****
  • Post: 1184
  • Respect: +57
    • Mostra profilo
  • Dispositivo Android:
    moto g
  • Play Store ID:
    Diego Tonini
  • Sistema operativo:
    OpenSuse
Re:Funzione read bluetooth incompleta
« Risposta #3 il: 17 Dicembre 2014, 12:58:21 CET »
0
La differenza è abissale. È alla base di ogni linguaggio di programmazione. Io ti consiglio di studiare ancora e poi applicarti su android.

Per un operazione lunga, non puoi usare il thread principale. Devi crearne uno parallelo. Cosi il main thread continua la sua esecuzione senza aspettare il thread creato

Offline ste9206

  • Nuovo arrivato
  • *
  • Post: 23
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy S4
  • Sistema operativo:
    Windows 8
Re:Funzione read bluetooth incompleta
« Risposta #4 il: 17 Dicembre 2014, 14:11:22 CET »
0
Grazie, non lo sapevo...ma quindi mi basta utilizzare un thread e togliere quel ciclo? E devo mettere in un thread anche la write( ) del bluetooth?

Offline wlf

  • Utente normale
  • ***
  • Post: 319
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:Funzione read bluetooth incompleta
« Risposta #5 il: 17 Dicembre 2014, 14:49:41 CET »
0
Grazie, non lo sapevo...ma quindi mi basta utilizzare un thread e togliere quel ciclo? E devo mettere in un thread anche la write( ) del bluetooth?

Io aggiungerei un AsyncTask e in questo ci infilerei le chiamate alla tua Ricevi() ed eventualmente Write().

Offline ste9206

  • Nuovo arrivato
  • *
  • Post: 23
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy S4
  • Sistema operativo:
    Windows 8
Re:Funzione read bluetooth incompleta
« Risposta #6 il: 17 Dicembre 2014, 16:05:55 CET »
0
Ho visto su developers.android che la funzione svolta col thread ha anche un handle...ma è necessario? Ho provato a implementarla cosi ma mi si blocca quando clicco sul bottone esattamente allo stesso modo di quando la implementavo col while...

Mi riferisco a questo:
Codice (Java): [Seleziona]
 public void run() {
        byte[] buffer = new byte[1024];  // buffer store for the stream
        int bytes; // bytes returned from read()
 
        // Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);
                // Send the obtained bytes to the UI activity
                mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                break;
            }
        }
    }

Un'altra domanda: se devo leggere solo una sequenza di caratteri il thread è necessario?
« Ultima modifica: 17 Dicembre 2014, 16:16:47 CET da ste9206 »

Offline wlf

  • Utente normale
  • ***
  • Post: 319
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:Funzione read bluetooth incompleta
« Risposta #7 il: 17 Dicembre 2014, 16:25:58 CET »
0
Un'altra domanda: se devo leggere solo una sequenza di caratteri il thread è necessario?

Il punto non è quante sequenze o la lunghezza della sequenza che devi leggere, è il tempo necessario che ci vuole. Il thread principale dovrebbe rimanere in attesa senza darti la possibilità di fare alcunché; è per questo che è necessario avviare un thread parallelo. ;)

Offline ste9206

  • Nuovo arrivato
  • *
  • Post: 23
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy S4
  • Sistema operativo:
    Windows 8
Re:Funzione read bluetooth incompleta
« Risposta #8 il: 17 Dicembre 2014, 17:52:46 CET »
0
Grazie, ora che lo so mi sarà molto utile  ;-) per quanto riguarda l'handle, è proprio necessario?

Offline wlf

  • Utente normale
  • ***
  • Post: 319
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:Funzione read bluetooth incompleta
« Risposta #9 il: 17 Dicembre 2014, 18:28:22 CET »
0
per quanto riguarda l'handle, è proprio necessario?

Dipende da quello che vuoi fare e come intendi gestirlo; io ho realizzato un app che comunica col bluetooth ed ho utilizzato un ciclo while () però prima faccio partire un Timer con un certo timeout che passo alla mia funzione ed interrompo il ciclo while o quando termina la ricezione del dato oppure al timeout in caso non arrivi nulla perché il dispositivo collegato potrebbe essere stato spento o si potrebbe essere bloccato.

Per capire se il dispositivo collegato ha finito di inviarti dati come fai? Quando fai la read dell'InputStream sei sicuro di leggere tutto il contenuto dei dati inviati? Leggi si un blocco da 1k ma potrebbe essere ancora in fase di trasmissione ...
Io per capire se ha finito o meno ho un carattere di terminazione, un delimitatore che mi dice se ho finito o meno di leggere, se non trovo tale carattere devo fare nuovamente una read dell'InputStream.

Offline ste9206

  • Nuovo arrivato
  • *
  • Post: 23
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy S4
  • Sistema operativo:
    Windows 8
Re:Funzione read bluetooth incompleta
« Risposta #10 il: 17 Dicembre 2014, 18:40:01 CET »
0
Il dispositivo che trasmette è un gps fix (o penso che si chiami cosi  :D) che ogni secondo invia una sequenza di stringhe, che comunicano per esempio la posizione e dati aggiuntivi..avevo pensato anche io al timer o a un delimitatore, però l'unico modo per farlo smettere di trasmettere è disattivare il bluetooth oppure interrompere la connessione...l'app in pratica dovrebbe visualizzare ogni secondo le stringhe che invia il dispositivo..

Offline wlf

  • Utente normale
  • ***
  • Post: 319
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:Funzione read bluetooth incompleta
« Risposta #11 il: 18 Dicembre 2014, 09:25:48 CET »
0
Il dispositivo che trasmette è un gps fix (o penso che si chiami cosi  :D)

E' una di quelle "scatolette" o antenne bluetooth esterne che venivano utilizzate a suo tempo dai telefoni sprovvisti di GPS immagino ...

Citazione
che ogni secondo invia una sequenza di stringhe, che comunicano per esempio la posizione e dati aggiuntivi..

Non sono del tutto convinto che l'invio delle stringhe sia cadenzato ogni secondo, a mio avviso lo invia ad ogni cambiamento di posizione, ma visto che anche tenendola immobile ogni fix con i satelliti da dei risultati leggermente diversi il risultato è che ti invia le stringhe ogni secondo. :)

Citazione
avevo pensato anche io al timer o a un delimitatore,

Con un timer rischi di troncare una stringa, sarebbe meglio cercare di interpretare la struttura dei dati che ricevi controllando se è fissa, se c'è magari un delimitatore o quant'altro.

Citazione
però l'unico modo per farlo smettere di trasmettere è disattivare il bluetooth oppure interrompere la connessione...

Oppure potresti tranquillamente più semplicemente ignorare quello che ti arriva sull'InputStream.

Citazione
l'app in pratica dovrebbe visualizzare ogni secondo le stringhe che invia il dispositivo..

Quello che vuoi visualizzare è già possibile farlo con alcune App già presenti sul play ...

Offline ste9206

  • Nuovo arrivato
  • *
  • Post: 23
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy S4
  • Sistema operativo:
    Windows 8
Re:Funzione read bluetooth incompleta
« Risposta #12 il: 18 Dicembre 2014, 09:51:05 CET »
0
Si è una scatoletta di quelle :D comunque il mio obiettivo è quello di ricevere tutti i messaggi che mi invia una radio via bluetooth..ora ho provato a implementarlo con i thread, e ho modificato la struttura:
Codice (Java): [Seleziona]
private class ConnectedThread extends Thread
    {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

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

            try
            {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            }
            catch (IOException e) { }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        public void read()
        {
            byte[] buffer;
            int bytes;

                try
                {
                    buffer = new byte[1024];
                    bytes = mmInStream.read(buffer);
                    mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
                }
                catch (IOException e)
                {

                }

        }

        public void write(byte[] bytes)
        {
            try
            {
                mmOutStream.write(bytes);
            }
            catch (IOException e) { }
        }
}
questo per quanto riguarda il thread, sull'handle:

Codice (Java): [Seleziona]
Handler mHandler = new Handler(){
        public void handleMessage(Message msg)
        {
            super.handleMessage(msg);
            switch(msg.what)
            {
                case SUCCESS_CONNECT:
                   
                    ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
                    TextView tx = (TextView) findViewById(R.id.textView2);
                    tx.setText("CONNESSO");
                    tx.setTextColor(Color.GREEN);

                    break;

                case MESSAGE_READ:

                    byte[]readBuf = (byte[])msg.obj;
                    String string = new String(readBuf);

                    TextView tx2 = (TextView) findViewById(R.id.textView2);
                    tx2.setText(readBuf + "\n");
                    tx2.setTextColor(Color.BLUE);

                    break;
            }
        }
ora sembra funzionare, quando premo sul bottone "ricevi messaggio" si mette "in ascolto" e quando invio un messaggio dalla radio lo riceve, ma è completamente errato  :'( è solo un problema di traduzione da byte a stringa oppure manca qualcosa a livello implementativo?

per wlf: ma se volessi mettere un timer, tipo 500 secondi e poi si interrompe la lettura e la connessione, devo implementarlo cosi?
Codice (Java): [Seleziona]
Message msg = mHandler.obtainMessage(SUCCESS_CONNECT,mSocket);
handler.sendMessageAtTime(msg, System.currentTimeMillis()+500000);
handler.sendMessageDelayed(msg, 500000);

Offline wlf

  • Utente normale
  • ***
  • Post: 319
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:Funzione read bluetooth incompleta
« Risposta #13 il: 22 Dicembre 2014, 09:59:15 CET »
0
Io il colloquio con il bluetooth l'ho implementato con un AsyncTask, non come hai fatto tu.

Per fare la write di una stringa io sono passato dal PrintWriter.

Codice: [Seleziona]
                        PrintWriter out = new PrintWriter(mmOutputStream, true);
                        out.write(StringCmd);
                        out.flush();

Per la ricezione ho usato un timer che mi valorizza un booleano che controllo nella read con un ciclo while. Io però ho anche un "delimiter", quindi esco dal ciclo while se ho il delimitatore oppure al timeout. Senza delimitatore usciresti sempre per timeout.