OnActivityResult фрагмента не вызывается после изменения ориентации

Обратите внимание, что этот вопрос не является дубликатом следующего:

  • https://stackoverflow.com/questions/19006776/onactivityresult-not-working-with-fragments
  • OnActivityResult не работает над фрагментами

Кроме того, ранее задавался другой аналогичный вопрос , но это не упоминает изменения ориентации (и не решено).

Мой метод onActivityResult в Fragment вызывает вызов, если я не переключаю ориентацию. Однако, если я последую этим шагам, он не будет вызван:

  1. Загрузите фрагмент в FragmentActivity.
  2. Из фрагмента: startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE), Constants.REQ_CODE_IMAGE_CAPTURE);
  3. Подождите, пока камера загрузится.
  4. Переключение ориентации.
  5. Сделайте снимок и нажмите галочку.

onActivityResult прежнему onActivityResult в родительском FragmentActivity. Однако из-за этого предупреждения я получаю:

 W/FragmentActivity(4418): Activity result no fragment exists for index: 0x22d73 

… я предполагаю, что родительский объект был уничтожен из-за изменения ориентации, и после того, как он был воссоздан, он не может найти Fragment который startActivityForResult вызвал startActivityForResult .

Это ошибка структуры? Как это можно обойти?

EDIT : добавлено больше кода из-за популярного спроса.

FragmentActivity.java:

 ... fragment = new ExampleFragment(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace (R.id.mainContentView, fragment); if (clearBackStack) { // clear the back stack while (getSupportFragmentManager().popBackStackImmediate ()); // add the current transaction to the back stack transaction.addToBackStack (null); } else { transaction.addToBackStack(null); } transaction.commit(); ... @Override public void onActivityResult(int reqCode, int resultCode, Intent data) { super.onActivityResult(reqCode, resultCode, data); } 

ExampleFragment.java:

 Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(takePicture, Constants.REQ_CODE_IMAGE_CAPTURE); ... @Override public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { super.onActivityResult(requestCode, resultCode, imageReturnedIntent); switch (requestCode) { case Constants.REQ_CODE_IMAGE_CAPTURE: // handle added image } } 

Решено, переместив всю логику onActivityResult из Fragment в Activity .

Обратите внимание , однако, что reqCode который передается в Fragment , отличается от reqCode который доставляется в родительскую Activity (тот, который для Activity задается системой, я думаю). Это означало, что мне также пришлось перенести исходный вызов startActivityForResult из Fragment в Activity , а затем создать метод для его вызова из Fragment когда это необходимо.

Если кто-нибудь найдет более элегантный способ, я буду рад услышать об этом.

У меня есть одно решение, которое оно сейчас работает в моем проекте. Следуйте за шагом.

-> Создать имя интерфейса OnActivityResultListener (или имя по своему усмотрению).

Открытый интерфейс OnActivityResultListener {

 public boolean onActivityResultTest(int request_code, int response_code, Intent data); 

}

-> Сделайте refrence intercace в своем FragmentActivity, как

 public OnActivityResultListener activityResultListener; 

-> теперь переопределить OnActivityResult в FragmentActivity. Как показано ниже.

 @Override public void onActivityResult(int arg0, int arg1, Intent arg2) { AppLog.Log(TAG, "onActivityResult"); try { if (activityResultListener != null) { activityResultListener.onActivityResultTest(arg0,arg1,arg2); } } catch (Exception e) { e.printStackTrace(); } super.onActivityResult(arg0, arg1, arg2); } 

-> теперь реализуем интерфейс в вашем фрагменте и переопределяем требуемый метод.

 @Override public boolean onActivityResultTest(int requestCode, int resultCode, Intent data) { AppLog.Log(TAG, "onActivityResultTest"); if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) { isHavePhoto = true; bitmap = (Bitmap) data.getExtras().get("data"); userEditPhoto.setImageBitmap(bitmap); } } 

->, и последний шаг внутри класса OnAttach Method of Fragment регистрирует ваш фрагмент в действии для результата Activity. как

 @Override public void onAttach(Activity activity) { this.activity = (YOUR_FRAGMENT_ACTIVITY) activity; this.activity.activityResultListener = this; super.onAttach(activity); } 

-> теперь проверяйте и не забывайте удалить его

 @Override public void onDestroyView() { activity.activityResultListener = null; super.onDestroyView(); } 

-> это какой-то длительный процесс, но он работает на 100% в любой ориентации.