1

При попытке создать простой .txt или .xml внешний файл (НЕ на SD-карте), мое приложение бросает FileNotFoundException. Если я позволю системе выбрать путь (возвращает/storage/emulated/legacy), он выбрасывает EACCES (разрешение отклонено). Точно так же, как когда я вручную установил путь к «/ android/data» (возвращает/storage/emulated/0/android/data) или «/ download» (возвращает/storage/emulated/0/Download) - оба запускают EACCES. Если я установил путь к «/ document», он выбрал ENOENT (нет такого файла или каталога).Невозможно создать внешний файл - EACCES (отклонено разрешение)

Как показано ниже в моем коде, я делаю чек перед тем, чтобы обеспечить доступность внешнего хранилища, а не только для чтения.

Я побежал это на 2 устройства, работает 4.4.2 и 4.4.4 Я также добавил «android.permission.MOUNT_UNMOUNT_FILESYSTEMS» в манифесте, как предложено в SO ответы, чтобы попытаться заставить устройство использовать его собственную файловой системы, а не ПК при запуске приложения через USB, но, похоже, он дает мне путь, полученный из/emulated/ . Я пытаюсь выполнить отладку с самого устройства с помощью параметров разработчика и, таким образом, исключая возможность доступа приложения к хранилищу ПК , но отладчик на устройстве просто зависает, пытаясь подключиться.

Конечно у меня есть, а также: «android.permission.WRITE_EXTERNAL_STORAGE» андроид: 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(); 
      } 

      } 
+0

можете Что это реквизит? –

+0

'возвращает/хранит/эмулирует/0/android/data'. Это путаный путь. У каждого устройства уже есть '/ storage/emulated/0/Android/data', так почему вы хотите создать каталог с A, измененным на? Лучше посмотрите на getExternalFilesDir, если вы хотите использовать папку Android. – greenapps

+0

реквизит - это ссылка на класс java.util.Properties, который я установил ранее в коде. Это простой способ задать пары имя/значение и не имеет отношения к проблеме. Мне удалось записать свойства во внутренний файл, но мне нужен внешний файл, так как он должен быть доступен для чтения/записи из приложений-сестра. – galaxigirl

ответ

0

Я думаю, что проблема в вашей этой линии

android:maxSdkVersion="18" . 

Причина тестируют на 4.4.2. И это устройство имеет уровень апи 19.

+0

Спасибо за ваш комментарий, но я добавил эту строку как «на всякий случай», так как начиная с 4.4 «эти разрешения не требуются, если вы читаете или записываете только файлы, которые являются приватными для вашего приложения». Запись IOW во внешнее хранилище является родной для 4.4 и далее. Я удалю эту строку, хотя, поскольку мне в конечном итоге понадобится другое приложение-сестра, чтобы иметь возможность писать в файл. – galaxigirl

0

Хорошо это решение:

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); 

А вы посмотрите на For more information about saving files

+0

getExternalFilesDir(), конечно, предоставляет путь к внешнему хранилищу. getFilesDir() предназначен для внутреннего хранилища. Его все в названии. – greenapps

+0

Нет, если вы вызываете 'Environment.getExternalStorageDirectory()', который возвращает внешнее хранилище, но если вы вызываете 'Context.this.getExternalFilesDir (null)' Контекст здесь - это ваш контекст приложения, который возвращает внутреннее хранилище, а не внешнее, и оно будет 'storage/emulated/0/Android/data/ваш пакет приложений/файлы/имя файла' –

+0

И .. Это внешнее хранилище. Опять же: внешний - в имени функции./data/data/package - внутреннее хранилище. – greenapps

Смежные вопросы