Android: не удалось установить каталог
Я использовал "Environment.getExternalStorage()
" для хранения и управления файлами. И с этим методом нет предупреждающего сообщения от logcat
и работает очень хорошо.
Но мой проект должен использовать метод "Context.getExternalFilesDir(String type)
", и есть предупреждающее сообщение
ContextImpl: Не удалось обеспечить каталог:/storage/external_SD/Android/data/(имя пакета)/файлы
К счастью, файл File работает нормально (чтение или запись или создание папки тоже работает).
Но я хочу знать, как разрешить это предупреждение. Я что-то пропустил?
Ответы
Ответ 1
Вы должны знать, как появляется предупреждающее сообщение.
getExternalFilesDir(String type)
вызовет getExternalFilesDirs(String type)
(обратите внимание на 's' в конце второго имени метода).
getExternalFilesDirs(String type)
найдет все типы этого типа и вызовет ensureDirsExistOrFilter()
в конце, чтобы гарантировать существование каталогов.
Если каталог недоступен, он выведет предупреждение!
Log.w(TAG, "Failed to ensure directory: " + dir);
dir = null;
Итак, если ваше устройство имеет два пути sdcard, оно будет создавать два каталога. Если он недоступен, появится предупреждение.
Вывод заключается в том, что предупреждение не нужно исправлять.
Ответ 2
Если у вас есть код, который выполняет итерацию файлов, вызывая этот API много раз, это предупреждение может вызвать загрязнение журналов. Чтобы решить эту проблему (поскольку предупреждение действительно доброкачественное), вы можете создать класс-оболочку, который сохраняет результат вызова getExternalFilesDir/getExternalCacheDir и впоследствии возвращает сохраненное значение вместо вызова API. Таким образом, по крайней мере, вы только когда-нибудь увидите это сообщение.
Ответ 3
Я следую за источником 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;
}
немедленное использование Environment.getExternalStorageDirectory() получить 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;
}
}