RequestCode incorreto em onActivityResult

310

Estou iniciando uma nova atividade do meu fragmento com

startActivityForResult(intent, 1);

e deseja manipular o resultado na atividade pai do fragmento:

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

O problema é que nunca recebi o requestCodeque acabei de publicar startActivityForResult().

Eu tenho algo parecido 0x40001, 0x20001etc. com um conjunto de bits mais alto aleatório. Os documentos não dizem nada sobre isso. Alguma ideia?

Dimanóide
fonte
possível duplicata de onActivityResult não sendo chamado Fragmento
PhoneixS

Respostas:

837

Você está ligando startActivityForResult()do seu Fragment. Quando você faz isso, o requestCodeé alterado pelo Activityque possui o Fragment.

Se você deseja obter o correto resultCodeem sua atividade, tente o seguinte:

Mudança:

startActivityForResult(intent, 1);

Para:

getActivity().startActivityForResult(intent, 1);
Changwei Yao
fonte
44
Porque ele deve decidir para qual fragmento entregará o resultado. Então, quando o fragmento chamar StartActivityForResult. o requestCode será alterado pela Atividade, para saber como entregar o resultado para qual fragmento. se você realmente deseja obter o resultado na atividade. basta chamar getActivity (). startActivityForResult ().
Changwei Yao
31
Apenas uma observação: se você usar startActivityForResultem um fragmento e esperar o resultado onActivityResultnesse fragmento, certifique-se de chamar super.onActivityResulta atividade do host (caso substitua esse método). Isso ocorre porque a atividade onActivityResultparece chamar de fragmento onActivityResult. Além disso, observe que o código de solicitação, quando viaja pela atividade onActivityResult, é alterado conforme explicado no link que Dimanoid postou em sua resposta abaixo. Você pode não precisar de saber isso, mas nunca se sabe ...
Ferran Maylinch
31
"o requestCode é alterado pela atividade que possui o fragmento" - Preciso amar o design do Android ... #
224 Tiago Tiago
13
Informações tão importantes que você não consegue encontrar em nenhum lugar claro nos documentos. Tem que amar o design do Android projetado para tornar sua vida um inferno.
Driss Bounouar 21/03
2
Cara eu te amo, passei muitos dias tentando entender esse problema e corrigir o erro, obrigado!
tinyCoder
35

O código de solicitação não está errado. Ao usar os fragmentos da biblioteca de suporte v4, o índice do fragmento é codificado nos 16 bits superiores do código de solicitação e o código de solicitação está nos 16 bits inferiores. O índice do fragmento é usado posteriormente para encontrar o fragmento correto para fornecer o resultado.

Portanto, para o Activities iniciado o objeto de fragmento, manipule onActivityResult requestCode como abaixo:

originalRequestCode = changedRequestCode - (indexOfFragment << 16)
      6             =      196614        -       (3 << 16)
Ashlesha Sharma
fonte
1
Grande informação que explica a causa exata para esta questão
Muzikant
pergunta rápida: o que é indexOfFragment?
Louis Tsai
indexOfFragment é o índice que o getSupportFragmentManager () getFragments () produz.
HerberthObregon
25

Mais fácil:

Java : int unmaskedRequestCode = requestCode & 0x0000ffff

Kotlin : val unmaskedRequestCode = requestCode and 0x0000ffff

Verifique os 16 bits inferiores, apenas desmascara-o fazendo um AND lógico com os 16 bits superiores zerados

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

    final int unmaskedRequestCode = requestCode & 0x0000ffff

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

    }
}
Jaime Agudo
fonte
1
Você pode me dizer o motivo pelo qual ele não forneceu o código de solicitação original?
K.Sopheak
3
Causa que o requestCode é alterado pela atividade que possui o fragmento. Veja resposta de Ashlesha Sharma
Jaime Agudo
obrigado, esta é a resposta que eu estava procurando. Não vejo por que o Android não deve retornar o código de solicitação original.
tonisives 24/01
Hoje, isso foi imensamente útil para mim e, na verdade, explica muito bem o problema. Obrigado!
Billy Lazzaro
6

Se você estiver fornecendo constante, torne-o público e use-o em startActivityResult

exemplo:

public static final int REQUEST_CODE =1;
getActivity().startActivityForresult(intent, REQUEST_CODE);
Nilesh Tiwari
fonte
2

Você também pode definir
super.onActivityResult(requestCode, resultCode, data)
em Activity(se você substituir onActivityResult) neste

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

        ...

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

e chame startActivityForResult(intent, requestCode)dentro do seuFragment

TarikW
fonte
0

em fragmento

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

na Atividade Principal:

if (requestCode == PLACE_PICKER_REQUEST) {
            if (resultCode == RESULT_OK) {    
     //what ever you want to do
            }
Null Pointer Exception
fonte