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?


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);

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)

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

    }
}

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);

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


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
            }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.