web-dev-qa-db-fra.com

Demandez les autorisations d'exécution à partir de v4.Fragment et demandez à Callback d'aller à Fragment?

J'ai un problème étrange qui cause un conflit. Je devais passer à Fragments pour résoudre ce problème, mais il y a des bugs avec cela.

Mon problème initial: J'ai une configuration de tiroir de navigation avec v4 Fragments. Pour demander une autorisation dans l'un de mes fragments que j'appelle ActivityCompat.requestPermissions(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION, 1); L'invite s'affiche correctement, mais rien ne se produit lorsque j'accepte ou refuse l'autorisation. Le callback onRequestPermissionsResult() n'est jamais appelé. Au lieu de cela, il est appelé dans l'activité à laquelle mes fragments sont attachés. Inutile pour moi, j'ai besoin du rappel pour travailler dans le fragment.

Dans cet esprit, on m'a dit que je devais utiliser FragmentCompat, mais cela ne fonctionne qu'avec native Fragments (v13+). J'ai donc modifié le tiroir de navigation pour qu'il fonctionne à partir de Fragments natifs au lieu de Fragments de la bibliothèque de support v4. Cependant , parce que j'utilise AppCompatActivity, certaines choses ne fonctionnent pas, comme addToBackStack() et revenir à un fragment précédent.

En résumé, quelqu'un sait-il comment je peux utiliser le v4.Fragment tout en demandant la permission dans Fragment et obtenir le rappel pour qu'il soit dans Fragment? J'ai l'impression qu'il s'agit d'un bogue dans Android qui n'a pas été résolu, mais je ne suis pas à 100%. 

Faites-moi savoir si vous avez besoin de voir mon code, ce sont juste les méthodes standard dont vous avez besoin pour les autorisations d'exécution, je voudrais travailler avec des fragments v4 bien que cela ne fonctionne pas de ma compréhension.

55
RED_

Ce comportement semble être présent dans la classe de support de fragment v4 requestPermissions in Fragment . Les implémentations Activity/FragmentCompat existent pour les personnes souhaitant utiliser les classes natives avec la fonctionnalité étendue aux niveaux d'API entre 11 et 23.

18
NasaGeek

Ajouter ceci à l'activité parent fonctionne pour moi:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    List<Fragment> fragments = getSupportFragmentManager().getFragments();
    if (fragments != null) {
        for (Fragment fragment : fragments) {
            fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

Source: https://code.google.com/p/Android/issues/detail?id=189121#c5

66
Samuel Gaona

Si vous devez obtenir le permissionResult dans fragment v4, assurez-vous d'utiliser

Fragment.requestPermission(String[], int);

au lieu de 

AppCompat.requestPermission(Activity, String[], int)

Découvrez ceci réponse!

18
DoruChidean

Vous pouvez utiliser cette partie de code

requestPermissions(new String[]{Manifest.permission.GET_ACCOUNTS}, PERMISSION_REQUEST_CODE);
11
Abubakar

Récemment, j’ai été confronté à la même situation, lorsque j’avais besoin de vérifier une autorisation à l’intérieur du fragment de support et d’obtenir un rappel. 

J'ai pu utiliser ContextCompat à checkSelfPermission, puis comme @NasaGeek a appelé requestPermissions de Android.support.v4.app.Fragment pour demander l'autorisation, puis a été rappelé à onRequestPermissionsResult dans le fragment v4. 

J'espère que cela t'aides. 

Merci. 

7
Nitesh Mudireddy

Pour le moment, la solution la plus stable consiste à le faire à la main. Je l'ai moi-même résolu simplement en notifiant les fragments enfants des fragments parents.

if (fragment.getParentFragment() != null) {
                            Fragment parentFragment = fragment.getParentFragment();
                            try {
                                ChildFragmentPermissionRegistry registry = (ChildFragmentPermissionRegistry) parentFragment;
                                registry.registerPermissionListener((ChildFragmentPermissionCallback) fragment);
                                parentFragment.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
                            } catch (ClassCastException e) {
                                Log.e(PermissionVerifier.class.getSimpleName(), e.getMessage());
                            }
                        } else {
                            fragment.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_REQUEST_CODE);
                        }

Lorsque fragment parent implémente l'interface ChildFragmentPermissionRegistry et enregistre un fragment enfant,

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (callback != null) {
        callback.onRequestPermissionsResult(requestCode, permissions, grantResults);
        callback = null;
    }
}

et fragments d'enfants implémentent ChildFragmentPermissionCallback

et les interfaces ressemblent à ceci:

public interface ChildFragmentPermissionCallback {
    void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults);
}

public interface ChildFragmentPermissionRegistry {
    void registerPermissionListener(ChildFragmentPermissionCallback callback);
}
2

le fragment fonctionne bien. J'ai un problème avec un fragment imbriqué de v4.Fragment. L'autorisation est demandée, mais le rappel onRequestPermissionsResult () n'est jamais appelé dans un fragment imbriqué!

Numéro ouvert

2
android_dev

Je ne sais pas si c'est récemment corrigé par Google, mais je peux atteindre le résultat escompté sans faire d'astuces.

Le plus important est d’appeler super.onRequestPermissionsResult(requestCode, permissions, grantResults); dans l’activité pour qu’il transmette le résultat à fragment si cela est demandé à fragment.

Alors, ce que je fais c'est:

1) en fragment, demandez la permission en utilisant v4 fragment.requestPermissions(permissions, requestCode)

2) dans l'activité onRequestPermissionsResult de l'activité, doit appeler super.onRequestPermissionsResult(requestCode, permissions, grantResults);

3) dans onRequestPermissionsResult du fragment, écrivez le code que je veux gérer.

1
YunhaoLIU

Dans mon cas, j'ai demandé l'autorisation du fragment et je dois également obtenir la réponse par fragment.

Mais mon téléphone fonctionne sous Android 8.1

donc j'étais besoin d'ajouter une autre condition pour vérifier cette

alors finalement, il y a ma solution

private void doOnWazeButtonClick()
{
    int permissionStatus = PackageManager.PERMISSION_DENIED;

    if (getContext() != null)
    {
        permissionStatus = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION);
    }

    if (permissionStatus == PackageManager.PERMISSION_GRANTED)
    {
        showContentWaze();
    }
    else
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        {
            Objects.requireNonNull(getActivity()).requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION_ACCESS_FINE_LOCATION);
        }
        else
        {
            requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION_ACCESS_FINE_LOCATION);
        }
    }
}
0