Разрешение EACCESS запрещено в Android

При записи файла на внешнюю SD-карту я получаю сообщение об ошибке разрешения EACCESS. Я установил разрешение <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> Но когда я прочитал файл, я успешно его прочитал, но не смог записать файл. Код, который я использую для записи файла на SD-карте:

 String path="mnt/extsd/Test"; try{ File myFile = new File(path, "Hello.txt"); //device.txt myFile.createNewFile(); FileOutputStream fOut = new FileOutputStream(myFile); OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut); myOutWriter.append(txtData.getText()); myOutWriter.close(); fOut.close(); Toast.makeText(getBaseContext(),"Done writing SD "+myFile.getPath(),Toast.LENGTH_SHORT).show(); } catch (Exception e) { Toast.makeText(getBaseContext(), e.getMessage(),Toast.LENGTH_SHORT).show(); System.out.println("Hello"+e.getMessage()); } } 

Путь для внешней карты памяти – mnt/extsd/ . Вот почему я не могу использовать Environment.getExternalStorageDirectory().getAbsolutePath() который дает мне путь mnt/sdcard и этот путь предназначен для внутреннего пути хранения в моем планшете. Пожалуйста, дайте понять, почему это так. Как я могу решить эту проблему?

Поскольку я помню, что Android получил частичную поддержку многопользовательской памяти, поскольку Honeycomb, а основное хранилище (то, которое вы получаете из Environment.getExternalStorageDirectory, обычно являющегося частью внутренней карты eMMC), по-прежнему защищено разрешением WRITE_EXTERNAL_STORAGE , но вторичные хранилища (например, Настоящая съемная SD-карта) защищены новым разрешением android.permission.WRITE_MEDIA_STORAGE , а уровень защиты – signatureOrSystem, см. Также обсуждение в этой статье .

Если это так, тогда обычное приложение кажется невозможным написать что-либо реальному SD-карте без сигнатуры платформы …

Начиная с API уровня 19, Google добавил API .

  • Context.getExternalFilesDirs()
  • Context.getExternalCacheDirs()
  • Context.getObbDirs()

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

Ниже приведен подход, чтобы получить конкретный каталог приложений на внешней SD-карте с абсолютными путями.

 Context _context = this.getApplicationContext(); File fileList2[] = _context.getExternalFilesDirs(Environment.DIRECTORY_DOWNLOADS); if(fileList2.length == 1) { Log.d(TAG, "external device is not mounted."); return; } else { Log.d(TAG, "external device is mounted."); File extFile = fileList2[1]; String absPath = extFile.getAbsolutePath(); Log.d(TAG, "external device download : "+absPath); appPath = absPath.split("Download")[0]; Log.d(TAG, "external device app path: "+appPath); File file = new File(appPath, "DemoFile.png"); try { // Very simple code to copy a picture from the application's // resource into the external file. Note that this code does // no error checking, and assumes the picture is small (does not // try to copy it in chunks). Note that if external storage is // not currently mounted this will silently fail. InputStream is = getResources().openRawResource(R.drawable.ic_launcher); Log.d(TAG, "file bytes : "+is.available()); OutputStream os = new FileOutputStream(file); byte[] data = new byte[is.available()]; is.read(data); os.write(data); is.close(); os.close(); } catch (IOException e) { // Unable to create file, likely because external storage is // not currently mounted. Log.d("ExternalStorage", "Error writing " + file, e); } } 

Выход журнала сверху выглядит следующим образом:

 context.getExternalFilesDirs() : /storage/extSdCard/Android/data/com.example.remote.services/files/Download external device is mounted. external device download : /storage/extSdCard/Android/data/com.example.remote.services/files/Download external device app path: /storage/extSdCard/Android/data/com.example.remote.services/files/ 

Я решил эту проблему, удалив android:maxSdkVersion="18" в android:maxSdkVersion="18" uses-permission в файле манифеста. Т.е. используйте это:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

вместо:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" /> 

Проверьте, имеет ли пользователь разрешение на внешнее хранилище или нет. Если нет, используйте кеш-диск для сохранения файла.

 final boolean extStoragePermission = ContextCompat.checkSelfPermission( context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; if (extStoragePermission && Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) { parentFile = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); } else{ parentFile = new File(context.getCacheDir(), Environment.DIRECTORY_PICTURES); }