Невозможно создать внешний файл - 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);

И вы можете посмотреть на Для получения дополнительной информации о сохранении файлов

Другие вопросы по тегам