onActivityResult не вызывается во фрагменте

Активность, на которой размещен этот фрагмент, получает onActivityResult вызов, когда возвращается активность камеры.

Мой фрагмент запускает действие для результата с намерением, отправленным на камеру, чтобы сделать снимок. Приложение для изображений загружается нормально, делает снимок и возвращается. Однако onActivityResult никогда не попадает. Я установил точки останова, но ничего не срабатывает. Может у фрагмента есть onActivityResult? Я так думаю, потому что это предоставленная функция. Почему это не срабатывает?

ImageView myImage = (ImageView)inflatedView.findViewById(R.id.image);
myImage.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(cameraIntent, 1888);
    }
});

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if( requestCode == 1888 ) {
        Bitmap photo = (Bitmap) data.getExtras().get("data");
        ((ImageView)inflatedView.findViewById(R.id.image)).setImageBitmap(photo);
    }
}

person Spidy    schedule 27.05.2011    source источник
comment
проверьте этот пост, там есть описание проблемы и общее решение: stackoverflow.com/questions/6147884/   -  person Oleksii K.    schedule 19.06.2014
comment
Все, кто читает это, убедитесь, что вы прошли requestCode >= 0!   -  person Muhammad Babar    schedule 26.08.2015
comment
Также убедитесь, что ваш Activity LauchMode не должен содержать singleInstance или singleTask. в противном случае onActivityResult не будет вызываться   -  person AndroidGeek    schedule 05.08.2016
comment
Эта ссылка может вам помочь: androidtutorialonline.com/onactivityresult-in-fragment   -  person Android Tutorial    schedule 17.09.2018
comment
Нам нужно перенаправить onActivityResult в Activity на фрагмент. Перейдите по этой ссылке: codexpedia.com/android/   -  person Reejesh PK    schedule 10.12.2018
comment
Как вы вообще можете вызвать startActivityForResult(cameraIntent, 1888); из фрагмента. Фрагменты - это части макета, которые не могут взаимодействовать с операцией действия, если вы не собираетесь это делать. Вы можете вызвать getActivity().startActivityForResult(cameraIntent, 1888); И когда результат вернется, передать его фрагменту fragment.onActivityResult(-,-,-)   -  person Ian Elvister    schedule 11.03.2021


Ответы (39)


Действия хостинга отменяют onActivityResult(), но не обращаются к super.onActivityResult() для получения необработанных кодов результатов. Очевидно, несмотря на то, что именно фрагмент выполняет вызов startActivityForResult(), действие получает первый шанс обработать результат. Это имеет смысл, если учесть модульность фрагментов. Как только я реализовал super.onActivityResult() для всех необработанных результатов, фрагмент получил шанс обработать результат.

А также из ответа @siqing:

Чтобы получить результат в вашем фрагменте, убедитесь, что вы вызываете startActivityForResult(intent,111); вместо getActivity().startActivityForResult(intent,111); внутри вашего фрагмента.

