Исключение «Не удалось открыть: EACCES (В доступе отказано)» на Android - PullRequest
230 голосов
/ 13 января 2012

Я получаю

Ошибка открытия: EACCES (Permission denied)

на линии OutputStream myOutput = new FileOutputStream(outFileName);

Я проверил рут и попробовал android.permission.WRITE_EXTERNAL_STORAGE.

Как я могу исправить эту проблему?

try {
    InputStream myInput;

    myInput = getAssets().open("XXX.db");

    // Path to the just created empty db
    String outFileName = "/data/data/XX/databases/"
            + "XXX.db";

    // Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    // Transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }

    // Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();
    buffer = null;
    outFileName = null;
}
catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}

Ответы [ 26 ]

312 голосов
/ 23 октября 2015

Для 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" />

Для получения официальной документации о запросе разрешений для API 23+, проверьте https://developer.android.com/training/permissions/requesting.html

226 голосов
/ 28 марта 2012

У меня была такая же проблема ... <uses-permission был не в том месте.Это правильно:

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

Тег uses-permission должен находиться вне тега application.

57 голосов
/ 17 января 2013

Я наблюдал это один раз при запуске приложения внутри эмулятора. В настройках эмулятора необходимо правильно указать размер внешнего хранилища («SD-карта»). По умолчанию поле «внешнее хранилище» пустое, и это, вероятно, означает, что такого устройства нет, и EACCES выбрасывается, даже если в манифесте предоставлены разрешения.

50 голосов
/ 19 ноября 2012

В дополнение ко всем ответам, убедитесь, что вы не используете свой телефон в качестве USB-накопителя.

У меня была такая же проблема в HTC Sensation при включенном режиме USB-накопителя.Я все еще могу отлаживать / запускать приложение, но не могу сохранить на внешнее хранилище.

28 голосов
/ 27 октября 2016

Моя проблема связана с «TargetApi (23)», который необходим, если ваш minSdkVersion ниже 23.

Итак, у меня есть запрос на разрешение со следующим фрагментом

protected boolean shouldAskPermissions() {
    return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}

@TargetApi(23)
protected void askPermissions() {
    String[] permissions = {
            "android.permission.READ_EXTERNAL_STORAGE",
            "android.permission.WRITE_EXTERNAL_STORAGE"
    };
    int requestCode = 200;
    requestPermissions(permissions, requestCode);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
// ...
    if (shouldAskPermissions()) {
        askPermissions();
    }
}
14 голосов
/ 08 февраля 2018

Я испытываю то же самое. Я обнаружил, что если вы перейдете в Настройки -> Диспетчер приложений -> Ваше приложение -> Разрешения -> Включить хранилище , это решит проблему.

13 голосов
/ 14 октября 2015

У меня была такая же проблема на Samsung Galaxy Note 3, под управлением CM 12.1. Проблема для меня заключалась в том, что у меня было

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

и пришлось использовать его, чтобы снимать и хранить пользовательские фотографии. Когда я попытался загрузить те же самые фотографии в ImageLoader, я получил ошибку (Permission denied). Решением было явное добавление

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

, поскольку вышеуказанное разрешение ограничивает разрешение на запись только API-версией 18, а вместе с ним разрешение на чтение.

13 голосов
/ 26 ноября 2012

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

Поэтому мне пришлось отключить USB-соединение, и все работало нормально.

9 голосов
/ 07 апреля 2016

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

Трюк: Если вы ориентируетесь на версию 22 или ниже, ваше приложение будет запрашивать все разрешения во время установки так же, как и на любом устройстве под управлением ОС ниже Marshmallow. Если вы пытаетесь использовать эмулятор, то начиная с Android 6.0 и далее вам нужно явно перейти в настройки-> приложения-> YOURAPP -> разрешения и изменить разрешение, если вы его дали.

6 голосов
/ 19 июля 2014

У меня была такая же проблема, и ни одно из предложений не помогло. Но я нашел интересную причину для этого на физическом устройстве Galaxy Tab .

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

...