Come passare più dati da un activity all'altra?

46 views
Skip to first unread message

kirtap.ck

unread,
Mar 25, 2013, 9:17:02 PM3/25/13
to corso-sm...@googlegroups.com
Buonasera, anzi ormai buonanotte!

Stavo facendo delle prove per come passare i dati da un activity all'altra, qui ho il caso in cui premendo un button passo UNA stringa presa in input da un editText dalla mainActivity all'activity secondaria (chiamata: RiceviDati), e in effetti funziona correttamente. Non scrivo qui i vari xml perchè non mi servono per il mio quesito.

Al click del button viene invocato il metodo 'invia' che sta nella classe MainActivity sotto i metodi onCreate e onCreateOptionsMenu 

public void invia(View view){
   String input = null;
   Intent intent = new Intent(this, RiceviDati.class);
   EditText et = (EditText) findViewById(R.id.input);
   input = et.getText().toString();
   intent.putExtra(EXTRA_MESSAGE, input);
   startActivity(intent);
}

Questa è RiceviDati la classe activity che riceve l'intent, ecco il metodo onCreate:

public void onCreate(Bundle savedInstanceState)
{
   super.onCreate(savedInstanceState);

   Intent intent = getIntent();
   String input = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
                
   TextView tv2 = new TextView(this);
   tv2.setText(input);
   setContentView(tv2);
}

.....
PROBLEMA:
Il mio problema da 1 ora a sta parte sta nel fatto che vorrei mandare alla activity secondaria PIU' dati... come fare??
Ho provato questa soluzione, ma sembra non andare(manca poco secondo me):
--------------------------------------------------
classe MainActivity:

String testo="patrik 61 idiota";
int num=2;
intent=new Intent(this, RiceviDati.class);
String pkg=getPackageName(); 
intent.putExtra(pkg+".miaStringa", testo);         
intent.putExtra(pkg+".mioNum", num);
-----------------------------------------------------


-----------------------------------------------------
Classe RiceviDati:

String pkg=getPackageName();
String testoRic=intent.getStringExtra(pkg+".miaStringa");
int numRic=intent.getIntExtra(pkg+".mioNum");
TextView tv=(TextView)findViewById(R.id.label);        
tv.append("miaStringa:"+testoRic+"\n");
tv.append("mioNum:"+numRic+"\n");
--------------------------------------------------------

Abbiate pazienza, è vero ancora queste cose nel corso non le abbiamo ancora fatte, o meglio le abbiamo fatte solo per teoria, ma io sono curioso e volevo fare qualcosa per capire meglio questo concetto di intent e activity.
Non sapevo a chi chiedere o dove cercare, dato che su internet si ci sono delle documentazioni, ma essendo al primo approccio con un app android non so bene cosa può essere valido oppure no!
Se quello che ho scritto è tutto errato allora me ne vergogno, ma qualcosa che non va c'è !!

Grazie a chiunque mi risponde. Patrik !! :)

Lorenz Cuno Klopfenstein

unread,
Mar 26, 2013, 6:15:57 AM3/26/13
to corso-sm...@googlegroups.com
Se il primo esempio funziona, il procedimento corretto è semplicemente quello di aggiungere altri "extra" nel proprio Intent, alla stessa maniera in cui si aggiunge il primo dato. Per cui, dopo la chiamata per l'aggiunta della stringa:

intent.putExtra(EXTRA_MESSAGE, input);

si potrà aggiungere un secondo campo, utilizzando:

intent.putExtra(EXTRA_MESSAGE2, "altra stringa");

facendo attenzione al fatto che la costante EXTRA_MESSAGE2 deve essere dichiarata nella classe che lancia l'Intent. La ricezione dell'Intent avviene alla stessa identica maniera:

Intent intent = getIntent();
String input = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
String input2 = intent.getStringExtra(MainActivity.EXTRA_MESSAGE2);

Non è necessario complicare l'esempio con il package name: l'Intent agisce come una mappa associativa tra valori ed oggetti serializzabili (nell'esempio, due stringhe). Per cui come si aggiunge un nuovo campo (con un nuovo valore identificativo, EXTRA_MESSAGE2 nell'esempio), lo si va a reperire quando si riceve l'Intent.

Spero funzioni. :)

kirtap.ck

unread,
Mar 27, 2013, 8:35:22 AM3/27/13
to corso-sm...@googlegroups.com
Prima di tutto grazie mille della risposta! 
Allora ho eseguito quello che mi ai suggerito, ma accade una cosa "strana", ovvero, nell'activity ricevente ricevo sempre il dato che viene passato per ultimo nell'activity inviante,es: qui l'activty ricevente stampa due volte inputB, infatti se nell'activty inviante inverto le due intent(prima inputB, poi inputA) nella ricevente stampo due volte inputA.
Grazie mille per l'eventuale risposta!! :)

