Open failed: EACCES (разрешение отклонено)

У меня очень странная проблема с доступом к хранилищу на некоторых устройствах. Приложение работает на моих тестовых устройствах (Nexus 4 и 7, Samsung GS5). Все мои устройства под управлением Android 4.4.2. Но я получил много писем от пользователей, говорящих, что приложение не может писать в хранилище (ни внутреннее хранилище, ни SD-карта). Из файла журнала, полученного от отзывов пользователей, я вижу, что проблема заключается в следующем коде:

try { if (fStream == null) { fStream = new FileOutputStream(filename, true); } fStream.write(data, 0, bytes); return; } catch (IOException ex) { ex.printStackTrace(); } 

Он выдает исключение в строке fStream = new FileOutputStream (имя файла, true); При создании FileOutputStream.

Журнал стека:

 W/System.err( 8147): Caused by: java.io.FileNotFoundException: /storage/emulated/0/my_folder/test_file_name.png: open failed: EACCES (Permission denied) w/System.err( 8147): at libcore.io.IoBridge.open(IoBridge.java:409) W/System.err( 8147): at java.io.FileOutputStream.<init>(FileOutputStream.java:88) W/System.err( 8147): at java.io.FileOutputStream.<init>(FileOutputStream.java:128) W/System.err( 8147): at myapp.save(SourceFile:515) W/System.err( 8147): ... 8 more W/System.err( 8147): Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied) W/System.err( 8147): at libcore.io.Posix.open(Native Method) W/System.err( 8147): at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110) W/System.err( 8147): at libcore.io.IoBridge.open(IoBridge.java:393) W/System.err( 8147): ... 11 more 

В AndroidManifest.xml я объявляю следующие разрешения:

  <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

Я подтвердил, что пользователи используют правильное приложение на SD-карте. И что более странно, так это то, что он не может писать и на внутреннее хранилище. Как это может произойти, если у меня есть права на чтение и запись? Пользователи говорят, что они не подключают свои устройства к ПК в это время.

Обновить

Оказывается, я слишком часто вызываю open и close FileOutputStream, что в какой-то момент бросает FileNotFoundException. Звучит скорее как проблема с потоками.

Я столкнулся с подобной проблемой некоторое время назад.

Ваша проблема может быть в двух разных областях. Это либо то, как вы создаете файл для записи, либо ваш метод письма может быть испорчен тем, что он зависит от телефона.

