Отправка данных обратно в Основное действие в Android - PullRequest
260 голосов
/ 28 мая 2009

У меня есть два вида деятельности: основная деятельность и деятельность с детьми.
Когда я нажимаю кнопку в основном действии, запускается дочернее действие.

Теперь я хочу отправить некоторые данные обратно на главный экран. Я использовал класс Bundle, но он не работает. Выдает некоторые исключения во время выполнения.

Есть ли какое-то решение для этого?

Ответы [ 11 ]

431 голосов
/ 04 июня 2009

Есть несколько способов добиться того, чего вы хотите, в зависимости от обстоятельств.

Наиболее распространенный сценарий (как звучит ваш) - это когда дочерняя активность используется для получения пользовательского ввода, например, выбора контакта из списка или ввода данных в диалоговом окне. В этом случае вы должны использовать startActivityForResult для запуска вашего дочернего действия.

Это обеспечивает конвейер для отправки данных обратно в основное действие с использованием setResult. Метод setResult принимает значение результата int и намерение, которое передается обратно вызывающей операции.

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();

Для доступа к возвращенным данным в вызывающем переопределении действия onActivityResult. RequestCode соответствует целому числу, переданному в вызове startActivityForResult, а resultCode и Intent данных возвращаются из дочернего Activity.

@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;
    } 
  }
}
171 голосов
/ 13 ноября 2012

Операция 1 использует startActivityForResult :

startActivityForResult(ActivityTwo, ActivityTwoRequestCode);

Запущено действие 2, и вы можете выполнить операцию, чтобы закрыть действие, выполните следующие действия:

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

Упражнение 1 - возвращение из предыдущего занятия вызовет onActivityResult :

@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);
    }
}

UPDATE: Ответ на комментарий Seenu69, во второй деятельности

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

Затем в первом упражнении

int result = data.getExtra(KEY_RESULT);
59 голосов
/ 05 декабря 2016

Отправка данных назад

Это помогает мне видеть вещи в контексте. Вот полный простой проект для отправки данных обратно. Вместо того, чтобы предоставлять файлы макета XML, вот изображение.

enter image description here

Основная деятельность

  • Начните второе действие с startActivityForResult, предоставив ему произвольный код результата.
  • Переопределить onActivityResult. Это называется, когда заканчивается второе задание. Вы можете убедиться, что это фактически Второе действие, проверив код запроса. (Это полезно, когда вы запускаете несколько разных действий из одного и того же основного действия.)
  • Извлечение данных, которые вы получили от возврата Intent. Данные извлекаются с использованием пары ключ-значение.

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);
            }
        }
    }
}

Второе занятие

  • Поместите данные, которые вы хотите отправить обратно в предыдущую операцию, в Intent. Данные хранятся в Intent с использованием пары ключ-значение.
  • Установите результат на RESULT_OK и добавьте намерение, содержащее ваши данные.
  • Позвоните finish(), чтобы закрыть второе занятие.

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();
    }
}

Другие заметки

  • Если вы находитесь во фрагменте, он не будет знать значение RESULT_OK. Просто используйте полное имя: Activity.RESULT_OK.

Смотри также

25 голосов
/ 10 декабря 2015

FirstActivity использует startActivityForResult:

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

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

при вызове SecondActivity setResult () события onClick или onBackPressed ()

Intent intent=new Intent();
intent.putExtra("MESSAGE",message);
setResult(2,intent);
16 голосов
/ 28 мая 2009

Вызовите намерение дочернего действия с помощью вызова метода startActivityForResult ()

Вот пример этого здесь: http://developer.android.com/training/notepad/notepad-ex2.html

и в «Возвращении результата с экрана» этого: http://developer.android.com/guide/faq/commontasks.html#opennewscreen

8 голосов
/ 19 сентября 2017

Я создал простой демонстрационный класс для вашей справки.

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);
            }
        }

    }
}

А вот 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();

            }
        });

    }
}
5 голосов
/ 05 августа 2017

В первом упражнении вы можете отправить намерение, используя startActivityForResult(), а затем получить результат второго занятия после того, как оно закончилось, используя setResult.

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();
    }
}
0 голосов
/ 19 февраля 2019

Все эти ответы объясняют, что сценарий вашего второго действия должен быть завершен после отправки данных.

Но если вы не хотите завершать второе действие и хотите отправить данные обратно в первое, то для этого вы можете использовать BroadCastReceiver.

Во втором занятии -

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

В первом занятии-

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

Зарегистрировать получателя в onCreate () -

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

Отменить регистрацию в onDestroy ()

0 голосов
/ 26 апреля 2018

Просто небольшая деталь, которая, я думаю, отсутствует в ответах выше.

Если ваша дочерняя активность может быть открыта из нескольких родительских действий, вы можете проверить, нужно ли вам setResult или нет, основываясь на том, была ли ваша активность открыта с помощью startActivity или startActivityForResult. Вы можете достичь этого, используя getCallingActivity(). Подробнее здесь .

0 голосов
/ 16 декабря 2016

Есть несколько способов сделать это. 1. с помощью startActivityForResult (), который очень хорошо объяснен в ответах выше.

  1. путем создания статических переменных в вашем классе "Utils" или любом другом вашем собственном классе. Например, я хочу передать studentId из ActivityB в ActivityA. Сначала моя ActivityA вызывает ActivityB. Затем внутри ActivityB установите идентификатор студента (который является статическим полем в Utils.class). Вот так Utils.STUDENT_ID = "1234"; затем, возвращаясь к ActivityA, используйте studentId, который хранится в Utils.STUDENT_ID.

  2. путем создания метода получения и установки в вашем классе приложений.

как это:

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;
    }
}

так что вы сделали. просто установите данные внутри, когда вы находитесь в ActivityB, и после возвращения в ActivityA получите данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...