NB:inputA, e inputB sono due stringhe lette da editText, e le due costanti le ho inizializzate! Ne warning ne errori in compilazione!

MainActivity:
intent.putExtra(EXTRA_MESSAGE, inputA);
intent.putExtra(EXTRA_MESSAGE2, inputB);
startActivity(intent);

-------------------------------------

Activity che riceve l'intent:
Intent intent = getIntent();
String inputA = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
String inputB = intent.getStringExtra(MainActivity.EXTRA_MESSAGE2);
        
TextView tv = new TextView(this);
tv.append("EXTRA_MESSAGE"+inputA+"\n");
tv.append("EXTRA_MESSAGE2"+inputB+"\n");
setContentView(tv);

Saverio Delpriori

unread,
Mar 27, 2013, 9:56:15 AM3/27/13
to corso-sm...@googlegroups.com
Il codice postato è corretto perciò l'errore deve essere da qualche altra parte.
Verificherei i valori delle due stringhe prima di inserirle nell'intent.

Il sistema di debug in Android (e Eclipse) non è così evoluto né così intuitivo perciò la soluzione più veloce è quella di usare l'API per la stampa nella console:

Log.i("MainActivity", "L'input numero 1 è: " + inputA);
Log.i("MainActivity", "L'input numero 2 è: " + inputB);

prima di

intent.putExtra(EXTRA_MESSAGE, inputA);
intent.putExtra(EXTRA_MESSAGE2, inputB);
startActivity(intent);


Se gli input dovessero essere corretti allora il problema sta nella seconda activity.
Altrimenti il bug potrebbe essere causato da una sovrascrittura di variabili o da un errato modo di ottenere le stringhe in input dalle EditText.
Il modo corretto potrebbe essere questo:

String inputA  = nomeVariabileEditView1.getText().toString(); 
String inputB  = nomeVariabileEditView2.getText().toString(); 
// dove nomeVariabileEditView1/2 vanno sostituiti con i nomi veri e propri delle variabili


Per chiarire meglio ho appena postato un progetto android già pronto che fa qualcosa di simile a quanto si vuole ottenere in questo caso. Lo trovi nella pagina dei download nel google code: https://code.google.com/p/sviluppo-apps-per-dispositivi-smart/downloads/detail?name=IntentTestApp.zip&can=2&q=

kirtap.ck

unread,
Mar 27, 2013, 6:09:30 PM3/27/13
to corso-sm...@googlegroups.com
Ok, io mi sono adattato al tuo esempio che è molto chiaro e in effetti funziona correttamente! (sotto mostro il mio vecchio codice)

Ho un solo un dubbio:
String inputA = receivedIntent.hasExtra(MainActivity.EXTRA_LABEL_1)?
              receivedIntent.getStringExtra(MainActivity.EXTRA_LABEL_1):"none";

Questo vuol dire che va a verificare che l'activity mittente sia in effetti la MainActivity, e se si prende il valore passato altrimenti "none"?
Questa non è analoga?:
String inputA = intent.getStringExtra(MainActivity.EXTRA_LABEL_1);
Forse non è analoga perchè un activity potrebbe ricevere intent da altre activity? E quindi questo è un semplice controllo per un coretto assegnamento?


Nel mio vecchio codice ho notato che la cattura dalle editText (all'interno della MainActivity) era corretto perchè nel debug le variabili assumevano l'esatto valore da me digitato, POI PERO' nella activty ricevente veniva ricevuto solo il dato passato per ultimo nell'activity inviante, quindi in effetti c'era una sovrascrittura.

Ecco le due activity:

public class MainActivity extends Activity
{
    public final static String EXTRA_MESSAGE = "EM";
    public final static String EXTRA_MESSAGE2 = "EM2";

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
    }
    
    public void invia(View view)
    {
    String inputA = null;
    String inputB = null;
   
    Intent intent = new Intent(this, RiceviDati.class);
    EditText et = (EditText) findViewById(R.id.inputA);
inputA = et.getText().toString();
EditText et2 = (EditText) findViewById(R.id.inputB);
inputB = et2.getText().toString();
intent.putExtra(EXTRA_MESSAGE, inputA);
intent.putExtra(EXTRA_MESSAGE2, inputB);
startActivity(intent);
    }
}
----------------------------------------------------------------------------------------------
public class RiceviDati extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        Intent intent = getIntent();
        String inputA = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
        String inputB = intent.getStringExtra(MainActivity.EXTRA_MESSAGE2);
        
        TextView tv = new TextView(this);
        tv.append("EM"+inputA+"\n");
        tv.append("EM2"+inputB+"\n");
        setContentView(tv);
    }
}


