Невозможно создать внешний файл - EACCES (разрешение запрещено)
При попытке создать простой внешний файл.txt или.xml (НЕ на SD-карте) мое приложение выдает исключение FileNotFoundException. Если я позволю системе выбрать путь (возврат / хранилище / эмуляция / наследие), она выдаст EACCES (разрешение отклонено). То же, что и когда я вручную устанавливаю путь к "/android/data" (возвращает /storage/emulated/0/android/data) или "/download" (возвращает /storage/emulated/0/Download) - оба бросают EACCES. Если я устанавливаю путь к "/ document", он выдает ENOENT (такого файла или каталога нет).
Как показано ниже в моем коде, я делаю проверку прежде, чтобы убедиться, что внешнее хранилище доступно и не только для чтения.
Я запустил это на 2 устройствах под управлением 4.4.2 и 4.4.4. Я также добавил "android.permission.MOUNT_UNMOUNT_FILESYSTEMS" в манифест, как предложено в ответах SO, чтобы попытаться заставить устройство использовать собственную файловую систему, а не ПК, когда запуск приложения через USB, но, похоже, он продолжает давать мне путь, полученный из / emulated /. Я пытаюсь отладить само устройство с помощью параметров разработчика и, таким образом, исключаю возможность доступа приложения к хранилищу ПК, но отладчик на устройстве просто виснет, пытаясь прикрепить.
Конечно, у меня также есть: "android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"
Это очень расстраивает, так как есть несколько похожих вопросов по SO, но с очень приемлемыми ответами.
public static File getExternalStorageDirectory() {
Log.i("EXTERNAL STORAGE DIR", EXTERNAL_STORAGE_DIRECTORY.toString());
return EXTERNAL_STORAGE_DIRECTORY;
}
public static final File EXTERNAL_STORAGE_DIRECTORY = getDirectory("EXTERNAL_STORAGE", "android/data");
public static File getDirectory(String variableName, String defaultPath) {
String path = System.getenv(variableName);
return path == null ? new File(defaultPath) : new File(path);
}
public boolean isExternalStorageReadOnly() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
return true;
}
return false;
}
public boolean isExternalStorageAvailable() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
return true;
}
return false;
}
public void writeToSettingsFile(String name, String value){
// File myDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "/settings.txt");
// File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), fileUrl);
// File myDir = getDirectory("EXTERNAL_STORAGE", "android/data");
// File myDir = getExternalStorageDirectory();
// File myDir = new File("download");
File myDir = new File(Environment.getExternalStorageDirectory() + "/android/data");
if(!myDir.exists()){
myDir.mkdirs();
}
try{
String fname = "settings.txt";
File file = new File (myDir, fname);
FileOutputStream fOut = new FileOutputStream(file);
Toast.makeText(context, "you made it, fOut!!!!", Toast.LENGTH_LONG).show();
props.setProperty(name, value);
props.store(fOut, "Settings Properties");
// props.storeToXML(fOut, "Settings Properties");
fOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.e("WTF", "No file found!");
}
catch (IOException e) {e.printStackTrace();
}
}
2 ответа
Я думаю, что проблема в вашей этой линии
android:maxSdkVersion="18" .
Причина. Вы тестируете на 4.4.2. И это устройство имеет API-уровень 19.
Хорошо, это решение:
public void writeToSettingsFile(String name, String value){
// File myDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "/settings.txt");
// File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), fileUrl);
// File myDir = getDirectory("EXTERNAL_STORAGE", "android/data");
// File myDir = getExternalStorageDirectory();
// File myDir = new File("download");
File myDir = new File(this.getExternalFilesDir(null), name);
if(!myDir.exists()){
myDir.mkdirs();
}
try{
String fname = "settings.txt";
File file = new File (myDir, fname);
FileOutputStream fOut = new FileOutputStream(file);
fOut.write(value.getBytes());
// props.storeToXML(fOut, "Settings Properties");
fOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.e("WTF", "No file found!");
}
catch (IOException e) {e.printStackTrace();
}
}
Попробуйте этот метод. Проблема в том, что вы не можете получить внутренний каталог, как это
File myDir = new File(Environment.getExternalStorageDirectory() + "/android/data"); // You don't have the permission to do this
если вы хотите записать на внутреннюю память, вы можете получить такой каталог
File myDir = new File(this.getExternalFilesDir(null), name);
И вы можете посмотреть на Для получения дополнительной информации о сохранении файлов