onActivityResult não está sendo chamado no fragmento

877

A atividade que hospeda esse fragmento é onActivityResultchamada quando a atividade da câmera retorna.

Meu fragmento inicia uma atividade para um resultado com a intenção enviada para a câmera tirar uma foto. O aplicativo de imagem carrega bem, tira uma foto e retorna. O onActivityResultporém nunca é atingido. Eu defini pontos de interrupção, mas nada é acionado. Um fragmento pode ter onActivityResult? Eu acho que sim, já que é uma função fornecida. Por que isso não está sendo acionado?

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);
    }
}
Spidy
fonte
2
verifique este post, não há descrição do problema e solução alternativa comum: stackoverflow.com/questions/6147884/...
Oleksii K.
5
Qualquer pessoa que esteja lendo isso não deixe de passar requestCode >= 0!
Muhammad Babar
3
Verifique também se o Activity LauchMode não deve singleInstance ou singleTask. caso contrário, onActivityResult não será chamado
Jawad Zeb
Veja este link pode ajudá-lo: androidtutorialonline.com/onactivityresult-in-fragment
Android Tutorial
Precisamos redirecionar o onActivityResult na atividade para o fragmento. Consulte este link: codexpedia.com/android/…
Reejesh PK

Respostas:

1240

A atividade de hospedagem substitui onActivityResult(), mas não super.onActivityResult()solicitou códigos de resultado não manipulados. Aparentemente, embora o fragmento seja o responsável pela startActivityForResult()chamada, a atividade é a primeira chance de lidar com o resultado. Isso faz sentido quando você considera a modularidade dos fragmentos. Depois que eu implementei super.onActivityResult()para todos os resultados não manipulados, o fragmento conseguiu lidar com o resultado.

E também da resposta @siqing:

Para obter o resultado no seu fragmento, ligue em startActivityForResult(intent,111);vez de getActivity().startActivityForResult(intent,111);dentro do fragmento.

Spidy
fonte
34
Em onActivityResult da sua atividade, super.onActivityResult call ()
Spidy
167
@StErMi Certifique-se de chamar startActivityForResult () e não getActivity (). StartActivityForResult () do seu fragmento. Veja a resposta siqing abaixo.
OferR 8/08/12
8
Parece haver um bug relacionado, em que a biblioteca de suporte está sendo usada code.google.com/p/android/issues/detail?id=15394
Ollie C
82
Observe também que se você estiver usando fragmentos aninhados, o fragmento filho deve chamar getParentFragment().startActivityForResultpara que o fragmento pai tenha seu método onActivityResult chamado.
Eric Brynsvold 10/10
7
@EricBrynsvold estava certo, startActivityForResult não funciona em fragmentos aninhados. Para isso, é melhor chamar getParentFragment (). StartActivityForResult () e nesse fragmento pai, então você pode implementar onActivityResult () e nesse método entregar o resultado ao fragmen filho, ou seja: childFragment.getParentFragment (). onActivityResult (requestCode, resultCode, data)
edrian
328

Eu acho que você ligou getActivity().startActivityForResult(intent,111);. Você deveria ligar startActivityForResult(intent,111);.

siqing
fonte
3
Eu também tive o mesmo problema com RingtonePreferencelocalizado em PreferenceFragment. Infelizmente, RingtonePreferenceligações getActivity().startActivityForResult()e eu não obtive resultados, mesmo que eu chamei super.onActivityResultas atividades onActivityResult. Fui obrigado a criar uma RingtonePreferenceclasse derivada , que se liga às PreferenceFragmentchamadas e fragment.startActivityForResult().
Stan
@siqing Não consigo chamar startActivitForResult do meu método estático. Alguma solução para isso? Preciso usar o activity.startActivityForResult. Por favor me ajude nisso #
Shreyash Mahajan 30/10
270

Opção 1:

Se você estiver chamando startActivityForResult()do fragmento, deverá chamar startActivityForResult(), não getActivity().startActivityForResult(), pois isso resultará no fragmento onActivityResult ().

Se você não tiver certeza de onde está ligando startActivityForResult()e como estará ligando para os métodos.

Opção 2:

Como Activity obtém o resultado onActivityResult(), você precisará substituir as atividades onActivityResult()e chamarsuper.onActivityResult() para propagar para o respectivo fragmento para códigos de resultados não manipulados ou para todos.

Se as duas opções acima não funcionarem, consulte a opção 3, pois ela definitivamente funcionará.