person Spidy    schedule 27.05.2011
comment
У меня такая же проблема, но я не понимаю, как вы ее исправили? - person Codejoy; 08.07.2011
comment
В своем действии onActivityResult вызовите super.onActivityResult () - person Spidy; 08.07.2011
comment
Извините, но у меня это не работает ... @Override public void onActivityResult (int requestCode, int resultCode, Intent data) {super.onActivityResult (requestCode, resultCode, data); } не буду отправлять onActivityResult моим фрагментам ... - person StErMi; 14.01.2012
comment
@StErMi Вы вызывали startActivityForResult() в своих фрагментах? Думаю, если вы вызовете этот метод в действии, он не будет уведомлять о его фрагментах ... Просто догадываюсь ... - person ; 26.05.2012
comment
@Spidy: +1 за ваши ответы ... такая мелочь, но я проигнорировал ее. Благодарность - person Zoombie; 01.07.2012
comment
@StErMi Убедитесь, что вы вызываете startActivityForResult (), а не getActivity (). StartActivityForResult () из вашего фрагмента. См. Ответ ниже. - person OferR; 08.08.2012
comment
Похоже, есть связанная ошибка, когда используется библиотека поддержки code .google.com / p / android / issues / detail? id = 15394. - person Ollie C; 09.08.2012
comment
Также обратите внимание, что если вы используете вложенные фрагменты, дочерний фрагмент должен вызывать getParentFragment().startActivityForResult, чтобы у родительского фрагмента был вызван метод onActivityResult. - person Eric Brynsvold; 10.09.2013
comment
была ли эта проблема исправлена ​​в более новых версиях библиотеки поддержки? - person android developer; 23.11.2013
comment
возможно, этот вопрос / ответ был создан в эпоху 3.0 - person Spidy; 25.11.2013
comment
У меня есть super.onActivityResult как во фрагменте, так и в действии. Все равно не работает :( - person emen; 05.03.2014
comment
@OferR, но тогда возникает проблема с возвращением неправильного кода запроса. - person user1940676; 18.03.2014
comment
Это приблизило меня к решению моей проблемы, но у меня уже было super.onActivityResult() в моей активности хоста. Просмотрите мой ответ ниже, чтобы узнать о другом рабочем решении. - person prolink007; 08.06.2014
comment
@EricBrynsvold был прав, startActivityForResult не работает во вложенных фрагментах. Для этого вам лучше вызвать getParentFragment (). StartActivityForResult (), и в этом родительском фрагменте вы можете реализовать onActivityResult () и в этом методе передать результат дочерним фрагментам, то есть: childFragment.getParentFragment (). onActivityResult (код запроса, код результата, данные) - person edrian; 07.01.2015
comment
Я обнаружил, что вызов startActivityForResult() из моего фрагмента, а затем наличие super.onActivityResult() в моем FragmentActivity заставляет ВСЕ фрагменты в getFragmentManager() вызывать их onActivityResult(). Обеспечение уникальности ВСЕХ кодов запросов. - person Unknownweirdo; 30.03.2015
comment
Если вы используете ViewPager, помимо того, что говорит этот ответ, вам также нужно делать то, что говорит @Oleksii Kropachov. Объединение обоих подходов решило мою проблему. - person Bitcoin Cash - ADA enthusiast; 29.04.2015
comment
что делать, если я хочу вызвать startActivityForResult из статического метода в моем фрагменте? Пожалуйста, помогите мне в этом. - person Shreyash Mahajan; 30.10.2015
comment
Спасибо, Спиди. Эта проблема, безусловно, могла стоить мне часов. Нет сомнений в том, что этот ответ принесет вам массу очков за stackoverflow на долгие годы вперед! - person Someone Somewhere; 17.12.2015
comment
Я считаю, что если Activity расширяет android.app.Activity, а не FragmentActivity, базовый метод onActivityResult ничего не делает. Даже в API 24. - person androidguy; 23.11.2016
comment
@Spidy добавляет super.onActivityResult (requestCode, result, intent) в Activity, который у меня не работает. - person Nishant Bhakta; 07.11.2017
comment
Также обратите внимание, что если вы обрабатываете отправку результата в методе onBackPressed (), вам не следует вызывать super.onBackPressed() - person Deepak Kumar; 20.06.2019
comment
Я хотел запустить намерение в своем адаптере, и я пробовал все методы, но не работал, наконец, я объявил интерфейс обратного вызова в своем адаптере, и я начал намерение в своем фрагменте и его исправили. - person masoudmjm; 17.02.2021

Я думаю, вы звонили getActivity().startActivityForResult(intent,111);. Вам следует позвонить startActivityForResult(intent,111);.

person siqing    schedule 13.06.2012
comment
У меня также была такая же проблема с RingtonePreference, расположенным в PreferenceFragment. К сожалению, RingtonePreference вызывает getActivity().startActivityForResult(), и я не получил результатов, хотя я вызываю super.onActivityResult в onActivityResult действия. Я был вынужден создать производный от RingtonePreference класс, который привязывается к PreferenceFragment и вызывает fragment.startActivityForResult(). - person Stan; 27.11.2013
comment
@siqing Я не могу вызвать startActivitForResult из своего статического метода. Любое решение для этого? Мне нужно использовать activity.startActivityForResult. Пожалуйста, помогите мне в этом - person Shreyash Mahajan; 30.10.2015

Вариант 1:

Если вы вызываете startActivityForResult() из фрагмента, вы должны вызывать startActivityForResult(), а не getActivity().startActivityForResult(), так как это приведет к фрагменту onActivityResult ().

Если вы не уверены, куда вы вызываете startActivityForResult() и как вы будете вызывать методы.

Вариант 2:

Поскольку Activity получает результат onActivityResult(), вам нужно будет переопределить onActivityResult() действия и вызвать super.onActivityResult() для распространения на соответствующий фрагмент для необработанных кодов результатов или для всех.

Если два вышеуказанных варианта не работают, обратитесь к варианту 3, так как он определенно сработает.

Вариант 3:

Явный вызов из фрагмента функции onActivityResult выглядит следующим образом.

В родительском классе Activity переопределите метод onActivityResult () и даже переопределите его в классе Fragment и вызовите его как следующий код.

В родительском классе:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
    fragment.onActivityResult(requestCode, resultCode, data);
}

