Restituire dati ad una Activity con startActivityForResult()
In questo tutorial vedremo il meccanismo che ci consente di restituire dei dati ad un'Activity, dopo che questa ha attivato una sub-activity.
Nei precedenti tutorial, abbiamo visto cosa sono e come sfruttare sia gli Intent Espliciti che gli Intent Impliciti. Abbiamo visto come ad un Intent Implicito, possa allegare dei dati da inviare grazie al metodo putExtra() e come questi possano essere recuperati nella sub-activity grazie al metodo getIntent().getExtras().
Non abbiamo però ancora visto come si possa ritornare all'Activity chiamante, passando indietro delle informazioni. Sappiamo infatti che per uscire dalla sub-activity, e tornare indietro, abbiamo sempre usato il pulsante indietro del telefono, che non fa altro che richiamare il metodo finish() dell'activity, il quale, se non personalizzato, terminerà l'activity.
Ora dobbiamo studiare come gestire il ritorno all'activity principale senza usare questo pulsante. E' un meccanismo spesso usato come mostrato nella figura qui sotto, dove con un Intent, richiamo la fotocamera, e dopo aver scattato la foto, ritorna all'activity chiamante, recuperando tra l'altro la foto stessa.
Cosa impareremo?
- Creare intent per richiamare la fotocamera e recuperare l'immagine
- Creare Intent per richiamare la lista foto della libreria e recuperarla
- Mostrare le foto nell'activity chiamante
Chiamare Activity aspettandosi un valore di ritorno: startActivityForResult()
Capita spesso di avere la necessità di recuperare un dato gestito dalla sub-activity. Ad esempio se questa fosse la fotocamera, potresti avere la necessità di recuperare la foto scattata, in modo da poterla visualizzare in miniatura nell'Activity chiamante.
Per sfruttare questo è necessario usare un metodo alternativo a startActivity(). Quindi invece di usare:
public void onClick(View view) { // avvio la chiamata alla fotocamera Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivity(i); }
proverai ad usare il metodo startActivityforResult(), il quale, come suggerisce lo stesso nome, ci permette di recuperare un risultato, nel nostro caso proprio l'immagine che è stata appena scattata:
public void onClick(View view) { // avvio la chiamata alla fotocamera aspettandomi poi un valore di ritorno Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(i, 0); }
Come puoi vedere, il metodo richiede due parametri: il primo è l'intent che vogliamo eseguire, il secondo è un parametro intero che identifica in modo univoco l'Activity chiamata. Se esiste solo un'activity in grado di chiamare la fotocamera, allora potremmo usare il valore 0. Questo valore sarà restituito all'activity chiamante e potrà essere usato per distinguere di quale sub-activity si tratta.
Torna a casa Lassie: usare il metodo onActivityResult()
A questo punto però, non abbiamo ancora scritto nulla su come possa essere gestita l'immagine scattata.
Tutte le volte che usiamo il metodo startActivityForResult(), dobbiamo anche implementare un override, nell'activity chiamante, del metodo onActivityResult(), il quale dovrà contenere tutto il codice per gestire il dato da recuperare, nel nostro caso proprio l'immagine.
@Override protected void onActivityResult(int requestCode, int resultCode, Intent databack) { Bitmap immagine = (Bitmap) databack.getExtras().get("data"); // img è un componente imageView presente sul layout img.setImageBitmap(immagine); Toast.makeText(this, "Immagine recuperate che posso ora visualizzare in un ImageView", Toast.LENGTH_SHORT).show(); } } }
Tra i parametri del metodo, nota la presenza del parametro di nome "databack", il quale non è altro che un Intent. E’ proprio grazie a questo, generato in automatico da Android in seguito alla chiamata con il metodo startActivityForResult(), che riusciamo a recuperare il valore dell'immagine appena scattata, esattamente come avveniva duratnte la chiamata di un qualsiasi Intent, quindi sfruttando proprio:
databack.getExtras().get("data");
dove al posto di recuperare una stringa, come avevamo visto in uno dei precedenti tutorial, recuperiamo il parametro “data” il quale non è altro che un’immagine Bitmap, da qui il casting.
Chiaramente per poter usare la fotocamera dovrai anche aggiungere i relativi permessi nel file manifest (android.permission.CAMERA).
Recupero Immagini dalla librerie con starActivityForResult()
Questo esempio può essere usato come base per sviluppare ogni genere di applicazione in cui sia necessario mettere in comunicazione due Activity (Activity principale e Sub-Activity), non solo inviando dati dalla prima alla seconda, ma anche ricevendoli, dalla seconda alla prima.
Ad esempio se volessi recuperare le immagini presenti all’interno del telefono per poi mostrarli in un opportuno componente View, potrei sfruttare sempre la chiamata di un Intent Implicito così:
// variabile della classe private Bitmap bitmap; private ImageView imageView; // metodo interno all'Activity principale, attivato al click sul pulsante public void pickImage(View View) { Intent intent = new Intent(); intent.setType("image/*"); // filtro solo le immagini intent.setAction(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(intent, 0); }
Mentre potrò accedere all’immagine nel metodo onActivityResult():
// override del metodo nell'Activity principale @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { InputStream stream = null; if (bitmap != null) { bitmap.recycle(); } stream = getContentResolver().openInputStream(data.getData()); bitmap = BitmapFactory.decodeStream(stream); }
Esercizio proposto
Come esercizio, potresti cercare di usare queste sezioni di codice per implementare la semplice app, vista nella prima figura, in cui è presente un'activity con del testo, un bottone e un componente ImageView.
Dovrai quindi scrivere le righe per gestire il tocco sul bottone (come visto in uno dei precedenti tutorial) ed inserire le righe viste in questo tutorial, sia facendo l'esempio della fotocamera, sia recuperando le immagini dalla libreria.
2024-10-06 Tipo/Autore: Davide Copelli {ing} Pubblicato da: CorsoAndroid.it