Opção 3:

Uma chamada explícita do fragmento para a função onActivityResult é a seguinte.

Na classe Activity pai, substitua o método onActivityResult () e até substitua o mesmo na classe Fragment e chame como o código a seguir.

Na classe pai:

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

Na classe filho:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // In fragment class callback
}
Vinayak
fonte
4
Isso funcionou para mim. É uma solução desagradável, mas eu não tenho uma idéia melhor para resolver este bug idiota ...
Bogdan Zurac
@ Vivky, sua resposta funcionou para mim. Mas há mais um problema que estou enfrentando, em vez de setResult(); finish();pressionar novamente a segunda atividade e também onActivityResultser chamado de fornecido RESULT_CODE.
snehal_penurkar
resposta excelente. Eu implementei a terceira solução para fazê-lo.
Sash_KP
Eu acho que a solução 3 funcionaria para mim, mas a onActivityResult()atividade retorna um estranho requestCodeque é passado para o meu fragmento e depois é ignorado = /
E-Kami
1
@notGeek Você está correto. O resultado é sempre recuperado em Activity, mesmo que você tenha chamado de fragmento ou atividade.
Vinayak,
83

Caso você não conheça fragmentos em sua atividade, apenas enumere todos eles e envie argumentos de resultado da atividade:

// 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);
    }
}
ruX
fonte
3
Porra, pensei que tinha acabado de encontrar a solução mais simples, mas não existe um método como getFragments ().
WindRider
2
@WindRider Existe. Se você usa a biblioteca de suporte do Android (AppCompat).
Dasar28
2
Além disso, aprendi da maneira mais difícil que você precisa verificar se o fragmento na matriz não é uma referência a si mesmo! `if (fragmento! = isto) {fragment.onActivityResult (requestCode, resultCode, data); `
reubenjohn
Isso não funciona se os fragmentos estiverem aninhados, pois apenas o fragmento superior estará na lista. Eu acredito que super.onActivityResult () já está chamando onActivityResult () em todos os fragmentos da lista, portanto, essa ideia é redundante.
BeccaP
83

Estou tendo o mesmo problema com o ChildFragmentManager. O gerente não passará o resultado para o fragmento aninhado, você deve fazer isso manualmente no fragmento base.

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);
    }
}
MinceMan
fonte
1
Se você tem o seu Fragmento filho como membro privado, use-o Fragment fragment = myChildFragment;para substituir a findFragmentByTaglinha de código acima . O restante pode ser mantido inalterado.
Lcn
7
Eu acho que eu recomendaria fortemente não manter um fragmento como membro privado. Eles têm seu próprio ciclo de vida, então você nunca sabe se eles estão em um bom estado para interagir, o gerente faz. Eles também são bem pesados ​​e eu ficaria preocupado com vazamentos de memória. O gerente não teria sido criado se você não precisasse usá-lo.
MinceMan
67

Postagem original.

FragmentActivitysubstitui requestCodepor um modificado. Depois disso, quando onActivityResult()será chamado, FragmentActivityanalisa os 16 bits mais altos e restaura o índice do fragmento original. Veja este esquema:

Digite a descrição da imagem aqui

Se você tiver alguns fragmentos no nível da raiz, não haverá problemas. Mas se você tiver fragmentos aninhados , por exemplo, Fragmentcom algumas guias dentro ViewPager, garantiu que terá um problema (ou já o enfrentou).

Porque apenas um índice é armazenado dentro requestCode. Esse é o índice de Fragmentdentro dele FragmentManager. Quando estamos usando fragmentos aninhados, existem filhos FragmentManager, que têm sua própria lista de fragmentos. Portanto, é necessário salvar toda a cadeia de índices, começando da raiz FragmentManager.

Digite a descrição da imagem aqui

Como resolvemos esse problema? Há uma solução alternativa comum nesta postagem .

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

Oleksii K.
fonte
Eu tenho o mesmo problema que usei um ViewPager no fragmento pai que contém outros fragmentos como guias. Tentei usar o problema de fragmento aninhado, mas acabou com erros de compilação. Você pode me sugerir a solução? Também levantou questões aqui github.com/shamanland/nested-fragment-issue/issues/2
cgr
Eu respondi no github, então vamos mover esta conversa daqui github.com/shamanland/nested-fragment-issue/issues/...
Oleksii K.
Obrigado! Se não for uma solução recomendada, sugiro editar a resposta adequadamente para que não seja necessário gastar tempo tentando isso para saber que possui erros de compilação.
CGR
44

