Неправильный код запроса в 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т. Д. С установленным случайным старшим битом. Документы ничего не говорят об этом. Любые идеи?


Ответы:


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


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.