web-dev-qa-db-fra.com

Android: échec de la création du répertoire

J'utilise "Environment.getExternalStorage()" pour stocker et gérer des fichiers. Et il n'y a pas de message d'avertissement de logcat avec cette méthode et fonctionne très bien.

Mais, mon projet doit utiliser la méthode "Context.getExternalFilesDir(String type)" et un message d'avertissement s'affiche.

ContextImpl: Impossible d’assurer le répertoire:/storage/external_SD/Android/data/(nom du package)/files

Heureusement, cet objet File fonctionne bien (lire ou écrire ou créer un dossier fonctionne également). 

Mais je veux savoir comment résoudre ce message d'avertissement. Est-ce que quelque chose me manque?

14
iroiroys

Vous devriez savoir comment le message d'avertissement apparaît.

La getExternalFilesDir(String type) appellera getExternalFilesDirs(String type) (notez le «s» à la fin du nom de la deuxième méthode).

La getExternalFilesDirs(String type) trouvera tous les répertoires du type et appellera ensureDirsExistOrFilter() à la fin pour s'assurer que les répertoires existent.

Si le répertoire ne peut pas être atteint, il affichera un avertissement!

Log.w(TAG, "Failed to ensure directory: " + dir);
dir = null;

Donc, si votre appareil a deux chemins sdcard, il produira deux dirs. Si l'un d'entre eux n'est pas disponible, l'avertissement apparaîtra.

La conclusion est que l'avertissement n'a pas besoin d'être corrigé.

9
Hongji Song

Si vous avez du code qui itère des fichiers, appelant cette API plusieurs fois, cet avertissement peut entraîner une pollution des journaux. Pour résoudre ce problème (puisque l'avertissement est réellement bénin), vous pouvez créer une classe wrapper qui stocke le résultat de l'appel de getExternalFilesDir/getExternalCacheDir et renvoie ensuite la valeur stockée au lieu d'appeler l'API. De cette façon, au moins vous ne verrez ce message qu’une seule fois.

1
Mr. Bungle

Je suis la source getExternalFilesDir ()

/**
 * Ensure that given directories exist, trying to create them if missing. If
 * unable to create, they are filtered by replacing with {@code null}.
 */
private File[] ensureExternalDirsExistOrFilter(File[] dirs) {
    File[] result = new File[dirs.length];
    for (int i = 0; i < dirs.length; i++) {
        File dir = dirs[i];
        if (!dir.exists()) {
            if (!dir.mkdirs()) {
                // recheck existence in case of cross-process race
                if (!dir.exists()) {
                    // Failing to mkdir() may be okay, since we might not have
                    // enough permissions; ask vold to create on our behalf.
                    final IMountService mount = IMountService.Stub.asInterface(
                            ServiceManager.getService("mount"));
                    try {
                        final int res = mount.mkdirs(getPackageName(), dir.getAbsolutePath());
                        if (res != 0) {
                            Log.w(TAG, "Failed to ensure " + dir + ": " + res);
                            dir = null;
                        }
                    } catch (Exception e) {
                        Log.w(TAG, "Failed to ensure " + dir + ": " + e);
                        dir = null;
                    }
                }
            }
        }
        result[i] = dir;
    }
    return result;
}


utilisation immédiate Environment.getExternalStorageDirectory () get ExternalDirs

public final class StorageUtil {

public static final String DIR_Android = "Android";
private static final String DIR_DATA = "data";
private static final String DIR_FILES = "files";
private static final String DIR_CACHE = "cache";

@Nullable
public static synchronized File getExternalStorageAppFilesFile(Context context, String fileName) {
    if (context == null) return null;
    if (fileName == null) return null;
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        File dirs = buildExternalStorageAppFilesDirs(Environment.getExternalStorageDirectory().getAbsolutePath(), context.getPackageName());
        return new File(dirs, fileName);
    }
    return null;
}


public synchronized static File buildExternalStorageAppFilesDirs(String externalStoragePath, String packageName) {
    return buildPath(externalStoragePath, DIR_Android, DIR_DATA, packageName, DIR_FILES);
}


public synchronized static File buildPath(String base, String... segments) {
    File cur = new File(base);
    for (String segment : segments) {
        cur = new File(cur, segment);
    }
    return cur;
}

}

0
任非凡