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

Android Studio Java Discussion :

Socket serveur qui envoie un message retour au client.


Sujet :

Android Studio Java

  1. #1
    Candidat au Club
    Socket serveur qui envoie un message retour au client.
    Bonjour à tous et à toutes !

    J’espère que vous allez bien ?

    Je réalise un petit projet et j'essaye d'afficher une image sur une application Android lorsque je clique sur un capteur relié à une Raspberry (codé en python). Il y a 4 capteurs donc 4 images différentes à afficher sur l'application. Donc lorsque l'application reçois une data de la Raspberry il affiche une image en conséquence.

    Je suis débutante en java et en application Android.
    J'ai voulue réaliser l'opération décrite précédemment en appliquant un protocole TCP via des sockets.

    Ma Raspberry en tant que serveur et mon téléphone Android en tant que Client.

    Pour le moment je me concentre sur la partie communication, j'ai suivi un tuto (sans faire la magicienne, c'est à dire comprendre le code et non juste l’exécuter).

    -J'arrive à établir une connexion entre mon téléphoné et la Raspberry, à envoyer un message du téléphone à la Raspberry mais je n'arrive pas à afficher le message retour sur le téléphone. En fait je ne sais pas comment afficher ce message dans un TextView...

    Exit-il une méthode plus facile que passer par un application mobile, peut-on envoyer un message retour du serveur au client ?

    Merci et bonne journée !


    Voici mon code côté serveur (Raspberry):

    Code Python :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
    import socket
     
    import time
     
     
    listensocket = socket.socket()
    Port = 10
    maxConnections = 999
    IP = socket.gethostname() #Hostname de la machine
     
    listensocket.bind(('',Port))
    #Ouverture de serveur
    listensocket.listen(maxConnections)
    print("Server sur " + IP + " sur port " + str(Port))
     
    #Accept connection
    (clientsocket, address) = listensocket.accept()
    print("Conncection faite!")
     
    running = True
     
     
    #Main
    while running:
        message = clientsocket.recv(1024).decode() #Recevoir Message
        print(message) 
        output = 'Serveur répond au client'
        clientsocket.sendall(output.encode('utf-8'))
        clientsocket.close()
        running = False


    Voici le code côté Android studio :

    MainActivity :

    Code :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
    package com.limeparallelogram.socketclient;
     
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
     
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.net.UnknownHostException;
     
    public class MainActivity extends AppCompatActivity {
        public String message;
     
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            final EditText inputtext = (EditText)findViewById(R.id.editText3);
            final Button clickable = (Button)findViewById(R.id.button3);
            clickable.setOnClickListener(new View.OnClickListener(){
                public void onClick(View v){
                    send sendcode = new send();
                    message = inputtext.getText().toString();
                    sendcode.execute();
                }
            });
        }
        class send extends AsyncTask<Void,Void,Void> {
            Socket s;
            PrintWriter pw;
            @Override
            protected Void doInBackground(Void...params){
                try {
                    s = new Socket("192.168.43.64",10);
                    pw = new PrintWriter(s.getOutputStream());
                    pw.write(message);
     
                    //Message retour
                    InputStream is = s.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader br = new BufferedReader(isr);
                    String retour = br.readLine();
                    System.out.println("Message received from the server : " +retour);
     
     
                    pw.flush();
                    pw.close();
                    s.close();
                } catch (UnknownHostException e) {
                    System.out.println("Fail");
                    e.printStackTrace();
                } catch (IOException e) {
                    System.out.println("Fail");
                    e.printStackTrace();
                }
                return null;
            }
        }
    }


    Manifest :
    Code XML :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
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.limeparallelogram.socketclient" >
        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
     
     
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme" >
            <activity android:name=".MainActivity" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
     
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
     
    </manifest>


    activity_main:

    Code XML :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
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.limeparallelogram.my_application.MainActivity">
     
        <EditText
            android:id="@+id/editText3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="@string/message"
            android:inputType="textPersonName"
            android:text="@string/message"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintHorizontal_bias="0.502"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
     
        <Button
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/send"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/editText3"
            app:layout_constraintVertical_bias="0.113" />
    </android.support.constraint.ConstraintLayout>

  2. #2
    Nouveau membre du Club
    salut,

    Tu dois mettre ton pw.flush(); après le write, en tout cas avant de lire le message retour.

    Coté serveur tu as quoi comme trace ?
    Le print(message) fonctionne ?

  3. #3
    Candidat au Club
    Salut,

    Merci pour ta réponse

    Côté serveur le print(message) fonctionne bien.

    Voici la trace :

    "Server sur raspberrypi sur port 10
    Conncection faite!
    Message"


    Avant de coder sur android studio j'ai fait un code en java et celui-ci fonctionne, j'ai bien une connexion qui s'établit entre le serveur sur Raspberry en python et le code java (client sur mon pc).

    Le serveur reçoit un message et le print et donne un retour au client qui le print à son tour.

    Donc cela vient soit des permissions sur android mais normalement j'ai tout ouvert, soit de mon interface. En particulier le fait de print le message retour dans un textview.

  4. #4
    Nouveau membre du Club
    Tu as déplacé le pw.flush(); comme demandé ?
    Car dans ton log server, message est vide.
    Sinon tu peux utiliser :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    pw = new PrintWriter(s.getOutputStream(), true); // Le true permet de faire un autoFlush


    Est-ce que tu peux rajouter avant:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    pw.write(message);

    ceci:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    Log.d("SOCKET_CLIENT", "Message: " + message);
    Toast.makeText(MainActivity.this, "Message: " + message, Toast.LENGTH_SHORT).show();


    Ça permettra de savoir ce que contient vraiment 'message'.

  5. #5
    Candidat au Club
    Oui j'ai bien déplacé le pw.flush et je viens de rajouter la commande :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     Log.d("SOCKET_CLIENT", "Message: " + message);
     Toast.makeText(MainActivity.this, "Message: " + message, Toast.LENGTH_SHORT).show();


    Je lance l'application il y a une connexion qui est établit puis l'application crash en affichant sur le téléphone "SocketClient s'arrête systématiquement"

    Voici le logcat :

    Code x :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
    2019-11-18 11:42:09.631 6465-6465/? E/Zygote: isWhitelistProcess - Process is Whitelisted
    2019-11-18 11:42:09.632 6465-6465/? E/Zygote: accessInfo : 1
    2019-11-18 11:42:09.637 6465-6465/? I/am.socketclien: Late-enabling -Xcheck:jni
    2019-11-18 11:42:09.666 6465-6465/? I/am.socketclien: report jit thread pid = 6470
    2019-11-18 11:42:09.739 6465-6465/com.limeparallelogram.socketclient I/am.socketclien: The ClassLoaderContext is a special shared library.
    2019-11-18 11:42:09.976 6465-6465/com.limeparallelogram.socketclient I/DecorView: createDecorCaptionView >> DecorView@6a89917[], isFloating: false, isApplication: true, hasWindowDecorCaption: false, hasWindowControllerCallback: true
    2019-11-18 11:42:10.085 6465-6465/com.limeparallelogram.socketclient W/am.socketclien: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/RectZ (light greylist, reflection)
    2019-11-18 11:42:10.087 6465-6465/com.limeparallelogram.socketclient W/am.socketclien: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
    2019-11-18 11:42:10.324 6465-6494/com.limeparallelogram.socketclient I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
    2019-11-18 11:42:10.324 6465-6494/com.limeparallelogram.socketclient I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
    2019-11-18 11:42:10.324 6465-6494/com.limeparallelogram.socketclient I/OpenGLRenderer: Initialized EGL, version 1.4
    2019-11-18 11:42:10.549 6465-6465/com.limeparallelogram.socketclient I/InputMethodManager: startInputInner - mService.startInputOrWindowGainedFocus
    2019-11-18 11:42:10.563 6465-6465/com.limeparallelogram.socketclient I/AssistStructure: Flattened final assist data: 2420 bytes, containing 1 windows, 8 views
    2019-11-18 11:42:12.987 6465-6516/com.limeparallelogram.socketclient E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
        Process: com.limeparallelogram.socketclient, PID: 6465
        java.lang.RuntimeException: An error occurred while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:354)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
            at java.util.concurrent.FutureTask.run(FutureTask.java:271)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
            at java.lang.Thread.run(Thread.java:764)
         Caused by: java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare()
            at android.widget.Toast$TN.<init>(Toast.java:932)
            at android.widget.Toast.<init>(Toast.java:201)
            at android.widget.Toast.makeText(Toast.java:623)
            at android.widget.Toast.makeText(Toast.java:584)
            at com.limeparallelogram.socketclient.MainActivity$send.doInBackground(MainActivity.java:47)
            at com.limeparallelogram.socketclient.MainActivity$send.doInBackground(MainActivity.java:38)
            at android.os.AsyncTask$2.call(AsyncTask.java:333)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)*
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)*
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)*
            at java.lang.Thread.run(Thread.java:764)*
    2019-11-18 11:42:13.186 6465-6494/com.limeparallelogram.socketclient W/libEGL: EGLNativeWindowType 0xdbcbc008 disconnect failed
    2019-11-18 11:42:18.297 6465-6474/com.limeparallelogram.socketclient W/System: A resource failed to call close.

  6. #6
    Nouveau membre du Club
    Oups, c'est ma faute, on peut rien afficher quand on n'est pas dans le thread principal.

    Soit utilise cette fonction:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public void postToastMessage(final String message, final int duration) {
    	Handler handler = new Handler(Looper.getMainLooper());
    	handler.post(new Runnable() {
    		@Override
    		public void run() {
    			Toast.makeText(MainActivity.this, message, duration).show();
    		}
    	});
    }


    Et remplace par:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    postToastMessage("Message: " + message, Toast.LENGTH_SHORT);

    Au lieu de:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    Toast.makeText(MainActivity.this, "Message: " + message, Toast.LENGTH_SHORT).show();



    Ou alors déplace le Toast dans:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    @Override
    protected void onPreExecute() {
    }

  7. #7
    Candidat au Club
    Donc la j'envoie un message à la RPI elle reçoit bien mon message et mon app android affiche ce message que j'ai envoyé.

  8. #8
    Nouveau membre du Club
    Très bien.

    Après si tu veux afficher le message retour, il faut:

    Modifier la signature de la class pour retourner le résultat dans un String:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    class send extends AsyncTask<Void,Void,String>


    Faire un return de la valeur lue:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Override
    protected String doInBackground(Void...params){
    ...
    	return retour;
    ...
    	// Dans les 'catch', tu peux retourner le message d'erreur éventuel:
    	return e.getMessage();
    ...
    }


    Surcharger onPostExecute pour récupérer la valeur et l'afficher:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Override
    protected void onPostExecute(String s) {
    	// onPostExecute s'execute dans thread principal, réservé à l'affichage.
    	// s = retour
     
    	if(s!=null) {
    		Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
    		// Si tu veux modifier la view :
    		TextView outputtext = findViewById(R.id.editText3);
    		outputtext.setText( s );
    	}
    }

  9. #9
    Candidat au Club
    Dans ce style ?
    Code :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
     
    public class MainActivity extends AppCompatActivity {
        public String message;
     
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            final EditText inputtext = (EditText)findViewById(R.id.editText3);
            final Button clickable = (Button)findViewById(R.id.button3);
            clickable.setOnClickListener(new View.OnClickListener(){
                public void onClick(View v){
                    send sendcode = new send();
                    message = inputtext.getText().toString();
                    sendcode.execute();
                }
            });
        }
        class send extends AsyncTask<Void,Void,String> {
            Socket s;
            PrintWriter pw;
            @Override
            protected String doInBackground(Void...params){
                try {
                    s = new Socket("192.168.43.64",10);
                    pw = new PrintWriter(s.getOutputStream());
                    Log.d("SOCKET_CLIENT", "Message: " + message);
                    postToastMessage("Message: " + message, Toast.LENGTH_SHORT);
                    pw.write(message);
                    pw.flush();
                    pw.close();
                    s.close();
     
                    //Message retour
                    InputStream is = s.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader br = new BufferedReader(isr);
                    String retour = br.readLine();
                    System.out.println("Message received from the server : " +retour);
     
                    return retour;
     
     
     
                } catch (UnknownHostException e) {
                    System.out.println("Fail");
                    e.printStackTrace();
     
                } catch (IOException e) {
                    System.out.println("Fail");
                    e.printStackTrace();
                }
                return null;
            }
     
            public void postToastMessage(final String message, final int duration) {
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, message, duration).show();
                    }
                });
            }
            @Override
            protected void onPostExecute(String s) {
                // onPostExecute s'execute dans thread principal, réservé à l'affichage.
                // s = retour
     
                if(s!=null) {
                    Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
                    // Si tu veux modifier la view :
                    TextView outputtext = (TextView) findViewById(R.id.editText3);
                    outputtext.setText( s );
                }
            }
     
            }
    }

  10. #10
    Nouveau membre du Club
    Le s.close(); est trop tôt, tu l'utilises juste après ! Déplace-le juste avant le return.

    Rajoute return e.getMessage(); dans chaque catch.

  11. #11
    Candidat au Club
    C'est bon j'ai fait les modifications, lors du lancement il y a la connexion entre le serveur(rpi) et le client. Ensuite s'affiche "Socket is close" sur l'app android

  12. #12
    Nouveau membre du Club
    Tu es sur d'avoir déplacer le s.close(); ?
    Car tu es passé dans un des try/catch, d'où le message d'erreur

    Essaye de lancer l'APP en debug en mode pas à pas en mettant un point d'arret dans la fonction AsyncTask
    Pour savoir à quel moment on passe dans le catch

    Je viens de tester avec ce code, ça fonctionne :
    (J'ai rajouté un timeout dans le cas où le server n'est pas lancé)

    Code :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
        class send extends AsyncTask<Void,Void,String> {
            Socket s;
            PrintWriter pw;
            @Override
            protected String doInBackground(Void...params){
                try {
     
                    InetSocketAddress inetAddress = new InetSocketAddress("192.168.43.64", 10);
                    s = new Socket();
                    s.connect(inetAddress, 1000);
                    s.setSoTimeout(5000);
     
                    pw = new PrintWriter(s.getOutputStream(), true);
     
                    //postToastMessage("Message: " + message, Toast.LENGTH_SHORT);
     
                    pw.write(message);
                    Log.d("SOCKET_CLIENT", "Message: " + message);
                    pw.flush();
     
                    //Message retour
                    InputStream is = s.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader br = new BufferedReader(isr);
                    String retour = br.readLine();
                    System.out.println("Message received from the server : " +retour);
                    Log.d("SOCKET_CLIENT", "Retour: " + retour);
     
                    pw.close();
                    s.close();
     
                    return retour;
                } catch (Exception e) {
                    System.out.println("Fail");
                    e.printStackTrace();
                    Log.e("SOCKET_CLIENT", "Exception: " + e.getMessage());
                    return e.getMessage();
                }
            }
     
            @Override
            protected void onPostExecute(String s) {
            // onPostExecute s'execute dans thread principal, réservé à l'affichage.
            // s = retour
     
                if(s!=null) {
                    Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
                    // Si tu veux modifier la view :
                    TextView outputtext = findViewById(R.id.editText3);
                    outputtext.setText( s );
                }
            }
        }

  13. #13
    Candidat au Club
    Salut,

    Oui en effet mtn je reçois bien une réponse de la Raspberry ! Merci

    Je vais continuer enfin d'afficher une image lors de la réponse, et je voulais savoir est-il possible d’interroger en continue le serveur ?
    Le but final étant d'afficher une image en fonction du capteur touché (4 capteurs au total).

  14. #14
    Nouveau membre du Club
    Salut,

    C'est cool.
    Pour l'image tu devrais t'en sortir facilement avec une ImageView.
    Pour le serveur oui, il suffit de faire une boucle infinie, je te conseille de prévoir le cas pour sortir de la boucle avec une cmd spéciale du serveur.

    Bonne continuation

  15. #15
    Candidat au Club
    Re

    C'est bon j'arrive à afficher différentes images en fonction de la sortie du code python.

    La je m'attaque à l'écoute en continue du serveur (je galère un peu à placer mon while ), mais je vais chercher.

    Ensuite pour la partie Client, je vais me connecter au serveur sans envoyer de message ( envoyer les messages c'était pour mes tests) et attendre que le serveur me donne une info d'affichage. Donc le Client écoute le serveur qui fonctionne en continue. Donc on envoie une requête de connexion et on reste connecter pour recevoir des réponses.

  16. #16
    Nouveau membre du Club
    Oui c'est comme ca que je ferais.

    Je ferais aussi un bouton stop, qui mettrait un boolean à true pour sortir du while. (Mettre le boolean à false au début du send)

    Il faudrait le faire aussi quand on quitte l'application pour pas laisser le thread tourner pour rien (bien qu'il s'auto killera au bout d'un moment vu que l'activity ne sera plus la)

  17. #17
    Candidat au Club
    Bonjour Cyrilf,

    Je suis encore sur cette appli

    J'ai tout d'abord fait du ménage dans mon code.

    Côté serveur j'ai fait une boucle while, il y avait bien une connexion entre la RPI et l'app mais pas de message retour envoyé de la RPI à l'app (je pense que c'est la socket que je ne ferme pas).

    Ensuite, est-il possible de modifier le temps des toast pour afficher l'image en continue ?( Je sais que l'on peut augmenter le temps, mais que pendant une période).

    J'ai aussi essayé de faire une connexion automatique de l'app au serveur mais sans succès...

    Serait-il possible de solliciter encore une fois ton aide ? Merci d'avance

    Serveur :

    Code :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
     
    import socket
    import time
     
     
     
    listensocket = socket.socket()
    Port = 10
    maxConnections = 999
    IP = socket.gethostname() #Hostname de la machine
     
    listensocket.bind(('',Port))
    #Ouverture de serveur
    listensocket.listen(maxConnections)
    print("Server sur " + IP + " sur port " + str(Port))
     
    #Accept connection
    (clientsocket, address) = listensocket.accept()
    print("Conncection faite!")
     
     
    running = True
     
    #Serveur qui marche en continue
    '''while running:
        output = input("Quelle région (stop pour sortir) ?")
        if output == "stop":
            running = False
        else:
            clientsocket.sendall(output.encode('utf-8'))
     
    clientsocket.close()'''
     
     
    #Main
    while running: 
        output = '1'
        clientsocket.sendall(output.encode('utf-8'))
        clientsocket.close()
        running = False


    Client :

    Code :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
     
    package com.limeparallelogram.socketclient;
     
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;
    import android.widget.Toast;
     
    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.InetSocketAddress;
    import java.net.Socket;
     
    public class MainActivity extends AppCompatActivity {
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
     
            final Button clickable = (Button)findViewById(R.id.button3);
            clickable.setOnClickListener(new View.OnClickListener(){
                public void onClick(View v){
                    send sendcode = new send();
                    sendcode.execute();
                }
            });
        }
        class send extends AsyncTask<Void,Void,String> {
            Socket s;
            @Override
            protected String doInBackground(Void...params){
                try {
                    InetSocketAddress inetAddress = new InetSocketAddress("192.168.43.64", 10);
                    s = new Socket();
                    s.connect(inetAddress, 1000);
                    s.setSoTimeout(5000);
     
                    //Message retour
                    InputStream is = s.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader br = new BufferedReader(isr);
                    String retour = br.readLine();
                    System.out.println("Message received from the server : " + retour);
                    Log.d("SOCKET_CLIENT", "Retour: " + retour);
     
                    s.close();
                    return retour;
                } catch (Exception e) {
                    System.out.println("Fail");
                    e.printStackTrace();
                    Log.e("SOCKET_CLIENT", "Exception: " + e.getMessage());
                    return e.getMessage();
                }
            }
     
            @Override
            protected void onPostExecute(String s) {
                // onPostExecute s'execute dans thread principal, réservé à l'affichage.
     
                if(s!=null) {
                    Toast toast = new Toast(MainActivity.this);
                    ImageView view = new ImageView(MainActivity.this);
     
                    if (s.equals("1")){
                        //Toast.makeText(MainActivity.this, s, Toast.LENGTH_LONG).show();
                        // Si tu veux modifier la view :
                        //TextView outputtext = (TextView) findViewById(R.id.editText3);
                        //outputtext.setText( s );
                        view.setImageResource(R.drawable.image1);
     
                    }
     
                    else if(s.equals("2")){
     
                        view.setImageResource(R.drawable.image2);
     
                    }
                toast.setView(view);
                toast.show();
                }
            }
        }
    }

###raw>template_hook.ano_emploi###