Если вы пишете файл в определенном месте на SD-карте, попробуйте использовать переменные среды. Они должны всегда указывать на допустимое местоположение. Ниже приведен пример записи в папку для загрузки:

 java.io.File xmlFile = new java.io.File(Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/Filename.xml"); 

Если вы пишете файл во внутреннем хранилище приложения. Попробуйте этот пример:

 java.io.File xmlFile = new java.io.File((getActivity() .getApplicationContext().getFileStreamPath("FileName.xml") .getPath())); 

Лично я полагаюсь на внешние библиотеки для обработки потоковой передачи в файл. Это еще не подвело меня.

 org.apache.commons.io.FileUtils.copyInputStreamToFile(is, file); 

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

Еще одно замечание: если файлы большие, вы также можете захотеть запустить IO в фоновом режиме или использовать обратные вызовы.

Для API 23+ вам необходимо запросить разрешения на чтение и запись, даже если они уже находятся в вашем манифесте.

 // Storage Permissions private static final int REQUEST_EXTERNAL_STORAGE = 1; private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; /** * Checks if the app has permission to write to device storage * * If the app does not has permission then the user will be prompted to grant permissions * * @param activity */ public static void verifyStoragePermissions(Activity activity) { // Check if we have write permission int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { // We don't have permission so prompt the user ActivityCompat.requestPermissions( activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE ); } } 

AndroidManifest.xml

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

В моем случае у меня был неправильный случай в

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

android.permission должен быть строчным, и как-никак вся строка была в верхнем регистре в нашем источнике.

Я также столкнулся с той же проблемой. После тяжелой работы я обнаружил, что было не так в моем случае. Мое устройство было подключено к компьютеру через USB-кабель. Существуют типы подключений USB, таких как Mass Storage, Media Device (MTP), Camera (PTP) и т. Д. Моим типом подключения было «Mass Storage», и это вызывало проблемы. Когда я изменил тип подключения, проблема была решена.

Всегда помните при доступе к файловой системе на устройстве Android: –

НЕ ПОДКЛЮЧИТЕ КАК МАСШТАБНОЕ ХРАНЕНИЕ к компьютеру / ПК.

В моем случае я использовал опцию android:isolatedProcess="true" для service в AndroidManifest.xml .

Как только я удалил его, ошибка исчезла …

Сначала дайте или проверьте разрешения, например

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

Если эти два разрешения в порядке, то проверьте, что выходные потоки находятся в правильном формате.

Пример:

 FileOutputStream fos=new FileOutputStream(Environment.getExternalStorageDirectory()+"/rahul1.jpg"); 

Я столкнулся с той же проблемой и обнаружил, что я должен запрашивать разрешения во время выполнения, даже если я объявил это в манифесте. Как сказано в ответе Джастина Фидлера.

Официальная документация по этому вопросу находится здесь: https://developer.android.com/training/permissions/requesting.html

Моя реализация немного отличается от ответа Джастина Фидлера о том, что он также реализует метод onRequestPermissionsResult фрагмента v4 для обработки запроса запроса разрешений.

 public static final int REQUEST_EXTERNAL_PERMISSION_CODE = 666; @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) public static final String[] PERMISSIONS_EXTERNAL_STORAGE = { READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE }; public boolean checkExternalStoragePermission(Activity activity) { if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) { return true; } int readStoragePermissionState = ContextCompat.checkSelfPermission(activity, READ_EXTERNAL_STORAGE); int writeStoragePermissionState = ContextCompat.checkSelfPermission(activity, WRITE_EXTERNAL_STORAGE); boolean externalStoragePermissionGranted = readStoragePermissionState == PackageManager.PERMISSION_GRANTED && writeStoragePermissionState == PackageManager.PERMISSION_GRANTED; if (!externalStoragePermissionGranted) { requestPermissions(PERMISSIONS_EXTERNAL_STORAGE, REQUEST_EXTERNAL_PERMISSION_CODE); } return externalStoragePermissionGranted; } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (requestCode == REQUEST_EXTERNAL_PERMISSION_CODE) { if (checkExternalStoragePermission(getActivity())) { // Continue with your action after permission request succeed } } } } 

Также я нашел решение для своего пути.

Перед запуском приложения я предоставил root файловому проводнику и не отключил разрешение на запись / чтение при выходе из приложения.

Мое приложение не может использовать внешнюю память, в то время как я заблокировал устройство для сброса всех разрешений.

Если клиенты используют Android 6.0, Android добавила новую модель разрешения для (Marshmallow).

Trick: Если вы ориентируетесь на версию 22 или ниже, ваше приложение будет запрашивать все разрешения во время установки так же, как и на любом устройстве, работающем под ОС ниже Marshmallow

В моем случае это были проблемы с разрешениями. Уловка заключается в том, что на устройстве с Android 4.0.4 я получил доступ к файлу без какой-либо ошибки или исключения. А на устройстве с Android 5.1 он вышел из строя с исключением ACCESS (open failed: EACCES (Permission denied)). Обработала его, добавив следующие действия для манифеста файла:

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

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

В моем случае проблема заключалась в том, что конфигурация WIFI, статическая, имела конфликт с другим устройством, использующим тот же IP-адрес.

У меня такая же проблема, но иногда, самый проблемный вопрос дает простой ответ.

Я перепроверяю явные разрешения, и там WAS_NOT пишут мне стыд за позор !!!