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?
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é.
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.
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;
}
}