Partage
  • Partager sur Facebook
  • Partager sur Twitter

[ANDROID] Bluetooth sur android studio

    14 septembre 2017 à 11:24:49

    Bonjour! 

    Je cherche à envoyer un byte par bluetooth à l'aide d'une application réalisée sous android Studio. 

    Malheureusement j'ai un soucis que je n'arrive pas à régler. Il me semble tout bête mais je n'ai pas trouvé de documentation dessus...

    L'idée de l'App : Je choisis, à l'aide d'un spinner, un genre (homme/femme). Le choix est relié à une variable via une énumération. J'ai aussi une class BTInterface qui sert à envoyer et recevoir des informations en bluetooth (je m'en fiche de recevoir mais j'ai suivi un tuto sur youtube donc j'ai tout simplement recopié). Finalement j'ai un bouton "enregistré" qui est censé envoyer la variable sélectionné. Entre temps j'ai transformé mon int en byte pour correspondre au critère de mon envoie de donnée. La partie connexion et appareillage n'est pas géré par l'app. L'utilisateur doit se débrouiller pour avoir un smartphone avec bluetooth et s'appareiller à un module bluetooth. Je vous laisse découvrir mon code : 

    Main : 

    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.Button;
    import android.widget.Spinner;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
    
        public static final String TAG = "MainActivity";
    
        //définition classe BtInterface
        BtInterface mBtInterface;
    
        //définition du button
        Button button1;
    
        //initialisation de la variable var
        public int var = 0;
    
        //création de l'objet Spinner
        Spinner spinner1;
    
        //pour ajouter des datas dans un spinner, on a besoin d'un "adapteur"
        ArrayAdapter<CharSequence> adapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
    
            //initialisation des objets Spinner
            spinner1 = (Spinner) findViewById(R.id.spinner1);
    
            //on set les valeurs des énumérations dans le  spinner grâce à ArrayAdapter
            spinner1.setAdapter(new ArrayAdapter<MyEnum1>(this, android.R.layout.simple_spinner_item, MyEnum1.values()));
    
            //création de l'évènement qui va gérer le spinner1
            spinner1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
    
                    var = ((MyEnum1) parent.getItemAtPosition(position)).getA();
    
                }
    
                @Override
                public void onNothingSelected(AdapterView<?> parent) {
    
                }
            });
    
            final byte varbyte = (byte)var;
    
            button1 = (Button) findViewById(R.id.button2);
    
            button1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    Toast.makeText(MainActivity.this, "var = "+var, Toast.LENGTH_SHORT).show();
                    byte[] bytes = varbyte;
                    mBtInterface.write(bytes);
    
                }
            });
    
        }
    
    }


    xml associé : 

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="20dp">
    
    
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:text="Je suis?"
            android:textSize="25sp"
            android:textStyle="bold" />
    
    
        <Spinner
            android:id="@+id/spinner1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="sélectionner genre"/>
    
    
        <Space
            android:layout_width="match_parent"
            android:layout_height="20dp"></Space>
    
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">
    
            <Button
                android:id="@+id/button2"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:padding="20dp"
                android:text="Enregistrer"
                android:textSize="18sp" ></Button>
    
        </FrameLayout>
    
    
    </LinearLayout>
    

    Mon énumération (MyEnum1) :

    public enum MyEnum1 {
    
        Boy("homme",  1),
        Girl("femme", 0);
    
        private final String label;
    
        public final int a;
    
        private MyEnum1(String label, int a){
            this.a = a;
            this.label = label;
        }
    
        @Override
        public String toString(){
            return label;
        }
    
        public int getA(){
            return a;
        }
    
    }
    

    Ma class BTInterface : 

    import android.app.ProgressDialog;
    import android.bluetooth.BluetoothDevice;
    import android.bluetooth.BluetoothSocket;
    import android.util.Log;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.nio.charset.Charset;
    
    import static com.pandaenterprise.cyril.bluetoothtest.MainActivity.TAG;
    
    
    public class BtInterface {
    
        ProgressDialog mProgressDialog;
        private ConnectedThread mConnectedThread;
    
    
    
        /**
         Finally the ConnectedThread which is responsible for maintaining the BTConnection, Sending the data, and
         receiving incoming data through input/output streams respectively.
         **/
        private class ConnectedThread extends Thread {
            private final BluetoothSocket mmSocket;
            private final InputStream mmInStream;
            private final OutputStream mmOutStream;
    
            public ConnectedThread(BluetoothSocket socket) {
                Log.d(TAG, "ConnectedThread: Starting.");
    
                mmSocket = socket;
                InputStream tmpIn = null;
                OutputStream tmpOut = null;
    
                //dismiss the progressdialog when connection is established
                try{
                    mProgressDialog.dismiss();
                }catch (NullPointerException e){
                    e.printStackTrace();
                }
    
    
                try {
                    tmpIn = mmSocket.getInputStream();
                    tmpOut = mmSocket.getOutputStream();
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
                mmInStream = tmpIn;
                mmOutStream = tmpOut;
            }
    
            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) {
                    // Read from the InputStream
                    try {
                        bytes = mmInStream.read(buffer);
                        String incomingMessage = new String(buffer, 0, bytes);
                        Log.d(TAG, "InputStream: " + incomingMessage);
                    } catch (IOException e) {
                        Log.e(TAG, "write: Error reading Input Stream. " + e.getMessage() );
                        break;
                    }
                }
            }
    
            //Call this from the main activity to send data to the remote device
            public void write(byte[] bytes) {
                try {
                    mmOutStream.write(bytes);
                } catch (IOException e) {
                    Log.e(TAG, "write: Error writing to output stream. " + e.getMessage() );
                }
            }
    
            /* Call this from the main activity to shutdown the connection */
            public void cancel() {
                try {
                    mmSocket.close();
                } catch (IOException e) { }
            }
        }
    
        private void connected(BluetoothSocket mmSocket, BluetoothDevice mmDevice) {
            Log.d(TAG, "connected: Starting.");
    
            // Start the thread to manage the connection and perform transmissions
            mConnectedThread = new ConnectedThread(mmSocket);
            mConnectedThread.start();
        }
    
        /**
         * Write to the ConnectedThread in an unsynchronized manner
         *
         * @param out The bytes to write
         * @see ConnectedThread#write(byte[])
         */
        public void write(byte[] out) {
            // Create temporary object
            ConnectedThread r;
    
            // Synchronize a copy of the ConnectedThread
            Log.d(TAG, "write: Write Called.");
            //perform the write
            mConnectedThread.write(out);
        }
    
    }
    

    En gros, je vois bien que le problème vient du type de variable ou de la déclaration ou de ... enfin ça se joue sur la variable que je veux envoyer. Mais je ne vois pas ce que je dois modifier...

    Merci d'avance pour votre aide! 





    • Partager sur Facebook
    • Partager sur Twitter
      14 septembre 2017 à 16:16:34

      Bonjour,

      En regardant vite fait je vois une première erreur. Dans ton MainActivity et dans button1.setOnClickListener

      Tu as :

      byte[] bytes = varbyte;
      

      Remplace le par :

      byte[]bytes = new byte[]{varbyte};
      

      Un byte n'est pas égale a un byte[]. Ce que je fais ici c'est crée un nouveau byte[] ou je met varbyte a l'interieur. ;)

      Dans tout le code que tu nous as envoyé il manque la partie connexion, ou tu initialise une variable de type BluetoothSocket

      -
      Edité par Morin21 14 septembre 2017 à 16:20:35

      • Partager sur Facebook
      • Partager sur Twitter
        14 septembre 2017 à 18:12:46

        Ok je suis d'accord. Par contre je ne connais pas la différence ^^ Peux-tu me l'expliquer?

        Aussi, je ne comprend pas à quoi sert la BluetoothSocket si j'ai déjà connecté mon smartphone au module bluetooth "HC06", faut-il vraiment que j'utilise le BluetoothSocket? J'ai vu beaucoup de tuto qui expliquent comment faire mais pas "pourquoi" je ne comprend pas toujours très bien à quoi sert BluetoothSocket...

        Merci d'avance! 

        • Partager sur Facebook
        • Partager sur Twitter
          15 septembre 2017 à 9:11:37

          La différence est vraiment simple :

          • byte[] est un tableau de byte
          • byte est juste un byte

          Ils sont différent l'un de l'autre mais il te suffit de créer un tableau et mettre ton byte a l'intérieur, comme ca tu as un tableau de byte avec 1 seul byte dedans.

          Je vais essayer de t'expliquer rapidement et simplement pour le BluetoothSocket :

          Il ne suffit pas de connecté ton device a ton module bluetooth pour que ton programme puisse faire la communication. L'appairage entre les deux devices doit être fait dans ton programme.

          Dans un premier temps tu dois :

          • Créer la connexion avec un UUID
          • Récupérer ton BluetoothDevice
          • Ensuite tu créer le BluetoothSocket en question, c'est grace a lui que tu vas récupérer ton InputStream et le OutputStream.

          Dès que j'ai un peu plus de temps je te fais un exemple de code ;)

          Dans un premier temps essai de crée une boite de dialog qui affiche tout les bluetooth qu'il détecte et qu'il te renvoi un BluetoothDevice quand tu clique sur un des Device. Regarde ce lien, il va t'aider a comprendre la fonction .startDiscovery() : ici

          Ca va beaucoup t'aider pour la suite.

          EDIT :

          
          public class ConnectivityBtThread extends Thread {
          
              private Context context;
              private BluetoothDevice device;
              private BluetoothSocket bluetoothSocket;
          
          
              public ConnectivityBtThread(Context context, BluetoothDevice device){
                  this.context = context;
                  this.device = device;
          
              }
          
              public void run(){
          
                  try {
          
                      // Get a BluetoothSocket to connect with the given BluetoothDevice
                      try {
                          int sdk = Integer.parseInt(Build.VERSION.SDK);
                          UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
                          Method m = BluetoothDevice.class.getMethod("createInsecureRfcommSocketToServiceRecord", new Class[]{UUID.class});
                          bluetoothSocket = (BluetoothSocket) m.invoke(device, uuid);
                      } catch (Exception e) {
                          Log.e(this.getClass().getName(), "IO Exception thrown while creating rf comm socket: " + e.getMessage(), e);
                      }
          
                      bluetoothSocket.connect();
          
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
          
              }
          
          

          Voici un exemple pour le BluetoothSocket. Attention c'est simplement un exemple, mon thread n'est pas 'Thread safe'.

          -
          Edité par Morin21 15 septembre 2017 à 16:53:55

          • Partager sur Facebook
          • Partager sur Twitter
            17 septembre 2017 à 21:20:22

            Ok merci pour toutes les infos. Je vais essayer de décortiquer ça demain. 

            Enfaite j'ai déjà fais les applications de bases du bluetooth (activer le bluetooth avec un bouton, chercher des devices, s'appareiller au device, ...) mais je n'avais jamais vraiment compris l'intérêt de ces fonctions dans une application (j'avais comme exemple en tête les enceintes bluetooth où il suffit de s'appareiller pour que ça fonctionne). 

            Donc enfaite, une fois que j'ai envoyé mon UUID au device et que j'ai reçu le sien je peux envoyer mes infos? 

            • Partager sur Facebook
            • Partager sur Twitter
              17 septembre 2017 à 22:10:17

              En quelque sorte oui,

              C'est cette étape qui te permet d'avoir ton BluetoothSocket et grace a ce dernier tu peux créer tes flux d'entrée / sortie entre tes deux devices avec InputStream et OutpuStream.

              J'espère que ce morceau de code va t'aider. Sinon hésite pas ;)

              • Partager sur Facebook
              • Partager sur Twitter

              [ANDROID] Bluetooth sur android studio

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown