Autore Topic: Invio e ricezione dati da socket  (Letto 1269 volte)

Offline panto91

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Tab S 10.5
  • Sistema operativo:
    Mac OS X 10.9
Invio e ricezione dati da socket
« il: 26 Ottobre 2015, 03:34:26 CET »
0
Ciao a tutti,
Sono nuovo del forum e anche della programmazione in ambito Android e Java...
Sono qui a chiedervi una mano per lo sviluppo di un app.

Tale app deve semplicemente connettersi come client ad un server tcp attraverso socket e ricevere costantemente i dati che il server invia e trasformarli in stringa e tali dati devono essere visualizzati con un intervallo molto breve nella UI.
Sarebbe anche necessario che venga inviata una determinata stringa di testo al server cliccando su un button nella UI. Ma per ora questo é secondario.

Ho hai iniziato a sviluppare l'app e ho creato una asynctask con un doinbackground per eseguire la connessione al socket e ricevere l'input stream.
Ho poi richiamato la task dopo la dichiarazione del layout (come descritto in tanti tutorial trovati online)... però non solo quando apro l'app non mi visualizza il dato che il server invia... ma non si collega nemmeno al server tcp attraverso socket (ho un tool sul PC che mi permette di verificare se la connessione é stata effettuata oppure no)

Potete aiutarmi dandomi qualche dritta?

Grazie mille

Panto91

Post unito: 26 Ottobre 2015, 15:16:37 CET
Scusate il doppio post... ora la connessione al server funziona... però non riesco a ricevere stringhe che il server invia via socket.

come mai?

Posto il codice sviluppato fin ora ... il concetto è molto semplice ... ma non funziona ... nella UI non mi si aggiorna la TextView.

Codice (Java): [Seleziona]
public class MainActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new BackgroundTask().execute();
    }

    private class BackgroundTask extends AsyncTask<Void, Void, Integer>
    {
        private Socket s;
        private static final String serverip = "192.168.10.11";
        private int i=0;

        @Override
        protected Integer doInBackground(Void... arg0)
        {
            try
            {
                InetAddress wifiserver = InetAddress.getByName(serverip);
                s = new Socket(wifiserver, 8899);
                while (i>0) {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
                    String risultato = reader.readLine();
                    TextView stampa = (TextView) findViewById(R.id.output);
                    stampa.setText(risultato);
                }
                } catch (IOException e) {
                    e.printStackTrace();
                    }

        return 0;
        }

    }
}

Per favore aiutatemi ... sto impazzendo ...
« Ultima modifica: 26 Ottobre 2015, 15:16:37 CET da panto91, Reason: Merged DoublePost »

Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Re:Invio e ricezione dati da socket
« Risposta #1 il: 26 Ottobre 2015, 15:55:17 CET »
0
Non puoi aggiornare la UI da un thread separato in doInBackground.
Visto che hai usato un AsyncTask usa il metodo onProgressUpdate tramite publishProgress per agire sul thread della UI.

Offline panto91

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Tab S 10.5
  • Sistema operativo:
    Mac OS X 10.9
Re:Invio e ricezione dati da socket
« Risposta #2 il: 26 Ottobre 2015, 16:24:00 CET »
0
Non puoi aggiornare la UI da un thread separato in doInBackground.
Visto che hai usato un AsyncTask usa il metodo onProgressUpdate tramite publishProgress per agire sul thread della UI.

Grazie mille per la risposta. Implementerò questa funzione tra qualche ora e vi comunicherò se funziona ...
Seconda domanda ... come posso fare per far si che venga letto di continuo l'input stream? Praticamente dato che il server manda di continuo dei dati ... ho bisogno che questi dati vengano di continuo presi dallo stream e inviati alla UI in una textView. Come posso fare per rendere tutto questo automatico e continuo senza che debba richiamare la funzione manualmente?

Post unito: 26 Ottobre 2015, 20:08:44 CET
Mi rispondo da solo ... cercando su internet ho capito che dato che la lettura del dato deve essere effettuata di continuo (ogni secondo tipo...) è meglio utilizzare un servizio .. solo che qui sono proprio a digiuno ... cosa mi conviene fare?
« Ultima modifica: 26 Ottobre 2015, 20:08:44 CET da panto91, Reason: Merged DoublePost »

Offline panto91

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Tab S 10.5
  • Sistema operativo:
    Mac OS X 10.9
Re:Invio e ricezione dati da socket
« Risposta #3 il: 28 Ottobre 2015, 02:15:12 CET »
0
Anche se sono alla prime armi ... cercando su internet ho trovato un tutorial che poteva fare al caso mio ma non riesco a farlo funzionare ...

Praticamente ora si collega al server via socket ma non riesco a ricevere i dati che invia il server di continuo ... e quindi di conseguenza questi non vengono visualizzati nella textView.

Vi prego datemi una mano... sto impazzendo ...

grazie

MainActivity.java
Codice (Java): [Seleziona]
package icm.icmweightcontrol;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import org.apache.commons.io.IOUtils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UTFDataFormatException;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;


public class MainActivity extends Activity
{
    int i=0;
    public static Socket s;
    private ResponseReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new BackgroundTask().execute();

        Intent service = new Intent(this, backgroundService.class);
        startService(service);

        IntentFilter filter = new IntentFilter(ResponseReceiver.ACTION_RESP);
        filter.addCategory(Intent.CATEGORY_DEFAULT);
        receiver = new ResponseReceiver();
        registerReceiver(receiver, filter);
    }

    // Socket connection
    private class BackgroundTask extends AsyncTask<Void, Void, Void>
    {
        private static final String serverip = "192.168.1.7";
        private static final int serverport = 8899;

        @Override
        protected Void doInBackground(Void... arg0)
        {
            try
            {
                InetAddress wifiserver = InetAddress.getByName(serverip);
                s = new Socket(wifiserver, serverport);
                } catch (IOException e) {
                    e.printStackTrace();
                    }
            return null;
        }
    }

    public class ResponseReceiver extends BroadcastReceiver {
        public static final String ACTION_RESP = "com.mamlambo.intent.action.MESSAGE_PROCESSED";

        @Override
        public void onReceive(Context context, Intent intent) {
            TextView result = (TextView) findViewById(R.id.output);
            String outputdata = intent.getStringExtra(backgroundService.PARAM_OUT_MSG);
            result.setText(outputdata);
        }
    }

}

backgroundService.java
Codice (Java): [Seleziona]
package icm.icmweightcontrol;

import android.app.IntentService;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
import android.text.format.DateFormat;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/*
public class backgroundService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, "Creazione servizio eseguita", Toast.LENGTH_LONG).show();
    } //chiusura onCreate

    @Override
    public void onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        Toast.makeText(this, "Avvio servizio completato", Toast.LENGTH_LONG).show();
    } // chiusura onStart

    @Override
    public IBinder onBind(Intent intent) {

    } // chiusura onBind

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "Cancellazzione servizio eseguita", Toast.LENGTH_LONG).show();
    } // chiusura onDestroy


} //chiusura classe

*/


public class backgroundService extends IntentService {
    public static final String PARAM_IN_MSG = "imsg";
    public static final String PARAM_OUT_MSG = "omsg";

    public backgroundService() {
        super("backgroundService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(MainActivity.s.getInputStream()));
                String risultato = reader.readLine();
                Intent broadcastIntent = new Intent();
                broadcastIntent.setAction(MainActivity.ResponseReceiver.ACTION_RESP);
                broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
                broadcastIntent.putExtra(PARAM_OUT_MSG, risultato);
                sendBroadcast(broadcastIntent);
            } catch (IOException e) {
                e.printStackTrace();
            }

    }
}

Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Re:Invio e ricezione dati da socket
« Risposta #4 il: 28 Ottobre 2015, 08:56:44 CET »
0
Non serve l'AsyncTask, che tra l'altro è una classe interna non statica e questo è il modo migliore per creare memory leaks: metti tutto il codice per gestire la connessione nel Service.
Evita inoltre di usare variabili globali.

Offline panto91

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Tab S 10.5
  • Sistema operativo:
    Mac OS X 10.9
Re:Invio e ricezione dati da socket
« Risposta #5 il: 28 Ottobre 2015, 21:56:40 CET »
0
Ok questo lo posso fare però non capisco come mai le attività inserita nell onHandlerIntent non vengono eseguite ... Mi potete dare due dritte modificandomi il codice che ho scritto ...

Grazie mille ...

Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Re:Invio e ricezione dati da socket
« Risposta #6 il: 29 Ottobre 2015, 08:48:01 CET »
0
Ok questo lo posso fare però non capisco come mai le attività inserita nell onHandlerIntent non vengono eseguite ... Mi potete dare due dritte modificandomi il codice che ho scritto ...

Grazie mille ...

Tu fai partire 2 thread separati ma non hai alcuna garanzia su quale dei 2 venga eseguito per primo, per cui la modifica che ti ho suggerito è necessaria.
Per il resto il problema potrebbe essere ovunque. Prova a mettere qualche log per seguire il flusso del programma. Dici che onHandleIntent non viene eseguito, ma sei sicuro di questo?

Offline panto91

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Tab S 10.5
  • Sistema operativo:
    Mac OS X 10.9
Re:Invio e ricezione dati da socket
« Risposta #7 il: 29 Ottobre 2015, 11:17:22 CET »
0
Sono abbastanza certo che non vengono eseguite le operazioni che gli ho indicato perchè ho impostato un toast che mi dice "Sto eseguendo onHandleIntent" e non viene fuori ... tra l'altro inserendo la connessione al socket dentro all'onHandleIntent la connessione al socket viene effettuata perchè vedo dal server il client connesso ma il toast "Mi sono connesso al socket" non viene visualizzato e le operazioni successive pare non venga eseguite ...

Offline iClaude

  • Utente normale
  • ***
  • Post: 177
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S5
  • Sistema operativo:
    Windows 10
Re:Invio e ricezione dati da socket
« Risposta #8 il: 29 Ottobre 2015, 11:30:55 CET »
0
Sono abbastanza certo che non vengono eseguite le operazioni che gli ho indicato perchè ho impostato un toast che mi dice "Sto eseguendo onHandleIntent" e non viene fuori ... tra l'altro inserendo la connessione al socket dentro all'onHandleIntent la connessione al socket viene effettuata perchè vedo dal server il client connesso ma il toast "Mi sono connesso al socket" non viene visualizzato e le operazioni successive pare non venga eseguite ...

onHandleIntent è eseguito in un thread separato,  per cui non può visualizzare il Toast.
Controlla meglio il codice per prelevare i dati dal server e la comunicazione tramite broadcast (i filter sono giusti? ).

Offline panto91

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Tab S 10.5
  • Sistema operativo:
    Mac OS X 10.9
Re:Invio e ricezione dati da socket
« Risposta #9 il: 30 Ottobre 2015, 01:54:16 CET »
0
Ho pensato di cambiare approccio dato che il servizio deve stare attivo per tutta la durata dell'utilizzo dell'APP.

Qui il codice dell'activity:
Codice (Java): [Seleziona]
package icm.icmweightcontrol;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends Activity
{
    MyReceiver myReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onStart() {
        myReceiver = new MyReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(backgroundService.MY_ACTION);
        registerReceiver(myReceiver, intentFilter);
        Intent intent = new Intent(MainActivity.this, icm.icmweightcontrol.backgroundService.class);
        startService(intent);
        super.onStart();
    }

    @Override
    protected void onStop() {
        unregisterReceiver(myReceiver);
        super.onStop();
    }

    private class MyReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context arg0, Intent arg1) {
            // TODO Auto-generated method stub

            int kgattuali = arg1.getIntExtra("kg", 0);
            TextView stampa = (TextView) findViewById(R.id.output);
            stampa.setText(kgattuali);

            Toast.makeText(MainActivity.this, "Triggered by Service!\n" + "Data passed: " + String.valueOf(kgattuali), Toast.LENGTH_LONG).show();

        }

    }

}

Qui il codice del servizio:
Codice (Java): [Seleziona]
package icm.icmweightcontrol;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;

public class backgroundService extends Service {

    final static String MY_ACTION = "MY_ACTION";

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public void onCreate() {
        Toast.makeText(this, "Servizio Creato", Toast.LENGTH_LONG).show();
        super.onCreate();
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        MyThread myThread = new MyThread();
        myThread.start();
        return super.onStartCommand(intent, flags, startId);
    }


    public class MyThread extends Thread {

