web-dev-qa-db-fra.com

listFiles () renvoie null sur l'émulateur Android 6.0

Je veux lire les fichiers JPEG de sdcard sur l'émulateur Android 6.0, mais la liste de fichiers renvoie la valeur null. L'exemple de code peut fonctionner sur mon téléphone:

            String sdcard = Environment.getExternalStorageDirectory().toString();
            File sdcard_dir = new File(sdcard);
            if (sdcard_dir.isDirectory()) {
                File[] fileNames = sdcard_dir.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File pathname) {
                        return pathname.toString().endsWith(".jpg") ? true : false;
                    }
                });
            }

fileNames = null!

Je peux utiliser adb Shell pour répertorier les fichiers image sur l'émulateur:

 enter image description here

La permission a été ajoutée à AndroidManifest.xml:

<uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE" />

Tout ce que je peux faire?

Je dois utiliser l'émulateur car mon appareil ne peut pas encore être mis à niveau vers Android 6.0 et je souhaite tester de nouvelles API.

14
yushulx

Android 6.0 a introduit les autorisations d'exécution. En plus de déclarer l'autorisation sur votre manifeste, vous devez demander l'autorisation à l'utilisateur au moment de l'exécution.

Plus d'infos et tutoriels ici: http://developer.Android.com/training/permissions/requesting.html

10
1615903

J'ai observé exactement le même problème, même après avoir ajouté le code d'autorisations d'exécution requis avec Android 6.0.

Dans mon activité, j'ai le code suivant:

    int permissionCheck1 = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
    int permissionCheck2 = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (permissionCheck1 != PackageManager.PERMISSION_GRANTED || permissionCheck2 != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                             Manifest.permission.READ_EXTERNAL_STORAGE},
                REQUEST_READWRITE_STORAGE);
    }

et je reçois le rappel attendu lorsque l'utilisateur confirme la demande d'autorisation de stockage en lecture/écriture.

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String[] permissions,
                                       int[] grantResults) {
    if (requestCode == REQUEST_READWRITE_STORAGE) {
        if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
            finishCreationStep();
        }
    }
}

J'ai vérifié dans le débogueur que les autorisations de lecture et d'écriture ont été accordées. Pourtant, l'appel exécuté ultérieurement pour lire le stockage échoue:

File[] possible_files = mrpDir.listFiles();

L'appel à listFiles () renvoie null. Si je ferme l'application et que j'accède à Paramètres> Applications pour mon application, je constate que l'autorisation de stockage a été accordée. Si je ferme également l'application, puis le redémarre, les autorisations sont là, comme prévu, et les appels de listFiles () fonctionnent parfaitement. En d'autres termes, la modification des autorisations ne prend effet que lorsque l'application est arrêtée et redémarrée. Existe-t-il un moyen de faire en sorte que l'application reconnaisse les autorisations modifiées sans obliger l'utilisateur à fermer et à le redémarrer manuellement?

Comme avec l'auteur de ce fil, je cours avec un émulateur API 23, car je n'ai actuellement pas accès à un appareil Android 6. Donc, je suppose qu'il est possible qu'il y ait un problème avec l'émulateur. Mais cela semble peu probable.

10
loxodrome

Votre premier appel 

if (permissionCheck1 != PackageManager.PERMISSION_GRANTED || permissionCheck2 != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                         Manifest.permission.READ_EXTERNAL_STORAGE},
            REQUEST_READWRITE_STORAGE);
}

est de vérifier si vous avez la permission. Si vous n'en avez pas, l'autorisation, le rappel est appelé. C'est la première fois. 

Par la suite, le rappel n'est pas appelé puisque vous avez déjà l'autorisation. Donc, votre code devrait ressembler à

if (permissionCheck1 != PackageManager.PERMISSION_GRANTED || permissionCheck2 != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                         Manifest.permission.READ_EXTERNAL_STORAGE},
            REQUEST_READWRITE_STORAGE);
}
else
    finishCreationStep();
1
Ananth