Enviando dados de volta para a atividade principal no Android

295

Eu tenho duas atividades: atividade principal e atividade infantil.
Quando pressiono um botão na atividade principal, a atividade infantil é iniciada.

Agora, quero enviar alguns dados de volta para a tela principal. Eu usei a classe Bundle, mas não está funcionando. Ele lança algumas exceções de tempo de execução.

Existe alguma solução para isso?

Rajapandian
fonte
Possível duplicata de Como transmito dados entre o aplicativo Atividades no Android?
precisa saber é o seguinte
Um truque definir um ArrayList em sua atividade principal e torná-lo estático para que você possa acessá-lo na segunda atividade, em seguida, adicionar dados em itthat que pretende enviar à atividade principal, então você acessá-lo na atividade principal
Abhishek Yadav
Abhishek Yadav, e se sua atividade principal for destruir (retorno de chamada onDestroy ()). Eu acho que não é um conselho muito bom.
Leontsev Anton 18/01

Respostas:

473

Existem algumas maneiras de conseguir o que você deseja, dependendo das circunstâncias.

O cenário mais comum (que é o seu som) é quando uma Atividade filho é usada para obter informações do usuário - como escolher um contato de uma lista ou inserir dados em uma caixa de diálogo. Nesse caso, você deve usar startActivityForResultpara iniciar o seu filho Activity.

Isso fornece um pipeline para enviar dados de volta para a Atividade principal usando setResult. O método setResult usa um valor de resultado int e um Intent que são passados ​​de volta para a atividade de chamada.

Intent resultIntent = new Intent();
// TODO Add extras or a data URI to this intent as appropriate.
resultIntent.putExtra("some_key", "String data"); 
setResult(Activity.RESULT_OK, resultIntent);
finish();

Para acessar os dados retornados na substituição de atividade de chamada onActivityResult. O requestCode corresponde ao número inteiro passado na startActivityForResultchamada, enquanto o resultCode e os dados Intent são retornados da atividade filho.

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  switch(requestCode) {
    case (MY_CHILD_ACTIVITY) : {
      if (resultCode == Activity.RESULT_OK) {
        // TODO Extract the data returned from the child Activity.
        String returnValue = data.getStringExtra("some_key");
      }
      break;
    } 
  }
}
Reto Meier
fonte
4
para completar, deve-se mencionar qual é o melhor local para fazer a chamada para terminar ()? Talvez seja claro para os especialistas, mas seria bom saber para os iniciantes sem fazer referência a fontes adicionais.
Califf
1
@jelmoodjasser Demorei um pouco para descobrir, mas basicamente quando você inicia a nova atividade com Intent, você precisa usar a startActivityForResultfunção em vez de apenas startActivity. Um exemplo pode ser startActivityForResult(myIntent, 2);onde 2 é o código do resultado, que pode substituir a MY_CHILD_ACTIVITYinstrução switch acima.
Spotlight
quando segunda atividade terminou e retorna à primeira atividade em seguida, como requestCode set em segunda atividade antes de terminá-lo .... para usá-lo para onActivityResult em FirstActivity
Ahamadullah Saikat
Intenção é obrigatória? Se não tenho nada para enviar, preciso da intenção vazia de enviar de volta?
Bagus Aji Santoso
A intenção @BagusAjiSantoso é opcional, necessária apenas se você tiver algo para enviar de volta.
Narendra Singh
186

A atividade 1 usa startActivityForResult :

startActivityForResult(ActivityTwo, ActivityTwoRequestCode);

A Atividade 2 é iniciada e você pode executar a operação. Para fechar a Atividade, faça o seguinte:

Intent output = new Intent();
output.putExtra(ActivityOne.Number1Code, num1);
output.putExtra(ActivityOne.Number2Code, num2);
setResult(RESULT_OK, output);
finish();

Atividade 1 - ao retornar da atividade anterior, chamaráActivityResult :

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == ActivityTwoRequestCode && resultCode == RESULT_OK && data != null) {
        num1 = data.getIntExtra(Number1Code);
        num2 = data.getIntExtra(Number2Code);
    }
}

ATUALIZAÇÃO: resposta ao comentário de Seenu69, na atividade dois,

int result = Integer.parse(EditText1.getText().toString()) 
           + Integer.parse(EditText2.getText().toString());
output.putExtra(ActivityOne.KEY_RESULT, result);

Então, na atividade um,

int result = data.getExtra(KEY_RESULT);
jimmithy
fonte
Olá, eu aprecio você por responder à minha pergunta. Este código não é suficiente para mim. Desejo que a adição seja executada na segunda atividade e o resultado deve ser retornado para o MainActivity através do método onActivityResult. Por exemplo, existe apenas um botão na Atividade principal que leva você para a segunda atividade ao clicar nele, há dois números inseridos no widget editText, a lógica de adição é executada na segunda atividade e, finalmente, o resultado é retornado à MainActivity. Entendi?
Seenu69
2
Nesse caso, na segunda atividade, você executaria o cálculo e armazenaria o resultado na intenção com putExtra (). Eu editei minha resposta acima
jimmithy 13/11/2012
68

