Nesta crónica vamos focar a transferência de dados entre a atividade invocada e a atividade invocadora, ou seja, como é que posso receber dados de uma atividade que invoquei.
Para enviar dados de volta para a atividade principal, a melhor forma é através de um Parcel (encomenda ou pacote). Segue um exemplo de uma classe que contém os dados a transferir para a atividade principal.
import android.os.Parcel; import android.os.Parcelable; //simple class that just has one member property as an example public class PacoteDados implements Parcelable { String que; String[] opcoes; public PacoteDados(String que, String[] opcoes) { this.que = que; this.opcoes = opcoes; } /* everything below here is for implementing Parcelable */ public int describeContents() { return 0; } // write your object's data to the passed-in Parcel public void writeToParcel(Parcel out, int flags) { out.writeString(que); out.writeInt(opcoes.length); out.writeStringArray(opcoes); } // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods public static final Parcelable.Creator<PacoteDados> CREATOR = new Parcelable.Creator<PacoteDados>() { public PacoteDados createFromParcel(Parcel in) { return new PacoteDados(in); } public PacoteDados[] newArray(int size) { return new PacoteDados[size]; } }; // example constructor that takes a Parcel and gives you an object populated with it's values private PacoteDados(Parcel in) { que = in.readString(); int n = in.readInt(); opcoes = new String[n]; in.readStringArray(opcoes); } }
Na classe anterior, os dados que vão ser transferidos são uma String que e um array de Strings opcoes. A classe deve implementar a interface Parcelable. É possível ter literalmente qualquer tipo de dados, nesta classe, e transferi-los para a atividade principal. A grande vantagem desta solução face a uma serialização é a rapidez.
O primeiro construtor permite fornecer os dados a transferir, no momento da criação de um objeto. O ultimo construtor é invocado pela atividade principal para rececionar os dados. O método writeToParcel deve escrever no Parcel todos os dados necessários para reconstruir os dados enviados: note-se que foi necessário passar o tamanho do array opcoes de forma a poder recriá-lo na receção (ver último construtor).
O objeto CREATOR do tipo Parcelable.Creator<PacoteDados> é obrigatório e é necessário para regenerar o objeto.
Na classe secundária (aquela que vai devolver os dados) o processo de retorno é o seguinte:
Intent resultIntent = new Intent(); PacoteDados pacote = new PacoteDados(que, opcSend); resultIntent.putExtra("dados", pacote); Log.d(TAG, this.toString()); setResult(Activity.RESULT_OK, resultIntent); finish();
A invocação e a receção, na classe principal, são apresentadas de seguida:
// Invocação public static final int REQUEST_CRIAR = 4; Intent grf = new Intent(this, Criar.class); startActivityForResult(grf, REQUEST_CRIAR); // Receção @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); switch(requestCode) { case REQUEST_CRIAR: if (resultCode == Activity.RESULT_OK) { PacoteDados pacote = (PacoteDados) intent.getParcelableExtra("dados"); String s = "que: " + pacote.que; for(int i=0; i<pacote.opcoes.length; i++) s += ", op" + (i+1) + ": " + pacote.opcoes[i]; Toast.makeText(this, s, Toast.LENGTH_LONG).show(); break; } }
Na receção, o campo que é recolhido de imediato, enquanto os vários campos de opcoes são recolhidos de forma iterativa. No fim é apresentado o conteúdo do retorno numa mensagem do tipo Toast.