В дочернем классе:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // In fragment class callback
}
person Vinayak    schedule 12.06.2013
comment
Это сработало для меня. Это неприятный обходной путь, но у меня нет лучшей идеи решить эту идиотскую ошибку ... - person Bogdan Zurac; 21.06.2013
comment
@Vivky, Ваш ответ у меня сработал. Но есть еще одна проблема, с которой я столкнулся, вместо setResult(); finish();, когда я возвращаюсь из второго действия, тогда также onActivityResult вызывается с предоставленным RESULT_CODE. - person snehal_penurkar; 09.08.2015
comment
отличный ответ. Я применил третье решение, чтобы это сделать. - person Sash_KP; 13.10.2015
comment
Я думаю, что решение 3 сработает для меня, но onActivityResult() активности возвращает странный requestCode, который передается моему фрагменту, а затем игнорируется = / - person E-Kami; 21.01.2016
comment
@Happy Vicky, это означает, что даже когда startActivityForResult () вызывается из фрагмента, результат получен и может быть обработан в действии? - person notGeek; 06.02.2018
comment
@notGeek Вы правы. Результат всегда получается в Activity, даже если вы вызывались из фрагмента или активности. - person Vinayak; 07.02.2018
comment
в дочернем классе это должно быть public void onActivityResult(int requestCode, int resultCode, Intent data) {, а не protected - person Shailendra Madda; 07.03.2018
comment
на самом деле, это зависит от `@ShylendraMadda, когда мы называем вещи защищенными, мы немедленно ищем понятие области доступа. Я думаю, что автор здесь намеревался защитить. - person EvOlaNdLuPiZ; 23.02.2019
comment
Если вы используете компонент навигации Android, вы должны увидеть этот ответ stackoverflow.com/questions/6147884/ - person Mohit Mehta; 22.11.2019
comment
Это сработало для меня. Просто измените getFragmentManager () на getSupportFragmentManager () в Activity, и фрагмент больше не был нулевым. - person Rodrigo Jardim; 08.08.2020

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

//Джава

// In your activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    for (Fragment fragment : getSupportFragmentManager().getFragments()) {
        fragment.onActivityResult(requestCode, resultCode, data);
    }
}

// Котлин

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        for (fragment in supportFragmentManager.fragments) {
            fragment.onActivityResult(requestCode, resultCode, data)
        }
    }
person ruX    schedule 27.03.2014
comment
Блин, я думал, что нашел самое простое решение, но такого метода, как getFragments (), нет. - person WindRider; 09.05.2014
comment
@WindRider Есть. Если вы используете библиотеку поддержки Android (AppCompat). - person dasar; 28.10.2014
comment
Кроме того, я на собственном горьком опыте узнал, что вам нужно проверять, не является ли фрагмент в массиве ссылкой на самого себя! `if (фрагмент! = это) {fragment.onActivityResult (requestCode, resultCode, data); ` - person reubenjohn; 11.02.2015
comment
Это не работает, если фрагменты вложены, так как в списке будет только верхний фрагмент. Я считаю, что super.onActivityResult () уже вызывает onActivityResult () для всех фрагментов в списке, поэтому эта идея избыточна. - person BeccaP; 02.09.2015
comment
stackoverflow.com/questions/27343945/ - person maruti060385; 01.12.2015
comment
как насчет android.app.Fragment? как получить все фрагменты? - person Rjz Satvara; 10.09.2016
comment
@RjzSatvara для реализации нативных фрагментов. Я использовал обратные вызовы, трансляции и шину сообщений. - person ruX; 10.09.2016
comment
Всегда проверяйте наличие нулевого фрагмента в fragmentManager. Я усвоил это на собственном горьком опыте. Скопировал этот код и вылетел из приложения. - person VipulKumar; 29.09.2016
comment
Если вы используете компонент навигации Android, вы должны увидеть этот ответ stackoverflow.com/questions/6147884/ - person Mohit Mehta; 22.11.2019
comment
Это работает как обаятельный человек, Ты спас мне день. Большое спасибо, дружище. - person Rohit Patil; 08.12.2020

У меня такая же проблема с ChildFragmentManager. Менеджер не передаст результат во вложенный фрагмент, вы должны сделать это вручную в своем базовом фрагменте.

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    Fragment fragment = (Fragment) getChildFragmentManager().findFragmentByTag(childTag);
    if (fragment != null) {
        fragment.onActivityResult(requestCode, resultCode, intent);
    }
}
person MinceMan    schedule 08.05.2013
comment
Если у вас есть дочерний фрагмент в качестве закрытого члена, используйте Fragment fragment = myChildFragment;, чтобы заменить указанную выше findFragmentByTag строку кода. Остальное можно оставить без изменений. - person lcn; 20.11.2013
comment
Думаю, я бы настоятельно рекомендовал не хранить фрагмент в качестве закрытого члена. У них есть свой жизненный цикл, поэтому вы никогда не узнаете, в хорошем ли состоянии они для взаимодействия, а менеджер знает. Кроме того, они довольно здоровенные, и я был бы обеспокоен утечками памяти. Менеджер не был бы создан, если бы вам не нужно было его использовать. - person MinceMan; 22.11.2013

Исходное сообщение.

FragmentActivity заменяет requestCode модифицированным. После этого, когда onActivityResult() будет вызван, FragmentActivity анализирует старшие 16 бит и восстанавливает индекс исходного фрагмента. Взгляните на эту схему:

Введите описание изображения здесь

Если у вас есть несколько фрагментов на корневом уровне, проблем нет. Но если у вас есть вложенные фрагменты, например Fragment с несколькими вкладками внутри ViewPager, вы гарантированно столкнетесь с проблемой (или уже столкнулись с ней).

Потому что только один индекс хранится внутри requestCode. Это индекс Fragment внутри FragmentManager. Когда мы используем вложенные фрагменты, есть дочерние FragmentManager, у которых есть собственный список фрагментов. Итак, необходимо сохранить всю цепочку индексов, начиная с корня FragmentManager.

Введите описание изображения здесь

Как решить эту проблему? Существует общее временное решение в этот пост.

GitHub: https://github.com/shamanland/nested-fragment-issue

person Oleksii K.    schedule 19.06.2014
comment
У меня такая же проблема, как я использовал ViewPager в родительском фрагменте, который содержит другие фрагменты как вкладки. Пытался использовать проблему вложенного фрагмента, но в итоге возникли ошибки компиляции. Вы можете мне предложить решение? Здесь также поднимались вопросы github.com/shamanland/nested-fragment-issue/issues / 2 - person cgr; 13.11.2015
comment
Я ответил на github, так что давайте уберем этот разговор отсюда github .com / shamanland / nested-fragment-issue / issues /. - person Oleksii K.; 13.11.2015
comment
Спасибо! Если это не рекомендуемое решение, я предлагаю отредактировать ответ соответствующим образом, чтобы не приходилось тратить время на попытки узнать, что у него есть ошибки компиляции. - person cgr; 13.11.2015

Это одна из самых популярных проблем. Мы можем найти множество веток по этой проблеме. Но ни один из них мне не пригодится.

Итак, я решил эту проблему с помощью этого решения.

Давайте сначала разберемся, почему это происходит.

Мы можем вызывать startActivityForResult прямо из Fragment, но на самом деле все механики обрабатываются Activity.

После вызова startActivityForResult из фрагмента requestCode будет изменен, чтобы прикрепить идентификатор фрагмента к коду. Это позволит Activity отслеживать тех, кто отправил этот запрос, после получения результата.

После возврата к Activity результат будет отправлен в onActivityResult Activity с измененным requestCode, который будет декодирован в исходный идентификатор requestCode + Fragment. После этого Activity отправит результат действия этому фрагменту через onActivityResult. И все сделано.

Проблема:

Activity может отправить результат только фрагменту, который был прикреплен непосредственно к Activity, но не вложенному. По этой причине onActivityResult вложенного фрагмента никогда не вызывается, несмотря ни на что.

Решение:

1) Начните намерение в своем фрагменте с помощью кода ниже:

       /** Pass your fragment reference **/
       frag.startActivityForResult(intent, REQUEST_CODE); // REQUEST_CODE = 12345

2) Теперь в переопределении родительской активности ** _ 4_: **

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

Вы должны вызвать это в родительском действии, чтобы оно работало.

3) В вызове фрагмента:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {

       }
}

Вот и все. С помощью этого решения его можно было применить к любому отдельному фрагменту, независимо от того, является он вложенным или нет. И да, он также охватывает все случаи жизни! К тому же коды тоже красивые и чистые.

person KishuDroid    schedule 01.09.2016
comment
Я запрашивал намерение системы с «активностью», мне просто нужно было использовать контекст фрагмента. - person Uzair; 23.05.2019

ДЛЯ МНОГИХ ВЛОЖЕННЫХ ФРАГМЕНТОВ (например, при использовании ViewPager во фрагменте)

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

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
}

В вашем фрагменте:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    for (Fragment fragment : getChildFragmentManager().getFragments()) {
        fragment.onActivityResult(requestCode, resultCode, data);
    }
}

Во вложенном фрагменте

Активность звонков

getParentFragment().startActivityForResult(intent, uniqueInstanceInt);

uniqueInstanceInt - замените его на int, который уникален среди вложенных фрагментов, чтобы другой фрагмент не обработал ответ.

Получите ответ

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == uniqueInstanceInt ) {
        // TODO your code
    }
}

Внимание

Число от 0 до 65536 необходимо использовать в uniqueInstanceInt во избежание ошибки «Может использовать только младшие 16 бит для requestCode».

person Luciano Marqueto    schedule 22.01.2016
comment
Отлично работает в Activity ›Fragment (ViewPager)› Fragment - person Oleksandr Firsov; 04.03.2016

Тем, кто использует компонент навигации Android, следует использовать в onActivityResult(...) действия primaryNavigationFragment для получить ссылку на фрагмент и вызвать fragment.onActivityResult(...) фрагмента.

Вот активность onActivityResult(...)

@Override
public void onActivityResult(int requestCode, int resultCode, Intent imageData)
{
    super.onActivityResult(requestCode, resultCode, imageData);

    for (Fragment fragment : getSupportFragmentManager().getPrimaryNavigationFragment().getChildFragmentManager().getFragments())
    {
            fragment.onActivityResult(requestCode, resultCode, imageData);
    }
}
person Mohit Mehta    schedule 22.11.2019
comment
спасибо, это сработало как шарм - person Nikhil Sharma; 15.07.2021

Я также столкнулся с той же проблемой, когда переместил этот блок кода за пределы фрагмента в служебный класс с parentActivity, переданным как аргумент,

Intent intent = new Intent(parentActivity, CameraCaptureActivity.class);
parentActivity.startActivityForResult(intent,requestCode);

Тогда я не получал никакого значения в onActivityResult методе этого Фрагмента. После этого я изменил аргумент на Фрагмент, поэтому измененное определение метода выглядит как,

Intent intent = new Intent(fragment.getContext(), CameraCaptureActivity.class);
fragment.startActivityForResult(intent,requestCode);

После этого я смог получить значение onActivityResult в Фрагменте.

person Shamsul Arefin Sajib    schedule 07.02.2018

Могу добавить два совета, если кто-то все еще не может этого сделать. В файле Manifest.xml убедитесь, что активность хостинга не завершилась при обратном вызове, а активность, которую нужно запустить, имеет стандартный режим запуска. См. Подробности ниже:

Для активности хостинга установите для свойства no history значение false, если есть

android:noHistory="false"

Для запуска Activity установите стандартный режим запуска, если

android:launchMode="standard"
person jowett    schedule 30.12.2012

Версия Kotlin для тех, кто использует компонент навигации Android, вдохновленный ответом Мохита Мехты

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    supportFragmentManager.primaryNavigationFragment?.childFragmentManager?.fragments?.forEach { fragment ->
        fragment.onActivityResult(requestCode, resultCode, data)
    }
}
person Oscar Emilio Perez Martinez    schedule 07.04.2020
comment
Это правильный код переопределения fun onActivityResult (requestCode: Int, resultCode: Int, data: Intent?) {Super.onActivityResult (requestCode, resultCode, data) activity? .SupportFragmentManager? .PrimaryNavigationFragment ?. childFragmentManager? .fragments? .forEach {фрагмент - ›fragment.onActivityResult (requestCode, resultCode, data)}} - person Felipe Franco; 22.08.2020
comment
Работа с навигационным компонентом Kotlin - person Chirag Savsani; 28.08.2020
comment
Должен ли я писать код (например, if (resultCode! = Result_ok)) внутри области forEach или внутри основной области после области forEach? - person Abdulsamet Kılınçarslan; 11.05.2021
comment
Это решило мою проблему, фрагмент навигационного графика onActivityResult. Отличная работа - person Hossein Kurd; 11.07.2021

Я также встретил эту проблему во фрагменте. И я позвонил startActivityForResult в DialogFragment.

Но теперь эта проблема решена:
FragmentClassname.this.startActivityForResult.

person Courysky    schedule 24.12.2014
comment
Отлично, у меня сработало, потому что я вызывал startActivityForResult(...) из абстрактного класса внутри кода фрагмента. - person Vince; 19.07.2015

ДЛЯ ВЛОЖЕННЫХ ФРАГМЕНТОВ (например, при использовании ViewPager)

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

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
}

В вашем основном фрагменте верхнего уровня (фрагмент ViewPager):

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    YourFragment frag = (YourFragment) getChildFragmentManager().getFragments().get(viewPager.getCurrentItem());
    frag.yourMethod(data);  // Method for callback in YourFragment
    super.onActivityResult(requestCode, resultCode, data);
}

В YourFragment (вложенный фрагмент):

public void yourMethod(Intent data){
    // Do whatever you want with your data
}
person Jyotman Singh    schedule 17.11.2015

В моем случае это была ошибка Android (http://technet.weblineindia.com/mobile/onactivityresult-not-getting-called-in-nested-fragments-android/), если вы используете поддерживаемый FragmentActivity, вы должны использовать getSupportFragmentManager вместо getChildFragmentManager:

List<Fragment> fragments = getSupportFragmentManager().getFragments();
if (fragments != null) {
    for (Fragment fragment : fragments) {
        if(fragment instanceof UserProfileFragment) {
            fragment.onActivityResult(requestCode, resultCode, data);
        }
    }
}
person Hazlo8    schedule 14.12.2015

Суммируя,

Во фрагменте объявить Fragment fragment = this;

после этого используйте fragment.startActivityForResult.

Результат вернется в activityResult.

person Clevester    schedule 18.07.2014

Решение 1:

Звоните startActivityForResult(intent, REQUEST_CODE); вместо getActivity().startActivityForResult(intent, REQUEST_CODE);.

Решение 2:

Когда вызывается startActivityForResult(intent, REQUEST_CODE);, вызывается onActivityResult(requestCode,resultcode,intent) действия, а затем вы можете вызвать fragments onActivityResult() отсюда, передав requestCode, resultCode and intent.

person Amey Haldankar    schedule 18.12.2014

Внутри вашего фрагмента позвоните

this.startActivityForResult(intent, REQUEST_CODE);

где this относится к фрагменту. В противном случае сделайте, как сказал @Clevester:

Fragment fragment = this;
....
fragment.startActivityForResult(intent, REQUEST_CODE);

Мне также пришлось позвонить

super.onActivityResult(requestCode, resultCode, data);

в onActivityResult родительского действия, чтобы оно работало.

(Я адаптировал этот ответ из ответа @Clevester.)

person Suragch    schedule 23.12.2014

При использовании компонента навигации Android эта проблема, когда у вас есть вложенные фрагменты, может показаться неразрешимой загадкой.

Основываясь на знаниях и вдохновении из следующих ответов в этом посте, мне удалось придумать простое решение, которое работает:

В onActivityResult() вашего действия вы можете просмотреть список активных фрагментов, который вы получите с помощью метода FragmentManager getFragments().

Обратите внимание, что для этого вам необходимо использовать getSupportFragmentManager() или API таргетинга 26 и выше.

Идея здесь состоит в том, чтобы пройти по списку, проверяя тип экземпляра каждого фрагмента в списке, используя instanceof.

Хотя цикл по этому списку типа Fragment является идеальным, к сожалению, когда вы используете компонент навигации Android, в списке будет только один элемент, то есть NavHostFragment.

Что теперь? Нам нужно, чтобы Фрагменты были известны NavHostFragment. NavHostFragment сам по себе является Фрагментом. Итак, используя getChildFragmentManager().getFragments(), мы снова получаем List<Fragment> фрагментов, известных нашему NavHostFragment. Мы просматриваем этот список, проверяя instanceof каждый фрагмент.

Как только мы находим интересующий нас Фрагмент в списке, мы вызываем его onActivityResult(), передавая ему все параметры, которые объявляет onActivityResult() Activity.

//  Your activity's onActivityResult()

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        List<Fragment> lsActiveFragments = getSupportFragmentManager().getFragments();
        for (Fragment fragmentActive : lsActiveFragments) {

            if (fragmentActive instanceof NavHostFragment) {

                List<Fragment> lsActiveSubFragments = fragmentActive.getChildFragmentManager().getFragments();
                for (Fragment fragmentActiveSub : lsActiveSubFragments) {

                    if (fragmentActiveSub instanceof FragWeAreInterestedIn) {
                        fragmentActiveSub.onActivityResult(requestCode, resultCode, data);
                    }

                }

            }

        }

    }

person Edward Quixote    schedule 13.03.2020

В большинстве этих ответов говорится, что вам нужно вызвать super.onActivityResult(...) на вашем хосте Activity для вашего Fragment. Но это, похоже, не помогло мне.

Итак, на вашем хосте Activity вы должны вместо этого вызвать ваш Fragments onActivityResult(...). Вот пример.

public class HostActivity extends Activity {

    private MyFragment myFragment;

    protected void onActivityResult(...) {
        super.onActivityResult(...);
        this.myFragment.onActivityResult(...);
    }
}

В какой-то момент в вашем HostActivity вам нужно будет назначить this.myFragment тот Fragment, который вы используете. Или используйте FragmentManager, чтобы получить Fragment, вместо того, чтобы сохранять ссылку на него в вашем HostActivity. Кроме того, проверьте null, прежде чем пытаться вызвать this.myFragment.onActivityResult(...);.

person prolink007    schedule 08.06.2014

  1. Вы можете просто переопределить BaseActivity onActivityResult на фрагменте baseActivity.startActivityForResult.

  2. В BaseActivity добавьте интерфейс и переопределите onActivityResult.

    private OnBaseActivityResult baseActivityResult;
    public static final int BASE_RESULT_RCODE = 111;
    public interface OnBaseActivityResult{
        void onBaseActivityResult(int requestCode, int resultCode, Intent data);
       }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(getBaseActivityResult() !=null && requestCode == BASE_RESULT_RCODE){
        getBaseActivityResult().onBaseActivityResult(requestCode, resultCode, data);
        setBaseActivityResult(null);
    }
    
  3. На фрагменте орудия OnBaseActivityResult

    @Override
    public void onBaseActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("RQ","OnBaseActivityResult");
    if (data != null) {
        Log.d("RQ","OnBaseActivityResult + Data");
        Bundle arguments = data.getExtras();
      }
    }
    

Этот обходной путь поможет.

person Khaled Lela    schedule 31.03.2015

Если указанная выше проблема возникает при входе в Facebook, вы можете использовать приведенный ниже код в родительском действии вашего фрагмента, например:

Fragment fragment = getFragmentManager().findFragmentById(android.R.id.tabcontent);
fragment.onActivityResult(requestCode, resultCode, data);

Или:

Fragment fragment = getFragmentManager().findFragmentById("fragment id here");
fragment.onActivityResult(requestCode, resultCode, data);

И добавьте в свой фрагмент приведенный ниже вызов ...

callbackManager.onActivityResult(requestCode, resultCode, data);
person Ketan Patel    schedule 27.10.2015

Другой вариант использования, еще не описанный в других ответах:

onActivityResult(), объявленный во фрагменте, не вызывается при использовании exception.startResolutionForResult():

if (exception is ResolvableApiException) {
    exception.startResolutionForResult(activity!!, MY_REQUEST_CODE)
}

В этом случае замените exception.startResolutionForResult() на startIntentSenderForResult() фрагмента:

if (exception is ResolvableApiException) {
    startIntentSenderForResult(exception.resolution.intentSender, MY_REQUEST_CODE, null, 0, 0, 0, null)
}
person dominik    schedule 18.08.2019

Версия Kotlin (в вашей деятельности onActivityResult ())

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    //add following lines in your activity
    if(supportFragmentManager?.fragments!=null && supportFragmentManager?.fragments!!.size>0)
     for (i in 0..supportFragmentManager?.fragments!!.size-1) {
         val fragment= supportFragmentManager?.fragments!!.get(i)
         fragment.onActivityResult(requestCode, resultCode, data)
    }
 }
person Ranjith Kumar    schedule 27.08.2019

Добавь это

public void onClick(View v) {   
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, 1);
}

когда вы замените свой код этим приведенным выше кодом, тогда автоматически этот

public void onActivityResult(int requestCode, int resultCode,
@Nullable Intent data){}

Метод начнет работать

//No Need to write this code in onclick method
    Intent intent=new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT)
    startActivityForResult(intent,1);
    Toast.makeText(getContext(), "image"+intent, Toast.LENGTH_SHORT).show();
person Bytecode    schedule 20.02.2012

Как упоминал Олли Си, существует активная ошибка для библиотеки поддержки, использующей возвращаемые значения для onActivityResult, когда вы используете вложенные фрагменты. Просто ударил :-(.

См. Fragment.onActivityResult не вызывается, когда requestCode! = 0.

person chaqke    schedule 09.06.2014

У меня есть сильное подозрение, что все ответы здесь не более чем хаки. Я перепробовал их все и многие другие, но без каких-либо надежных выводов, поскольку всегда есть какая-то глупая проблема. Я лично не могу полагаться на противоречивые результаты. Если вы посмотрите официальную документацию Android API для фрагментов, вы увидите, что Google четко заявляет следующее:

Вызовите startActivityForResult (Intent, int) из объекта Activity, содержащего фрагмент.

См .: API фрагментов Android

Таким образом, может показаться, что наиболее правильным и надежным подходом было бы фактически вызвать startActivityForResult () из активности хостинга, а также обработать полученный onActivityResult () оттуда.

person Chris    schedule 15.09.2014
comment
Я не думаю, что вызов startActivityForResult из Activity является рекомендацией. Если вы посмотрите на реализацию внутри базового класса Fragment, то все, что он делает, это mActivity.startActivityFromFragment(this, intent, requestCode) - так что это не что иное, как удобная оболочка. - person Anti Veeranna; 02.10.2014

В вашем коде есть вложенный фрагмент. Вызов super.onActivityForResult не работает

Вы не хотите изменять каждое действие, из которого может быть вызван ваш фрагмент, или обходиться вызовом каждого фрагмента в цепочке фрагментов.

Вот одно из многих рабочих решений. создайте фрагмент на лету и подключите его напрямую к операции с помощью диспетчера фрагментов поддержки. Затем вызовите startActivityForResult из вновь созданного фрагмента.

private void get_UserEmail() {

    if (view == null) {
        return;
    }
    ((TextView) view.findViewById(R.id.tvApplicationUserName))
            .setText("Searching device for user accounts...");

    final FragmentManager fragManager = getActivity().getSupportFragmentManager();

    Fragment f = new Fragment() {
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            startActivityForResult(AccountPicker.newChooseAccountIntent(null, null,
                    new String[]{"com.google"}, false, null, null, null, null), REQUEST_CODE_PICK_ACCOUNT);
        }

        @Override
        public void onActivityResult(int requestCode, int resultCode,
                                     Intent data) {
            if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
                String mEmail = "";
                if (resultCode == Activity.RESULT_OK) {
                    if (data.hasExtra(AccountManager.KEY_ACCOUNT_NAME)) {
                        mEmail = data
                                .getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                    }
                }
                if (mActivity != null) {
                    GoPreferences.putString(mActivity, SettingApplication.USER_EMAIL, mEmail);
                }
                doUser();
            }
            super.onActivityResult(requestCode, resultCode, data);
            fragManager.beginTransaction().remove(this).commit();
        }
    };
    FragmentTransaction fragmentTransaction = fragManager
            .beginTransaction();
    fragmentTransaction.add(f, "xx" + REQUEST_CODE_PICK_ACCOUNT);
    fragmentTransaction.commit();
}
person danny117    schedule 23.11.2014
comment
Это действительно работает, и у меня есть только один голос. Создавайте фрагменты на лету. Слишком простое, но настоящее рабочее решение. Кто-то даже пытался его отредактировать для меня. - person danny117; 14.06.2016

Моя проблема заключалась в активности хоста. Я нашел ее с помощью набора android:launchMode="standard" Я временно удалил ее, и она работает!

person Cool    schedule 23.06.2016

Одна точка, mention которой нет ни у кого, чтобы убедиться, что режим запуска активности хоста не должен быть установлен на singleInstance или singleTask.

onActivityResult не будет работать, если ваш режим запуска установлен на SingleInstance или SingleTask. или вы называете свою деятельность с помощью этих IntentFilters

Режим запуска standard или singleTop будет работать нормально.

person AndroidGeek    schedule 04.08.2016

Если вы используете вложенные фрагменты, это тоже работает:

getParentFragment().startActivityForResult(intent, RequestCode);

В дополнение к этому вы должны вызвать super.onActivityResult из родительской активности и заполнить onActivityResult метод фрагмента.

person Oguz Ozcan    schedule 16.11.2015

прежде всего вам нужно переопределить этот код в Activity;

 @Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
}

а после, в вашем фрагменте,

startActivityForResult(intent,GALLERY_REQUEST_CODE);

и снова, чем в вашем фрагменте,

@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    // Result code is RESULT_OK only if the user selects an Image
    if (resultCode == Activity.RESULT_OK) {

    }

}
person ozanurkan    schedule 12.11.2019

Один из самых простых способов - начать действие с вашего фрагмента.

startActivity(ActivityName);

Затем добавьте вызов startActivityForResult(intent,"1"); из своей деятельности и добавьте onActivityResult в свою деятельность.

startActivityForResult(intent,"1");

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
    fragment.onActivityResult(requestCode, resultCode, data);
// perform other activity result like fetching from Uris or handling cursors

finish(); // finish the activity will  get to back to your fragment.
}
person Rohit Goyal    schedule 30.05.2016

Я просто использую обходной метод:

public static Fragment _tempFragment = null;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(_tempFragment != null)
        _tempFragment.onActivityResult(requestCode, resultCode, data);
}

В вашем фрагменте перед startActivityResult установите

MainActivity._tempFragment = this;

После onActivityResult ‹- во фрагменте

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
     super.onActivityResult(requestCode, resultCode, data);

     // Do your job
     {

     }
     MainActivity._tempFragment = null;
}
person Ah Lam    schedule 06.11.2013
comment
Зачем использовать метод обхода, если фреймворк его уже поддерживает? - person Spidy; 07.11.2013
comment
Например Facebook - ›Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data); - person Ah Lam; 09.11.2013

Просто используйте приведенный ниже код для фрагмента.

@Override
public void onOtherButtonClick(ActionSheet actionSheet, int index) {

    if (index == 1)
    {
        Intent intent = new Intent(Intent.ACTION_PICK,
                                   android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.setType("image/*");
        startActivityForResult(Intent.createChooser(intent,
                                                    "Select Picture"), 1);
     }
}

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == 1) {
        if (requestCode == 1) {
            Uri selectedImageUri = data.getData();
            //selectedImagePath = getPath(selectedImageUri);
        }
    }
}

onActivityResult будет вызывать без вызова своего родителя.

person Kirtikumar A.    schedule 26.12.2014

Если есть проблема с методом onActivityResult, который находится внутри класса фрагмента, и вы хотите обновить что-то, что также находится внутри класса фрагмента, используйте:

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

    if(resultCode == Activity.RESULT_OK)
    {
        // If the user had agreed to enabling Bluetooth,
        // populate the ListView with all the paired devices.
        this.arrayDevice = new ArrayAdapter<String>(this.getContext(), R.layout.device_item);
        for(BluetoothDevice bd : this.btService.btAdapater.getBondedDevices())
        {
            this.arrayDevice.add(bd.getAddress());
            this.btDeviceList.setAdapter(this.arrayDevice);
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Просто добавьте this.variable, как показано в приведенном выше коде. В противном случае метод будет вызван в родительском действии, и переменная не будет обновлена ​​для текущего экземпляра.

Я также протестировал это, поместив этот блок кода в MainActivity, заменив this классом HomeFragment и сделав переменные статическими. Я получил результаты, как и ожидал.

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

person Evgeny Danilenko    schedule 04.05.2016

В моем случае в параметрах разработчика я включил Не сохранять действия, из-за чего возникла эта проблема.

В случае, если это кому-то поможет.

person Monster Brain    schedule 22.06.2020

onActivityResult теперь устарел. Вы можете использовать следующий код:

   registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result->
    // here you can handle result, result.data and result.resultCode
   }

Для начала деятельности

    val intent = Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE)
    launcher.launch(intent)
person Sherzodbek Muhammadiev    schedule 15.06.2021

Просто позвоните:

startActivityForResult(intent, "1");
person Nimit Raja    schedule 23.11.2015
comment
Не могли бы вы объяснить подробнее? - person Ronak Gadhia; 21.12.2016