Enviando Dados Voltar

Isso me ajuda a ver as coisas em contexto. Aqui está um projeto simples e completo para enviar dados de volta. Em vez de fornecer os arquivos de layout xml, aqui está uma imagem.

insira a descrição da imagem aqui

Atividade principal

  • Inicie a segunda atividade com startActivityForResult, fornecendo um código de resultado arbitrário.
  • Substituir onActivityResult. Isso é chamado quando a Segunda Atividade termina. Você pode ter certeza de que é realmente a segunda atividade, verificando o código de solicitação. (Isso é útil quando você está iniciando várias atividades diferentes da mesma atividade principal.)
  • Extraia os dados que você obteve do retorno Intent. Os dados são extraídos usando um par de valores-chave.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private static final int SECOND_ACTIVITY_REQUEST_CODE = 0;

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

    // "Go to Second Activity" button click
    public void onButtonClick(View view) {

        // Start the SecondActivity
        Intent intent = new Intent(this, SecondActivity.class);
        startActivityForResult(intent, SECOND_ACTIVITY_REQUEST_CODE);
    }

    // This method is called when the second activity finishes
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Check that it is the SecondActivity with an OK result
        if (requestCode == SECOND_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {

                // Get String data from Intent
                String returnString = data.getStringExtra("keyName");

                // Set text view with string
                TextView textView = (TextView) findViewById(R.id.textView);
                textView.setText(returnString);
            }
        }
    }
}

Segunda atividade

  • Coloque os dados que você deseja enviar de volta para a atividade anterior em um Intent. Os dados são armazenados no Intentpar usando valor-chave.
  • Defina o resultado como RESULT_OKe adicione a intenção que contém seus dados.
  • Ligue finish()para fechar a segunda atividade.

SecondActivity.java

public class SecondActivity extends AppCompatActivity {

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

    // "Send text back" button click
    public void onButtonClick(View view) {

        // Get the text from the EditText
        EditText editText = (EditText) findViewById(R.id.editText);
        String stringToPassBack = editText.getText().toString();

        // Put the String to pass back into an Intent and close this activity
        Intent intent = new Intent();
        intent.putExtra("keyName", stringToPassBack);
        setResult(RESULT_OK, intent);
        finish();
    }
}

Outras notas

  • Se você estiver em um fragmento, ele não saberá o significado de RESULT_OK. Basta usar o nome completo: Activity.RESULT_OK.

Veja também

Suragch
fonte
Essa é uma explicação explícita muito bem escrita. Bem feito!
Kingsley Ijike 16/02/19
29

FirstActivity usa startActivityForResult:

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivityForResult(intent, int requestCode); // suppose requestCode == 2

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 2)
    {
        String message=data.getStringExtra("MESSAGE");
    }
}

Na chamada SecondActivity, setResult () eventos onClick ou onBackPressed ()

Intent intent=new Intent();
intent.putExtra("MESSAGE",message);
setResult(Activity.RESULT_OK, intent);
Vijay
fonte
É resultCode de requestCode?
Engr Syed Rowshan Ali
15

Chame a atividade filho Intent usando a chamada do método startActivityForResult ()

Há um exemplo disso aqui: http://developer.android.com/training/notepad/notepad-ex2.html

e em "Retornando um resultado de uma tela": http://developer.android.com/guide/faq/commontasks.html#opennewscreen

Intrications
fonte
Sim, concordo com o cbrulak, o link para os documentos foi muito mais útil que a resposta.
219132 javafree
Os links estão mostrando algumas coisas gerais agora. O conteúdo pode ser alterado por favor atualizá-lo ou remover a resposta para a comunidade
Manoranjan
7

Eu criei uma classe de demonstração simples para sua melhor referência.

FirstActivity.java

 public class FirstActivity extends AppCompatActivity {

    private static final String TAG = FirstActivity.class.getSimpleName();
    private static final int REQUEST_CODE = 101;
    private Button btnMoveToNextScreen;

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

        btnMoveToNextScreen = (Button) findViewById(R.id.btnMoveToNext);
        btnMoveToNextScreen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent mIntent = new Intent(FirstActivity.this, SecondActivity.class);
                startActivityForResult(mIntent, REQUEST_CODE);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(resultCode == RESULT_OK){
            if(requestCode == REQUEST_CODE && data !=null) {
                String strMessage = data.getStringExtra("keyName");
                Log.i(TAG, "onActivityResult: message >>" + strMessage);
            }
        }

    }
}

E aqui está SecondActivity.java

public class SecondActivity extends AppCompatActivity {

    private static final String TAG = SecondActivity.class.getSimpleName();
    private Button btnMoveToPrevious;
    private EditText editText;

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

        editText = (EditText) findViewById(R.id.editText);

        btnMoveToPrevious = (Button) findViewById(R.id.btnMoveToPrevious);
        btnMoveToPrevious.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String message = editText.getEditableText().toString();

                Intent mIntent = new Intent();
                mIntent.putExtra("keyName", message);
                setResult(RESULT_OK, mIntent);
                finish();

            }
        });

    }
}
Kuls
fonte
3
bem explicado!
Radhey
5

