Неправильный код запроса в onActivityResult

310

Я начинаю новую активность из моего фрагмента с

startActivityForResult(intent, 1);

и хотите обработать результат в родительской активности фрагмента:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG, "onActivityResult, requestCode: " + requestCode + ", resultCode: " + resultCode);
    if (requestCode == 1) {
        // bla bla bla
    }
}

Проблема в том, что я так и не получил сообщение, на которое requestCodeтолько что отправил startActivityForResult().

Я получил что-то подобное 0x40001и 0x20001т. Д. С установленным случайным старшим битом. Документы ничего не говорят об этом. Любые идеи?

Dimanoid
источник
возможный дубликат onActivityResult не вызывается во фрагменте
PhoneixS

Ответы:

838

Ты звонишь startActivityForResult()со своего Fragment. Когда вы делаете это, то requestCodeизменяется Activityвладельцем Fragment.

Если вы хотите получить правильные результаты resultCodeв своей деятельности, попробуйте это:

Изменить:

startActivityForResult(intent, 1);

Для того, чтобы:

getActivity().startActivityForResult(intent, 1);
Чанвэй Яо
источник
44
Потому что он должен решить, какой фрагмент доставит результат. Так что, когда Фрагмент вызывает StartActivityForResult. Код запроса будет изменен Активностью, поэтому он будет знать, как доставить результат в какой фрагмент. если вы действительно хотите получить результат в Activiy. просто вызовите getActivity (). startActivityForResult ().
Чанвэй Яо
31
Просто примечание: если вы используете startActivityForResultфрагмент и ожидаете результат от onActivityResultэтого фрагмента, просто убедитесь, что вы вызываете super.onActivityResultдействие хоста (если вы переопределяете этот метод там). Это потому, что активность, onActivityResultкажется, вызывает фрагмент onActivityResult. Также обратите внимание, что код запроса, когда он проходит через действие onActivityResult, изменяется, как объяснено в ссылке, которую Диманоид разместил в своем ответе ниже. Возможно, вам не нужно это знать, но вы никогда не узнаете ...
Ферран Мэйлинч
31
«Код запроса изменяется Активностью, которой принадлежит Фрагмент» - Должен полюбить дизайн Android ...
Tiago
13
Такая важная информация, которую вы не найдете нигде в документации. Должен любить дизайн Android, созданный, чтобы сделать вашу жизнь адом.
Дрисс Боунуар
2
Человек, которого я люблю, я провел много дней, пытаясь понять эту проблему и исправить ошибку, спасибо!
tinyCoder
35

Код запроса не неправильный. При использовании фрагментов библиотеки поддержки v4 индекс фрагмента кодируется в верхних 16 битах кода запроса, а код запроса - в нижних 16 битах. Позднее индекс фрагмента используется для поиска правильного фрагмента для доставки результата.

Следовательно, для Деятельности запущен объект фрагмента формы, обработайте onActivityResult requestCode, как показано ниже:

originalRequestCode = changedRequestCode - (indexOfFragment << 16)
      6             =      196614        -       (3 << 16)
Ашлеша шарма
источник
1
Отличная информация, которая объясняет точную причину этой проблемы
Muzikant
быстрый вопрос: что такое indexOfFragment?
Луи Цай
indexOfFragment - это индекс, который создает getSupportFragmentManager (). getFragments ()
HerberthObregon
25

Полегче:

Java : int unmaskedRequestCode = requestCode & 0x0000ffff

Котлин : val unmaskedRequestCode = requestCode and 0x0000ffff

Проверьте младшие 16 бит, просто снимите маску, выполнив логическое И с обнуленными старшими 16 битами

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    final int unmaskedRequestCode = requestCode & 0x0000ffff

    if(unmaskedRequestCode == ORIGINAL_REQUEST_CODE){
      //Do stuff

    }
}
Хайме Агудо
источник
1
Можете ли вы сказать мне причину, по которой он не дает исходный код запроса?
Софик
3
Причина, почему код запроса изменяется Деятельностью, которой принадлежит Фрагмент. См. Ашлеша Шарма ответ
Хайме Агудо
спасибо, это ответ, который я искал. Я не понимаю, почему Android не должен возвращать исходный код запроса.
tonisives
Это было очень полезно для меня сегодня и на самом деле очень хорошо объясняет проблему. Спасибо!
Билли Лаззаро
6

Если вы предоставляете постоянный, сделайте его публичным, а затем используйте в startActivityResult

пример:

public static final int REQUEST_CODE =1;
getActivity().startActivityForresult(intent, REQUEST_CODE);
Нилеш Тивари
источник
2

Вы также можете определить
super.onActivityResult(requestCode, resultCode, data)
в Activity(если вы переопределить onActivityResult) в этом

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {

        ...

        default:
            super.onActivityResult(requestCode, resultCode, data);
    }
}

и позвоните startActivityForResult(intent, requestCode)в свойFragment

TarikW
источник
0

во фрагменте

  getActivity().startActivityForResult(builder.build(getActivity()), PLACE_PICKER_REQUEST);

в основной деятельности:

if (requestCode == PLACE_PICKER_REQUEST) {
            if (resultCode == RESULT_OK) {    
     //what ever you want to do
            }
исключение нулевого указателя
источник