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.