        @Override
        public void run() {
            int i=0;
            Intent intent;
            String serverip = "192.168.1.7";
            int serverport = 8899;
            try {
                InetAddress wifiserver = InetAddress.getByName(serverip);
                Socket s = new Socket(wifiserver, serverport);

                while (i>1) {
                        intent = null;
                        InputStream is = s.getInputStream();
                        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                        String risultato = reader.readLine();
                        intent = new Intent();
                        intent.setAction(MY_ACTION);
                        intent.putExtra("kg", risultato);
                        sendBroadcast(intent);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            stopSelf();
        }
    }
}

Dunque ... il servizio viene creato e si avvia perchè si connette al socket server che è una delle istruzioni contenute nel thread del servizio.
Però purtroppo le informazioni non vengono ricevute dall'activity principale o forse i dati proprio non vengono "ricevuti" anche se penso sia più probabile la seconda.

Qualcuno può aiutarmi sistemandomi il codice per fare funzionare il tutto?

Grazie mille.

Post unito: 30 Ottobre 2015, 02:04:34 CET
*più probabile la prima

avevo sbagliato a scrivere
« Ultima modifica: 30 Ottobre 2015, 02:04:34 CET da panto91, Reason: Merged DoublePost »

Offline agenio

  • Utente junior
  • **
  • Post: 77
  • Respect: +11
    • Google+
    • Mostra profilo
  • Dispositivo Android:
    Moto G
  • Sistema operativo:
    Windows 8.1
Re:Invio e ricezione dati da socket
« Risposta #10 il: 30 Ottobre 2015, 09:12:59 CET »
0
Ciao,
da quel che vedo sembrerebbe una terza, i dati non vengono letti :)

Nel codice servizio vedo:
Codice (Java): [Seleziona]
            int i=0;
            Intent intent;
            String serverip = "192.168.1.7";
            int serverport = 8899;
            try {
                InetAddress wifiserver = InetAddress.getByName(serverip);
                Socket s = new Socket(wifiserver, serverport);

                while (i>1) {....}

Quindi nel while non ci entra dato che i è sempre 0, o sbaglio?

Offline panto91

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Tab S 10.5
  • Sistema operativo:
    Mac OS X 10.9
Re:Invio e ricezione dati da socket
« Risposta #11 il: 30 Ottobre 2015, 10:02:55 CET »
0
Ciao,
da quel che vedo sembrerebbe una terza, i dati non vengono letti :)

Nel codice servizio vedo:
Codice (Java): [Seleziona]
            int i=0;
            Intent intent;
            String serverip = "192.168.1.7";
            int serverport = 8899;
            try {
                InetAddress wifiserver = InetAddress.getByName(serverip);
                Socket s = new Socket(wifiserver, serverport);

                while (i>1) {....}

Quindi nel while non ci entra dato che i è sempre 0, o sbaglio?

Capperi hai ragione ... ho sistemato la cosa invertendo il segno ma il problema rimane ... anzi ... ora non so come mai ma non si collega piu al socket.

 :-(

Post unito: 30 Ottobre 2015, 12:11:59 CET
Piccolo update ... ora si collega al socket ma non funziona ... i valori che invia il server al client non arrivano (o non vengono visualizzati).

Sono disperato  :'( :'( :'(
« Ultima modifica: 30 Ottobre 2015, 12:11:59 CET da panto91, Reason: Merged DoublePost »

Offline agenio

  • Utente junior
  • **
  • Post: 77
  • Respect: +11
    • Google+
    • Mostra profilo
  • Dispositivo Android:
    Moto G
  • Sistema operativo:
    Windows 8.1
Re:Invio e ricezione dati da socket
« Risposta #12 il: 31 Ottobre 2015, 16:31:32 CET »
0
Hai messo nel manifest il permesso per usare la rete?

Codice (XML): [Seleziona]
<uses-permission android:name="android.permission.INTERNET"></uses-permission>

Offline panto91

  • Nuovo arrivato
  • *
  • Post: 14
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Tab S 10.5
  • Sistema operativo:
    Mac OS X 10.9
Re:Invio e ricezione dati da socket
« Risposta #13 il: 31 Ottobre 2015, 17:05:21 CET »
0
Si!! È da ore che ci sbatto la testa sopra e non trovo il problema ...

Offline agenio

  • Utente junior
  • **
  • Post: 77
  • Respect: +11
    • Google+
    • Mostra profilo
  • Dispositivo Android:
    Moto G
  • Sistema operativo:
    Windows 8.1
Re:Invio e ricezione dati da socket
« Risposta #14 il: 31 Ottobre 2015, 17:11:38 CET »
0
Si!! È da ore che ci sbatto la testa sopra e non trovo il problema ...

Dove stai facendo le prove? sull'emulatore o sul device fisico?