Este é um dos problemas mais populares. Podemos encontrar muitos tópicos sobre esse problema. Mas nenhum deles é útil para mim.

Então, eu resolvi esse problema usando esta solução.

Vamos primeiro entender por que isso está acontecendo.

Podemos ligar startActivityForResultdiretamente do Fragment, mas, na verdade, o mecânico por trás é tratado pela Activity.

Depois de ligar startActivityForResult de um Fragment, requestCode será alterado para anexar a identidade do Fragment ao código. Isso permitirá que a Activity possa rastrear quem envia essa solicitação assim que o resultado é recebido.

Depois que a Atividade for navegada de volta, o resultado será enviado ao onActivityResult da Atividade com o requestCode modificado, que será decodificado para a identidade original do requestCode + Fragment. Depois disso, a Activity enviará o resultado da atividade para esse fragmento por meio de onActivityResult. E está tudo pronto.

O problema é:

A atividade pode enviar o resultado apenas para o fragmento que foi anexado diretamente à atividade, mas não ao aninhado. Essa é a razão pela qual onActivityResult do fragmento aninhado nunca seria chamado, não importa o quê.

Solução:

1) Inicie o Intent no seu fragmento pelo código abaixo:

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

2) Agora, em sua substituição da atividade dos pais **onActivityResult() : **

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

Você deve chamar isso na atividade dos pais para que funcione.

3) Na sua chamada de fragmento:

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

       }
}

É isso aí. Com esta solução, ela poderia ser aplicada a qualquer fragmento único, aninhado ou não. E sim, também cobre todo o caso! Além disso, os códigos também são agradáveis ​​e limpos.

KishuDroid
fonte
Eu estava solicitando a intenção do sistema com 'atividade', apenas tive que usar o contexto do fragmento.
Uzair
18

PARA MUITOS FRAGMENTOS NESTADOS (por exemplo, ao usar um ViewPager em um fragmento)

Na sua atividade principal :

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

No seu fragmento:

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

No seu fragmento aninhado

Atividade de chamada

getParentFragment().startActivityForResult(intent, uniqueInstanceInt);

uniqueInstanceInt - substitua-o por um int exclusivo entre os fragmentos aninhados para impedir que outro fragmento trate a resposta.

Receber resposta

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

Atenção

Um número entre 0 e 65536 precisa ser usado em uniqueInstanceInt para evitar erros "Pode usar apenas 16 bits inferiores para requestCode".

Luciano Marqueto
fonte
Funciona muito bem em Atividade> Fragmento (ViewPager)> Fragmento
Oleksandr Firsov
14

Posso acrescentar dois conselhos se alguém ainda não conseguir. No arquivo Manifest.xml, verifique se a atividade de hospedagem não terminou quando a chamada de retorno e a atividade a ser iniciada têm o modo de inicialização como padrão. Veja os detalhes abaixo:

Para atividade de hospedagem, configure a propriedade no history como false se houver

android:noHistory="false"

Para que a Atividade seja iniciada, defina o modo de inicialização como padrão, se houver

android:launchMode="standard"
jowett
fonte
13

Eu também estava enfrentando o mesmo problema quando transferi esse bloco de código para fora de um fragmento para uma classe de utilitário , com parentActivitypassado como argumento ,

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

Então, eu não estava obtendo nenhum valor no onActivityResultmétodo desse fragmento . Depois, mudei o argumento para Fragment , então a definição revisada do método parecia:

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

Depois disso, consegui valorizar onActivityResulto fragmento

Shamsul Arefin Sajib
fonte
10

Eu também encontrei esse problema em um fragmento. E eu liguei startActivityForResultpara a DialogFragment.

Mas agora esse problema foi resolvido:
FragmentClassname.this.startActivityForResult .

Courysky
fonte
Ótimo, funcionou para mim, porque eu estava ligando startActivityForResult(...)de uma classe abstrata dentro do código do fragmento.
Vince
9

PARA FRAGMENTOS NESTADOS (por exemplo, ao usar um ViewPager)

Na sua atividade principal:

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

No seu fragmento principal de nível superior (fragmento 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);
}

Em YourFragment (fragmento aninhado):

public void yourMethod(Intent data){
    // Do whatever you want with your data
}
Jyotman Singh
fonte
8