Grazie mille, spero di non essere pedante! :)

Saverio Delpriori

unread,
Mar 28, 2013, 7:39:56 AM3/28/13
to corso-sm...@googlegroups.com
Sebbene ci siano un paio di cose che è "sconsigliato fare" il tuo codice mi sembra corretto. Anzi ho provato a sostituirlo al mio per verifica e sembra andare tutto...
Magari porta il progetto alla prossima lezione e cerchiamo insieme una soluzione.

Per il dubbio ti rispondo in linea.


Ok, io mi sono adattato al tuo esempio che è molto chiaro e in effetti funziona correttamente! (sotto mostro il mio vecchio codice)

Ho un solo un dubbio:
String inputA = receivedIntent.hasExtra(MainActivity.EXTRA_LABEL_1)?
              receivedIntent.getStringExtra(MainActivity.EXTRA_LABEL_1):"none";

Questo vuol dire che va a verificare che l'activity mittente sia in effetti la MainActivity, e se si prende il valore passato altrimenti "none"? 

Non proprio. Il codice qua sopra può essere riscritto come 

String inputA = receivedIntent.getStringExtra(MainActivity.EXTRA_LABEL_1);

if(receivedIntent.hasExtra(MainActivity.EXTRA_LABEL_1)){
    inputA = "none";
}

dove 

receivedIntent.hasExtra(MainActivity.EXTRA_LABEL_1);

è un metodo della classe Intent che ritorna vero se l'intent ha un extra con quel nome, falso altrimenti.
Quindi non è una verifica dell'activity che ha inviato l'intent ma solo una verifica che nell'intent siano effettivamente contenute le informazioni che stiamo cercando.
 
Questa non è analoga?:
String inputA = intent.getStringExtra(MainActivity.EXTRA_LABEL_1);

Il risultato è lo stesso nel caso in cui il dato sia stato effettivamente inserito come extra prima di inviare l'intent.
Se il dato non è presente nell'intent questo metodo ritorna null mentre il codice sopra gestisce la cosa e inizializza la stringa ad un valore di default "none".

Forse non è analoga perchè un activity potrebbe ricevere intent da altre activity? E quindi questo è un semplice controllo per un coretto assegnamento?

In particolare, Android non permette (facilmente) di conoscere il mittente di un intent, o meglio, sfruttando un modo piuttosto complesso è possibile rendere l'activity lanciata consapevole di chi la ha lanciata ma è una cosa che ha poco senso fare.
 


Nel mio vecchio codice ho notato che la cattura dalle editText (all'interno della MainActivity) era corretto perchè nel debug le variabili assumevano l'esatto valore da me digitato, POI PERO' nella activty ricevente veniva ricevuto solo il dato passato per ultimo nell'activity inviante, quindi in effetti c'era una sovrascrittura.

Ecco le due activity:

public class MainActivity extends Activity
{
    public final static String EXTRA_MESSAGE = "EM";
    public final static String EXTRA_MESSAGE2 = "EM2";

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
    }
    
    public void invia(View view)
    {
     String inputA = null;
     String inputB = null;
    
     Intent intent = new Intent(this, RiceviDati.class);
     EditText et = (EditText) findViewById(R.id.inputA);
inputA = et.getText().toString();
EditText et2 = (EditText) findViewById(R.id.inputB);
inputB = et2.getText().toString();
intent.putExtra(EXTRA_MESSAGE, inputA);
intent.putExtra(EXTRA_MESSAGE2, inputB);
startActivity(intent);
    }
}
----------------------------------------------------------------------------------------------
public class RiceviDati extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        Intent intent = getIntent();
        String inputA = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
        String inputB = intent.getStringExtra(MainActivity.EXTRA_MESSAGE2);
        
        TextView tv = new TextView(this);
        tv.append("EM"+inputA+"\n");
        tv.append("EM2"+inputB+"\n");
        setContentView(tv);
    }
}


Grazie mille, spero di non essere pedante! :)

No figurati.

kirtap.ck

unread,
Mar 28, 2013, 8:23:28 AM3/28/13
to corso-sm...@googlegroups.com
Grazie!!!
Ok perfettissimo e chiarissimo!! 
Si in effetti ora ho capito che quello che scrivevo non era "corretto", ma il fatto della sovrascrittura ancora non mi da pace, perchè in teoria se pur nella sua inesattezza dovrebbe funzionare!! :D 
Grazie mille davvero!

Patrik
Reply all
Reply to author
Forward
0 new messages