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?

Dimanoïde
la source
le double possible de onActivityResult n'est pas appelé dans Fragment
PhoneixS

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);
Changwei Yao
la source
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)
Ashlesha Sharma
la source
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

    }
}
Jaime Agudo
la source
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);
Nilesh Tiwari
la source
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

TarikW
la source
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
            }
Exception de pointeur nul
la source