No meu caso, foi um bug do Android ( http://technet.weblineindia.com/mobile/onactivityresult-not-getting-called-in-nested-fragments-android/ ), se você usar o suporte, FragmentActivityprecisará usar em getSupportFragmentManagervez de getChildFragmentManager:

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

Em resumo,

Em fragmento, declare Fragment fragment = this;

após esse uso fragment.startActivityForResult.

O resultado retornará em activityResult.

Clevester
fonte
6

Solução 1:

Ligue em startActivityForResult(intent, REQUEST_CODE);vez degetActivity().startActivityForResult(intent, REQUEST_CODE); .

Solução 2:

Quando startActivityForResult(intent, REQUEST_CODE);é chamado, a atividade onActivityResult(requestCode,resultcode,intent)é invocada e você pode ligar a fragments onActivityResult()partir daqui, passando o requestCode, resultCode and intent.

Amey Haldankar
fonte
5

Dentro do seu fragmento, ligue

this.startActivityForResult(intent, REQUEST_CODE);

onde thisestá se referindo ao fragmento. Caso contrário, faça como o @Clevester disse:

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

Eu também tive que ligar

super.onActivityResult(requestCode, resultCode, data);

na atividade dos pais onActivityResultpara fazê-lo funcionar.

(Adaptei esta resposta da resposta de @ Clevester.)

Suragch
fonte
5

Para aqueles que usam Android componente de navegação deve usar na Actividade onActivityResult(...)do primaryNavigationFragmentconseguir é referência fragmento e chamada fragmento de fragment.onActivityResult(...).

Aqui está a atividade 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);
    }
}
Mohit Mehta
fonte
4

A maioria dessas respostas continua dizendo que você deve ligar super.onActivityResult(...)para o seu host ActivityparaFragment . Mas isso não parecia estar funcionando para mim.

Então, no seu host, Activityvocê deve ligar para o seu Fragments onActivityResult(...). Aqui está um exemplo.

public class HostActivity extends Activity {

    private MyFragment myFragment;

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

Em algum momento do seu processo, HostActivityvocê precisará atribuir this.myFragmento Fragmentque está usando. Ou use o FragmentManagerpara obter o em Fragmentvez de manter uma referência a ele no seu HostActivity. Além disso, verifique nullantes de tentar ligar para this.myFragment.onActivityResult(...);.

prolink007
fonte
3
public class takeimage extends Fragment {

    private Uri mImageCaptureUri;
    private static final int PICK_FROM_CAMERA = 1;
    private static final int PICK_FROM_FILE = 2;
    private String mPath;
    private ImageView mImageView;
    Bitmap bitmap = null;
    View view;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.activity_send_image, container, false);
        final String[] items = new String[] { "From Camera", "From SD Card" };
        mImageView = (ImageView)view.findViewById(R.id.iv_pic);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.select_dialog_item, items);
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Select Image");

        builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {
                if (item == 0) {
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    File file = new File(Environment.getExternalStorageDirectory(), "tmp_avatar_"
                        + String.valueOf(System.currentTimeMillis())
                        + ".jpg");
                    mImageCaptureUri = Uri.fromFile(file);

                    try {
                        intent.putExtra(
                            android.provider.MediaStore.EXTRA_OUTPUT,
                            mImageCaptureUri);
                        intent.putExtra("return-data", true);

                        getActivity().startActivityForResult(intent,
                            PICK_FROM_CAMERA);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    dialog.cancel();
                } else {
                    Intent intent = new Intent();

                    intent.setType("image/*");
                    intent.setAction(Intent.ACTION_GET_CONTENT);

                    getActivity().startActivityForResult(
                        Intent.createChooser(intent,
                            "Complete action using"), PICK_FROM_FILE);
                }
            }
        });
        final AlertDialog dialog = builder.create();

        Button show = (Button) view.findViewById(R.id.btn_choose);
        show.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // Switch the tab content to display the list view.
                dialog.show();
            }
        });

    return view;
    }

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

        if (resultCode != Activity.RESULT_OK)
            return;

        if (requestCode == PICK_FROM_FILE) {
            mImageCaptureUri = data.getData();
            // mPath = getRealPathFromURI(mImageCaptureUri); //from Gallery

            if (mPath == null)
                mPath = mImageCaptureUri.getPath(); // from File Manager

            if (mPath != null)
                bitmap = BitmapFactory.decodeFile(mPath);
        } else {
            mPath = mImageCaptureUri.getPath();
            bitmap = BitmapFactory.decodeFile(mPath);
        }
        mImageView.setImageBitmap(bitmap);  
    }

    public String getRealPathFromURI(Uri contentUri) {
        String [] proj = {MediaStore.Images.Media.DATA};
        Cursor cursor = managedQuery(contentUri, proj, null, null,null);

        if (cursor == null) return null;

        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
} 
shakirullah orakzai
fonte
3
  1. Você pode simplesmente substituir BaseActivity onActivityResultno fragmento baseActivity.startActivityForResult.

  2. Em BaseActivity, adicione interface e substitua 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. Em implementos de fragmento 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();
      }
    }

Esta solução alternativa fará o truque.

Khaled Lela
fonte
3

Se o problema acima for enfrentado no login do Facebook , você poderá usar o código abaixo em uma atividade pai do seu fragmento, como:

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

Ou:

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

E adicione a chamada abaixo no seu fragmento ...

callbackManager.onActivityResult(requestCode, resultCode, data);
Ketan Patel
fonte
2

Outro caso de uso ainda não descrito em outras respostas:

onActivityResult()declarado no fragmento não é chamado ao usar exception.startResolutionForResult():

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

Nesse caso, substitua exception.startResolutionForResult()pelo fragmento startIntentSenderForResult():

if (exception is ResolvableApiException) {
    startIntentSenderForResult(exception.resolution.intentSender, MY_REQUEST_CODE, null, 0, 0, 0, null)
}
dominik
fonte
2

Versão do Kotlin (Em sua atividade noActivityResult ())

 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)
    }
 }
Ranjith Kumar
fonte
1

Eu tenho uma forte suspeita de que todas as respostas aqui nada mais são do que hacks. Eu tentei todos eles e muitos outros, mas sem nenhuma conclusão confiável, pois sempre há algum tipo de problema estúpido. Eu, pelo menos não posso confiar em resultados inconsistentes. Se você consultar a documentação oficial da API do Android para Fragments, verá que o Google declara claramente o seguinte:

Chame startActivityForResult (Intent, int) do Activity que contém o fragmento.

Consulte: API de fragmentos do Android

Portanto, parece que a abordagem mais correta e confiável seria realmente chamar startActivityForResult () da atividade de hospedagem e também manipular o onActivityResult () resultante a partir daí.

Chris
fonte
2
Eu não acho que "chamar startActivityForResult from Activity" é uma recomendação. Se você olhar para a implementação dentro da classe base Fragmento, em seguida, tudo que faz é mActivity.startActivityFromFragment(this, intent, requestCode)- por isso nada mais é que um invólucro de conveniência
Anti Veeranna
1

Seu código possui um fragmento aninhado. Chamar super.onActivityForResult não funciona

Você não deseja modificar todas as atividades das quais seu fragmento pode ser chamado e / ou trabalhar para chamar cada fragmento na cadeia de fragmentos.

Aqui está uma das muitas soluções de trabalho. crie um fragmento rapidamente e conecte-o diretamente à atividade com o gerenciador de fragmentos de suporte. Em seguida, chame startActivityForResult a partir do fragmento recém-criado.

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();
}
danny117
fonte
Isso realmente funciona e eu só tenho um voto para isso. Crie um fragmento em tempo real. Muito fácil, mas sua verdadeira solução de trabalho. Alguém até tentou editá-lo para mim.
danny117
1

Meu problema foi com a atividade Host que encontrei com um conjunto android:launchMode="standard"que o removi temporariamente e funcionou!

Chulo
fonte
1

Um ponto que ninguém tem é mentionque verifique se o modo de inicialização da Atividade do Host não deve ser definido como singleInstanceou singleTask.

onActivityResult não funcionará se o seu modo de inicialização estiver definido como SingleInstance ou SingleTask. ou você chama sua atividade usando esses IntentFilters

standardou singleTopo modo de inicialização funcionará bem.

Jawad Zeb
fonte
1

Se você estiver usando fragmentos aninhados, isso também funcionará:

getParentFragment().startActivityForResult(intent, RequestCode);

Além disso, você deve chamar super.onActivityResultda atividade dos pais e preencher o onActivityResultmétodo do fragmento.

Oguz Ozcan
fonte
1

Eu lidei com o problema escrevendo uma classe base que se estende Fragmente, na onactivityresultatividade, identifiquei o fragmento em execução no momento usando o fragmenttag. Então eu chamo um método definido pelo usuário na classe fragmentbase. Isso disparará um evento no fragmento em execução no momento.

Bytecode
fonte