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

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

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

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

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

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

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

... я предполагаю, что родительский объект уничтожен из-за изменения ориентации, и после его повторного создания не может найти Fragment, который вызвал 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
    }
}

Ответ 1

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

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

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

Ответ 2

У меня есть одно решение он в настоящее время работает в моем проекте. выполните шаг.

- > Создать имя интерфейса 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 класса 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% в любой ориентации.