У меня в приложении есть 3 занятия:
MainMenuActivity -> ExecuteTrainingActivity -> ExecuteExerciseActivity.
Из MainMenuActivity в ExecuteTrainingActivity я передаю idExecution и idExercise для запроса ExecuteTrainingActivity и загружаю исходные данные.
ExecuteTrainingActivity onCreate:
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
initialize();
setupRecyclerView(exercises);
}
private void initialize() {
Bundle extras = getIntent().getExtras();
if (extras != null) {
if (extras.containsKey("id_execution")) {
idExecution = extras.getLong("id_execution");
idExercise = extras.getLong("id_exercise");
execution = queryExecution(idExecution);
} else {
insertExecution();
}
}
}
В третьем действии, ExecuteExerciseActivity, у меня есть TimerFragment, и когда TimerCountdown достигает 0, он открывает всплывающее окно с уведомлением, которое при нажатии открывает новую ExecuteExerciseActivity.
В этом TimerFragment я передаю в качестве Extras те же идентификаторы, поэтому я могу получить их в новом свежем ExecuteExerciseActivity:
public class TimerFragment extends Fragment {
//...
private void showNotification(){
Intent intent = new Intent(getActivity(), ExecuteExerciseActivity.class);
intent.putExtra("id_execution", idExecution);
intent.putExtra("id_exercise", idExercise);
intent.putExtra("position", position);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(getActivity());
stackBuilder.addNextIntentWithParentStack(intent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
/*=== CHECK IF NOTIFICATION CHANNEL IS ACTIVE ===*/
boolean ok = isNotificationChannelEnabled(getActivity(), Constants.CHANNEL_ID);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(requireNonNull(getActivity()), Constants.CHANNEL_ID)
.setSmallIcon(R.drawable.d77)
.setContentTitle("Teste Notificação")
.setContentText("Ababa")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getActivity());
notificationManager.notify(0, mBuilder.build());
}
Из этого нового свежего ExecuteExerciseActivity я хочу, чтобы система поддерживала тот же поток навигации для Activity, но когда я возвращаюсь с нового ExecuteExerciseActivity на ExecuteTrainingActivity, я не могу передать идентификаторы для запроса и загрузки ExecuteTrainingActivity.
Есть ли способ передать аргументы в BackPress? Является ли лучший подход заменой onBackPress созданием нового намерения и запуском нового действия?
** Мой манифест правильно использует parentActivityName.




Сохраните свой запрос и идентификатор в SharedPreferences в onDestroy вашего ExecuteExerciseActivity, затем снова вытащите запрос и идентификатор в старом ExecuteTrainingActivity. onBackPressed запускает событие onDestroy жизненного цикла действия. Затем в onResume ExecuteTrainingActivity вытащите эти данные обратно.
Я думаю, вы можете добиться этого, переопределив метод onOptionsItemSelected() ExecuteExerciseActivity. Попробуй это:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
Intent intent = new Intent(this, ExecuteExerciseActivity.class);
//Add the extras to the intent
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
В Android, если ваше Activity запускает другое Activity и вы хотите передать данные в это Activity, вы должны добавить эти данные в качестве дополнений Intent.
Этот тип отправки данных Activity A to Activity B - это то, что вы уже используете.
Но для Activity B, возвращаясь к Activity A, на самом деле для этого есть встроенное решение, которое использует startActivityForResult(Intent, REQUEST_CODE) вместо startActivity(Intent).
Теперь в действии B вам просто нужно написать код:
@Override
public void onBackPressed()
{
Intent resultIntent = getIntent();
resultIntent.putExtra(EXTRA_NAME, extra_value);
setResult(Activity.RESULT_OK, resultIntent);
finish();
}
По сути, в действии B вы устанавливаете данные, которые хотите отправить обратно в действие A, которое запустило действие B, поскольку между этими двумя действиями существует связь.
Затем в своем действии A просто переопределите метод onActivityResult().
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// get data through data.getIntExtra() and etc
}
}
}
Код запроса должен соответствовать REQUEST_CODE, который вы использовали для Activity B, поэтому Activity A знает, на какое действие следует ответить. Код результата - это просто быстрый способ категоризировать тип результата, который вы получаете от действия B, поскольку от действия B может быть возвращено более одного типа результата.
Это решение передачи данных лучше, чем создание нового намерения и запуск нового действия, потому что вам не нужно запускать новое действие. Ваше действие A уже существует, поэтому нет причин перестраивать весь макет, перезагружать все данные и иметь новое действие, существующее в стеке действий.
Поскольку ваше единственное намерение - передать данные из Activity B обратно в Activity A, которое его запустило, используйте startActivityForResult() и onActivityResult() для обработки этого типа совместного использования данных.
ActivityResult не работает с новым действием, созданным из уведомления! Новый Activity запускается как обычный startActivity, поэтому он не вызывает onActivityResult при обратном нажатии!
Извините, я неправильно понял ваш вопрос. Есть еще некоторые части вопроса, которые мне неясны. Чтобы уточнить, у ExecuteExerciseActivity есть фрагмент с именем TimerFragment, который запускает уведомление с некоторыми дополнениями, заполненными его намерением для отправки в запускаемое действие. Затем, когда нажимается Notification, запускается новый ExecuteExerciseActivity, и вы хотите, чтобы он передавал данные обратно ... исходной ExecuteExerciseActivity, создавшей уведомление?
В порядке! Сработало нормально!