Na primeira atividade, você pode enviar a intenção de usar startActivityForResult()e, em seguida, obter resultados da segunda atividade depois que ela terminar de usarsetResult .

MainActivity.class

public class MainActivity extends AppCompatActivity {

    private static final int SECOND_ACTIVITY_RESULT_CODE = 0;

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

    // "Go to Second Activity" button click
    public void onButtonClick(View view) {

        // Start the SecondActivity
        Intent intent = new Intent(this, SecondActivity.class);
        // send intent for result 
        startActivityForResult(intent, SECOND_ACTIVITY_RESULT_CODE);
    }

    // This method is called when the second activity finishes
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // check that it is the SecondActivity with an OK result
        if (requestCode == SECOND_ACTIVITY_RESULT_CODE) {
            if (resultCode == RESULT_OK) {

                // get String data from Intent
                String returnString = data.getStringExtra("keyName");

                // set text view with string
                TextView textView = (TextView) findViewById(R.id.textView);
                textView.setText(returnString);
            }
        }
    }
}

SecondActivity.class

public class SecondActivity extends AppCompatActivity {

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

    // "Send text back" button click
    public void onButtonClick(View view) {

        // get the text from the EditText
        EditText editText = (EditText) findViewById(R.id.editText);
        String stringToPassBack = editText.getText().toString();

        // put the String to pass back into an Intent and close this activity
        Intent intent = new Intent();
        intent.putExtra("keyName", stringToPassBack);
        setResult(RESULT_OK, intent);
        finish();
    }
}
Yogesh Adhe
fonte
1

Todas essas respostas estão explicando que o cenário da sua segunda atividade precisa ser concluído após o envio dos dados.

Mas, se você não deseja concluir a segunda atividade e deseja enviar os dados novamente para a primeira, use o BroadCastReceiver.

Na segunda atividade -

Intent intent = new Intent("data");
intent.putExtra("some_data", true);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

Na primeira atividade

private BroadcastReceiver tempReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // do some action
    }
};

Registre o receptor em onCreate () -

 LocalBroadcastManager.getInstance(this).registerReceiver(tempReceiver,new IntentFilter("data"));

Cancelar o registro em onDestroy ()

Shivam Yadav
fonte
0

Outra maneira de alcançar o resultado desejado, que pode ser melhor, dependendo da sua situação, é criar uma interface de ouvinte.

Ao fazer com que a atividade pai escute uma interface que é acionada pela atividade filho ao passar os dados necessários como parâmetro, pode criar um conjunto semelhante de circunstâncias

Lenos
fonte
-1

Existem algumas maneiras de fazer isso. 1. usando o startActivityForResult (), que é muito bem explicado nas respostas acima.

  1. criando as variáveis ​​estáticas na sua classe "Utils" ou em qualquer outra classe de sua preferência. Por exemplo, eu quero passar studentId de ActivityB para ActivityA.Primeiro meu ActivityA está chamando o ActivityB. Em seguida, dentro da ActivityB, defina o studentId (que é um campo estático no Utils.class). Como este Utils.STUDENT_ID = "1234"; depois, ao voltar para a ActivityA, use o studentId que está armazenado em Utils.STUDENT_ID.

  2. criando um método getter e setter na sua classe Application.

como isso:

public class MyApplication extends Application {

    private static MyApplication instance = null;
    private String studentId="";

    public static MyApplication getInstance() {
        return instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
    }

    public void setStudentId(String studentID){
        this.studentId=studentID;
    }

    public String getStudentId(){
        return this.studentId;
    }
}

então você está pronto. basta definir os dados quando você estiver no ActivityB e, depois de retornar ao ActivityA, obtenha os dados.

swetabh suman
fonte
-1

Apenas um pequeno detalhe que acho que está faltando nas respostas acima.

Se a sua atividade filho puder ser aberta a partir de várias atividades principais, você poderá verificar se precisa setResultou não, com base em se a sua atividade foi aberta por startActivityou startActivityForResult. Você pode conseguir isso usando getCallingActivity(). Mais informações aqui .

Dhruv Jagetiya
fonte
-2

Use sharedPreferences, salve seus dados e acesse-os de qualquer lugar do aplicativo

salvar data como esta

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString(key, value);
    editor.commit();

E receba dados como este

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    String savedPref = sharedPreferences.getString(key, "");
    mOutputView.setText(savedPref);
Desenvolvedor híbrido
fonte
6
Isso seria mais apropriado se a segunda atividade estivesse definindo uma alteração / configuração permanente no aplicativo.
elimirks
Isso funcionará se eu quiser compartilhar dados entre dois aplicativos Android diferentes? Um chamado biblioteca?
Joey Rohan
21
Este é um abuso de SharedPreferences.
Eran Goldin
1
Usar esse método para apenas passar dados entre duas atividades (pergunta original do OP) é ​​como abusar de SharedPreferences. Não é para isso e o sistema precisa fazer muito trabalho (escrevendo xml no armazenamento e lendo-o novamente) para uma tarefa simples, como passar dados entre duas atividades.
Sudara 22/07/2015