IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API standards et tierces Android Discussion :

pousser une ecriture dans une bluetooth socket


Sujet :

API standards et tierces Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2008
    Messages : 289
    Par défaut pousser une ecriture dans une bluetooth socket
    bonjour,
    j'écris une appli qui doit se connecter à un module HC-05 relié par sa ligne à un Raspberry. Pour l'instant, le test unitaire doit émettre un string vers le Raspberry qui répond par une autre string.
    Je me suis largement inspiré de l'exemple de Brian Wirsing.
    Mon code:
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
     
            //Android supporte le bluetooth? recherche de l'adaptateur bluetooth
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            if(mBluetoothAdapter == null) {
                //Device does not support bluetooth
                Context context = getApplicationContext();
                CharSequence text = "Device support bluetooth";
                int duration = Toast.LENGTH_SHORT;
                Toast toast = Toast.makeText(context, text, duration);
                toast.show();
            }
     
            if(!mBluetoothAdapter.isEnabled()) {
                Context context = getApplicationContext();
                CharSequence text = "BluetoothAdapter is not enable!";
                int duration = Toast.LENGTH_SHORT;
                Toast toast = Toast.makeText(context, text, duration);
                toast.show();
                //lancer un Intent pour activer le bluetooth
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, 1);
            }
     
            //Discovering devices. Register for broadcasts when a device is discovered.
            IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
            //Enregistrer le broadcast receiver
            registerReceiver(mReceiver, filter);
            //lancer la découverte. Si on découvre, on passe dans le BroadcastReceiver
            mBluetoothAdapter.startDiscovery(); //lance un intent? Android envoie l’intention à tous les BroadCast Receiver abonnées
     
            //Querying paired devices: la requête peut être nulle si aucun appareil n'est appairé
            Set<BluetoothDevice> setpairedDevices = mBluetoothAdapter.getBondedDevices();
            BluetoothDevice[] pairedDevices = (BluetoothDevice[])setpairedDevices.toArray(new BluetoothDevice[setpairedDevices.size()]);
            if (pairedDevices.length > 0) {
                // There are paired devices. Get the name and address of each paired device.
                for(int i=0;i<pairedDevices.length;i++) {
                    if (pairedDevices[i].getName().contains("HC-05-AA")) {
                        mDevice = pairedDevices[i];
                    }
                }
                Log.d("BONDED TO", mDevice.getName()+" "+mDevice.getAddress());
            }
            else Log.d("QUERYING", "NO BONDED DEVICES");
     
            //A ce niveau, on connaît le device avec lequel on va travailler
            mConnectThread = new ConnectThread(mDevice);
            mConnectThread.start();
        }
     
        @Override
        protected void onDestroy() {
            super.onDestroy();
            // Don't forget to unregister the ACTION_FOUND receiver.
            unregisterReceiver(mReceiver);
        }
     
        private class ConnectThread extends Thread {
            private final BluetoothSocket mmSocket;
            private final BluetoothDevice mmDevice;
            private final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
            private String TAG = "Socket";
     
            //constructeur
            public ConnectThread(BluetoothDevice device) {
                BluetoothSocket tmp = null;
                mmDevice = device;
                Method m;
                try {
                    m = mDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
                    tmp = (BluetoothSocket) m.invoke(mDevice, 1);
                } catch (SecurityException e) {
                    Log.e(TAG, "create socket failed", e);
                } catch (NoSuchMethodException e) {
                    Log.e(TAG, "create socket failed", e);
                } catch (IllegalArgumentException e) {
                    Log.e(TAG, "create socket failed", e);
                } catch (IllegalAccessException e) {
                    Log.e(TAG, "create socket failed", e);
                } catch (InvocationTargetException e) {
                    Log.e(TAG, "create socket failed", e);
                }
                mmSocket = tmp;
            }
     
            public void run() {
                mBluetoothAdapter.cancelDiscovery();
                try {
                    mmSocket.connect();
                } catch (IOException connectException) {
                    Log.e("connectException", "Run");
                    connectException.printStackTrace();
                    try {
                        mmSocket.close();
                    } catch (IOException closeException) {
                        Log.e("closeException", "Run");
                        closeException.printStackTrace();
                    }
                    return;
                }
                mConnectedThread = new ConnectedThread(mmSocket);
                mConnectedThread.start();
            }
     
            public void cancel() {
                try {
                    mmSocket.close();
                } catch (IOException e) { }
            }
        }
     
        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) {
                    Log.e("ConnectedThread", "Stream");
                }
                mmInStream = tmpIn;
                mmOutStream = tmpOut;
            }
     
            public void run() {
                //emettre
                String cmd = new String("Bluetooth --> ");
                write(cmd.getBytes());
            }
            public void write(byte[] bytes) {
                try {
                    Log.e("Write", bytes.toString());
                    mmOutStream.write(bytes);
                    mmOutStream.flush();
                } catch (IOException e) { }
            }
     
            public void cancel() {
                try {
                    mmSocket.close();
                } catch (IOException e) { }
            }
        }
    Sur mon téléphone, quand je lance ce code, le programme en réception côté PI ne voit rien arriver.
    Je ferme et lance Bluetooth Terminal, me connecte au HC-05, entre une chaîne quelconque et appui sur send...
    Côté PI je vois s'afficher Bluetooth --> suivi de ce que j'ai entré précédemment.

    J'en déduis que le résultat de ma ligne write(cmd.getBytes()); est bufferisé quelque part dans le téléphone et émise par Blutooth Terminal qui s'y prend plus proprement que moi.

    Bonne déduction ou mystère plus profond ???

    Merci.

  2. #2
    Membre chevronné Avatar de Drowan
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2014
    Messages
    460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2014
    Messages : 460
    Par défaut

    Cela vient surement du fait que ta connexion n'est soit pas établie correctement soit que tu n'as pas attendu que la connexion soit mise en place.
    Au vu de ton code c'est assez étrange, tu n'utilise aucun listener ou receiver, or tout se fait en asynchrone donc ça me semble plutot normal que ça ne fonctionne pas.
    Essaye de suivre la documentation android pour faire ça, c'est tout détaillé : ici

  3. #3
    Membre éclairé
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2008
    Messages : 289
    Par défaut
    bonjour et merci pour ta réponse.
    j'ai repris le projet et progressé. Mon téléphone émet correctement sa requête vers le Raspberry via le HC-05 et la liaison série et le serveur qui y tourne répond systématiquement par "bien recu ;-)". Mon pb est maintenant la réception correcte de la réponse qui est aléatoire pour l'instant.
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    public void run() {
        byte[] buffer = new byte[1024];
        int begin = 0;
        int nb = 0;
     
        while (true) {
            try {
                nb = mmInStream.read(buffer, begin, buffer.length);
    	    Log.e("Buffer size", String.valueOf(nb));
                Log.e("Buffer content", buffer.toString());
                mHandler.obtainMessage(1, begin, nb, buffer).sendToTarget();  //passer le message au handler du threadUI
    	    ----
    	}
        }
    }
     
    public void write(byte[] bytes) {
        try {
    	Log.e("Write bytes", bytes.toString());
            mmOutStream.write(bytes);
            mmOutStream.flush();
        } catch (IOException e) { }
    }
    Ce code tourne dans un thread qui communique par un handler avec le threadUI pour faire de l'affichage dans un TextView. Dans ce TextView je reçois "recu ;-)", partie du message initial.

    Le résultat des Log donne ça:
    Write: Bluetooth //appel de la méthode write() du thread
    Write*bytes: [B@41aef4d8
    Buffer*size: 1
    Buffer*content: [B@41aca278
    Buffer*size: 9
    Buffer*content: [B@41aca278
    Buffer*size: 10
    Buffer*content: [B@41aca278
    Buffer*size: 6
    Buffer*content: [B@41aca278
    handleMessage*begin: 0 //affichage dans le handler
    handleMessage*size: 1
    handleMessage*begin: 0
    handleMessage*size: 9
    recu����������������
    handleMessage*begin: 0
    handleMessage*size: 10
    recu�������������������������������
    handleMessage*begin: 0
    handleMessage*size: 6
    recu��������������������������������

    Hormis le pb d'affichage, je ne comprend pas pourquoi on passe plusieurs fois dans le read() du run alors que le serveur ne fait qu'un seul write (j'ai vérifié avec un scope numérique sur la ligne Tx). En plus avec une valeur de siez toujours différente alors que le contenu ne varie pas.

    Une idée ? Merci.

  4. #4
    Membre chevronné Avatar de Drowan
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2014
    Messages
    460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2014
    Messages : 460
    Par défaut
    Au vu de la doc de InputStream.read() et de ton code, peut-être que tu lis trop vite.
    C'est à dire que lors du premier appel de read(), il n'y a que 1 caractère (sur tout ceux envoyer) qui est arrivé dans ton InputStream. read() a donc quelque chose à lire et le fait. Mais comme le message n'est pas complet elle ne te retourne qu'un caractère. Puis au tour d'après rebelote seul 9 caractères suplémentaires sont arrivés. Ceci expliquerais les tailles différentes et les multiples appels à read().

    Combien de caractère envoie tu au total ? Si c'est plus de 26 (10+9+6+1) alors le problème est surement là. Essaye d'ajouter un délai d'attente dans ta boucle (Thread.sleep(10) par exemple)

    Pour l'affichage c'est peut-etre un problème d'encodage

  5. #5
    Membre chevronné Avatar de Drowan
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2014
    Messages
    460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2014
    Messages : 460
    Par défaut
    Par ailleurs je te déconseille le while(true) notamment à l'intérieur d'un thread. C'est un coup à laisser un thread vivant sans y avoir accès pour le tuer.
    Essaye une condition qui vérifie que tu es toujours connecté.

    Plus d'information sur les problèmes de threads laissé vivants : ici

Discussions similaires

  1. [XL-2007] Afficher une checkbox dans une feuille si une checkbox d'une autre feuille est cochée
    Par JessieCoutas dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 18/08/2009, 13h35
  2. portée d'une variable dans une fonction dans une méthode
    Par laurentg2003 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/06/2009, 19h05
  3. [POO] dans une classe, appeler une fonction dans une méthode
    Par arnaudperfect dans le forum Langage
    Réponses: 3
    Dernier message: 26/08/2007, 23h04
  4. Envoyer une formulaire dans une page dans une Frame
    Par zooffy dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 29/06/2007, 10h13
  5. Recherche une valeur d'une cellule dans une colonne d'une autre feuille
    Par kourria dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 21/06/2007, 13h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo