Mauvais requestCode dans onActivityResult


310

Je commence une nouvelle activité à partir de mon fragment avec

startActivityForResult(intent, 1);

et souhaitez gérer le résultat dans l'activité parent du fragment:

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

Le problème est que je n'ai jamais eu le message que requestCodeje viens de publier startActivityForResult().

J'ai obtenu quelque chose comme 0x40001, 0x20001etc. avec un ensemble de bits supérieur aléatoire. Les documents ne disent rien à ce sujet. Des idées?


Réponses:


837

Vous appelez startActivityForResult()depuis votre Fragment. Lorsque vous effectuez cette opération, le requestCodeest modifié par le Activitypropriétaire du Fragment.

Si vous voulez obtenir le bon résultat resultCodedans votre activité, essayez ceci:

Changement:

startActivityForResult(intent, 1);

À:

getActivity().startActivityForResult(intent, 1);

44
Parce qu'il doit décider à quel fragment il fournira le résultat. Ainsi, lorsque le fragment appelle StartActivityForResult. le requestCode sera modifié par l'activité, il saura donc comment livrer le résultat à quel fragment. si vous voulez vraiment obtenir le résultat dans l'Activiy. il suffit d'appeler getActivity (). startActivityForResult ().
Changwei Yao

31
Juste une note: si vous utilisez startActivityForResultdans un fragment et attendez le résultat de onActivityResultce fragment, assurez-vous simplement d'appeler super.onActivityResultl'activité hôte (au cas où vous surchargeriez cette méthode là). C'est parce que l'activité onActivityResultsemble appeler celle du fragment onActivityResult. Notez également que le code de demande, lorsqu'il parcourt l'activité onActivityResult, est modifié comme expliqué dans le lien que Dimanoid a publié dans sa réponse ci-dessous. Vous pourriez ne pas avoir besoin de savoir cela mais vous ne savez jamais ...
Ferran Maylinch

31
"le requestCode est changé par l'Activité qui possède le Fragment" - Faut aimer le design Android ...
Tiago

13
Une information si importante, que vous ne pouvez trouver nulle part dans les documents. Je dois aimer le design Android conçu pour faire de votre vie un enfer.
Driss Bounouar

2
Mec je t'aime, j'ai passé plusieurs jours à essayer de comprendre ce problème et de corriger l'erreur, merci!
tinyCoder

35

Le code de demande n'est pas faux. Lorsque vous utilisez des fragments de bibliothèque de prise en charge v4, l'index des fragments est codé dans les 16 premiers bits du code de demande et votre code de demande est dans les 16 derniers bits. L'index de fragment est ensuite utilisé pour trouver le fragment correct pour fournir le résultat.

Par conséquent, pour les activités ayant commencé l'objet fragment de formulaire, gérez onActivityResult requestCode comme ci-dessous:

originalRequestCode = changedRequestCode - (indexOfFragment << 16)
      6             =      196614        -       (3 << 16)

1
Grande info qui explique la cause exacte de ce problème
Muzikant

question rapide: qu'est-ce que indexOfFragment?
Louis Tsai

indexOfFragment est l'index produit par getSupportFragmentManager (). getFragments ()
HerberthObregon

25

Plus facile:

Java : int unmaskedRequestCode = requestCode & 0x0000ffff

Kotlin : val unmaskedRequestCode = requestCode and 0x0000ffff

Vérifiez les 16 bits inférieurs, démasquez-le simplement en faisant un ET logique avec les 16 bits supérieurs mis à zéro

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

    final int unmaskedRequestCode = requestCode & 0x0000ffff

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

    }
}

1
Pouvez-vous me dire pourquoi il ne donne pas le code de demande d'origine?
K.Sopheak

3
Parce que le requestCode est modifié par l'activité qui possède le fragment. Voir la réponse d'Ashlesha Sharma
Jaime Agudo

merci, c'est la réponse que je cherchais. Je ne vois pas pourquoi Android ne devrait pas renvoyer le code de demande d'origine.
toniques

Cela m'a été extrêmement utile aujourd'hui et explique vraiment très bien le problème. Merci!
Billy Lazzaro

6

Si vous fournissez constant rendez-le public, puis utilisez-le dans startActivityResult

exemple:

public static final int REQUEST_CODE =1;
getActivity().startActivityForresult(intent, REQUEST_CODE);

2

Vous pouvez également définir
super.onActivityResult(requestCode, resultCode, data)
dans Activity(si vous remplacez onActivityResult) à ce

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

        ...

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

et appeler à l' startActivityForResult(intent, requestCode)intérieur de votreFragment


0

en Fragment

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

dans l'activité principale:

if (requestCode == PLACE_PICKER_REQUEST) {
            if (resultCode == RESULT_OK) {    
     //what ever you want to do
            }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.