Отправка данных обратно в Основное действие в Android

295

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

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

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

Rajapandian
источник
Еще один трюк определяет ArrayList в вашем основном действии и делает его статичным, чтобы вы могли получить к нему доступ во втором действии, затем добавить в него данные, которые вы хотите отправить в основное действие, а затем получить к нему доступ в основном
Абхишек Ядав
Абхишек Ядав, что если твоя основная деятельность собирается уничтожить (обратный вызов onDestroy ()). Я думаю, что это не очень хороший совет.
Леонцев Антон

Ответы:

474

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

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

Это обеспечивает конвейер для отправки данных обратно в основное действие с помощью 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;
    } 
  }
}
Рето Мейер
источник
4
для полноты следует упомянуть, какое место лучше всего сделать для завершения вызова ()? Это может быть понятно специалистам, но для начинающих было бы полезно узнать, не ссылаясь на дополнительные источники.
Califf
1
@jelmoodjasser Мне потребовалось немного времени, чтобы понять, но в основном, когда вы начинаете новое действие с Intent, вам нужно использовать startActivityForResultфункцию вместо просто startActivity. Примером может быть startActivityForResult(myIntent, 2);где 2 - код результата, который может занять место MY_CHILD_ACTIVITYв приведенном выше операторе switch.
Прожектор
когда второе действие завершено и возвращается к первому действию, то как установить requestCode во второе действие, прежде чем завершить его .... для использования его в onActivityResult в FirstActivity
Ahamadullah Saikat
Намерение является обязательным? Если мне нечего отправить обратно, нужно ли пустое намерение отправить обратно?
Багус Ажи Сантосо
Намерение @BagusAjiSantoso является необязательным, оно необходимо только в том случае, если вам нужно что-то отправить обратно.
Нарендра Сингх
186

Упражнение 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);
    }
}

ОБНОВЛЕНИЕ: Ответ на комментарий 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);
jimmithy
источник
Привет, я ценю тебя за ответ на мой вопрос. Этого кода мне недостаточно. Я хочу, чтобы дополнение выполнялось во втором действии, и результат должен быть возвращен в MainActivity через метод onActivityResult. Например, в главном действии есть только кнопка, которая переводит вас во второе действие при нажатии на нее, там два числа вводятся через виджет editText, логика добавления выполняется во втором действии и, наконец, результат возвращается в MainActivity. Понял?
Seenu69
2
В этом случае во втором упражнении вы выполняете вычисление и сохраняете результат в функции с помощью putExtra (). Я отредактировал мой ответ выше
Джимми
68

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

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

введите описание изображения здесь

Основное занятие

  • Начните второе действие с startActivityForResult, предоставив ему произвольный код результата.
  • Override 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.

Смотрите также

Suragch
источник
Это очень хорошо написанное явное объяснение. Отлично сработано!
Кингсли Иджике
29

FirstActivity использует 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");
    }
}

По вызову SecondActivity setResult () для событий onClick или onBackPressed ()

Intent intent=new Intent();
intent.putExtra("MESSAGE",message);
setResult(Activity.RESULT_OK, intent);
Виджай
источник
Это resultCode запросаCode?
Ангр Сайед Роушан Али
15

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

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

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

Intrications
источник
Да, я согласен с cbrulak, ссылка на документы была намного полезнее, чем ответ.
george_h
Ссылки показывают некоторые общие вещи сейчас. Содержание может быть изменено , пожалуйста , обновите его или удалить ответ для сообщества
Manoranjan
7

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

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

            }
        });

    }
}
Kuls
источник
3
хорошо объяснил!
Радхи
5

В первом упражнении вы можете отправить намерение с помощью, 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();
    }
}
Йогеш Адхе
источник
1

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

Но в случае, если вы не хотите завершать второе действие и хотите отправить данные обратно сначала, для этого вы можете использовать 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

Другим способом достижения желаемого результата, который может быть лучше в зависимости от вашей ситуации, является создание интерфейса слушателя.

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

Lenos
источник
-1

Есть несколько способов сделать это. 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 получите данные.

Swetabh Suman
источник
-1

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

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

Дхрув Ягетия
источник
-2

Используйте sharedPreferences и сохраняйте свои данные и к ним доступ из любой точки приложения

сохранить дату, как это

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

И получать данные, как это

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    String savedPref = sharedPreferences.getString(key, "");
    mOutputView.setText(savedPref);
Гибридный разработчик
источник
6
Это было бы более уместно, если вторым действием была установка постоянного изменения / настройки в приложении.
elimirks
Будет ли это работать, если я хочу обмениваться данными между 2 различными приложениями для Android? Одно называется библиотекой?
Джои Рохан
21
Это злоупотребление SharedPreferences.
Эран Голдин
1
Использование этого метода для простой передачи данных между двумя действиями (оригинальный вопрос OP) похоже на злоупотребление SharedPreferences. Это не предназначено для этого, и система должна делать слишком много работы (писать XML на хранилище и читать его снова) для такой простой задачи, как передача данных между двумя действиями.
Судара