Java.io.filenotfoundexception открыть сбой eacces (разрешен отказ) на устройстве

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

java.io.filenotfoundexception открыть не удалось eacces (разрешение отклонено)

public void downloadFile(String dlUrl, String dlName) {
    int count;

    HttpURLConnection con = null;
    InputStream is = null;
    FileOutputStream fos = null;

    try {
        URL url = new URL( dlUrl );
        con = (HttpURLConnection) url.openConnection();
        con.setDoInput(true);
        con.connect();

        is = url.openStream();
        String dir = Environment.getExternalStorageDirectory() + Util.DL_DIRECTORY;
        File file = new File( dir );
        if( !file.exists() ){
            file.mkdir();
        }

        Util.LOG_W(TAG, "Downloading: " + dlName + " ...");

        fos = new FileOutputStream(file + "/" +  dlName);
        byte data[] = new byte[1024];

        while( (count = is.read(data)) != -1 ){
            fos.write(data, 0, count);
        }

        Util.LOG_D(TAG, dlName + " Download Complete!");


    } catch (Exception e) {
        Util.LOG_E(TAG, "DOWNLOAD ERROR = " + e.toString() );
        bServiceDownloading = false;
    }
    finally{
        try {
            if( is != null)
                is.close();
            if( fos != null)
                fos.close();
            if( con != null)
                con.disconnect();
        } catch (Exception e) {
            Util.LOG_E(TAG, "CLOSE ERROR = " + e.toString() );
        }
    }
}

И в файле манифеста у меня есть следующее:

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

Любые предложения, что может быть причиной? Кстати Environment.getExternalStorageDirectory() возвращает /mnt/sdcard/, а file.mkdir() возвращает false.

Ответы

Ответ 1

Эта проблема, кажется, вызвана несколькими факторами.

Проверка # 1
Сначала добавьте это разрешение в ваш файл манифеста и проверьте, работает ли он:

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

</application>

.....

Проверка № 2:

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

Проверка # 3:

Отключить передачу файлов с устройства на компьютер. Если включено, приложение не сможет получить доступ к SD-карте.

Проверка # 4:
Если все еще не работает, попробуйте следующее:

 String dir = Environment.getExternalStorageDirectory().getAbsolutePath()

Для меня сработало следующее:
Проблема в том, что getExternalStorageDirectory возвращает /mnt/sdcard, тогда как мне нужен фактический путь к внешнему хранилищу, который является /mnt/sdcard-ext, и в Android нет API, который мог бы получить абсолютный путь к съемной SD-карте.
Моим решением было жестко закодировать каталог следующим образом:

String dir = "/mnt/sdcard-ext" ;

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

Ответ 2

Использовать разрешение READ_EXTERNAL_STORAGE для чтения данных с устройства.

Ответ 3

Вы пробовали его на эмуляторе? Проверьте свойства, если у него есть SD-карта. У меня была такая же проблема, и это было потому, что у эмулятора не было SD-карты. Проверьте, есть ли у вас или нет.

Ответ 4

У меня была та же проблема, и я решил ее, отключив передачу файлов с устройства на компьютер. Поскольку, если u разрешает передачу файлов, SD-карта недоступна для отладки приложения.

Ответ 5

try
Environment.getExternalStorageDirectory().getAbsolutePath()

и не забудьте добавить

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

Ответ 6

Я подозреваю, что вы используете Android 6.0 Marshmallow (API 23) или более поздней версии. Если это так, вы должны внедрить разрешения во время выполнения, прежде чем пытаться читать/записывать внешнее хранилище. https://developer.android.com/training/permissions/requesting.html

Ответ 7

Попробуйте использовать mkdirs вместо mkdir. Если вы создаете путь к каталогу, а родительский язык не существует, вы должны использовать mkdirs.

Ответ 8

У меня была та же проблема. Я правильно использовал права на запись и чтение в манифесте, но это не сработало! Решение было очень глупым: отключите телефон от ПК перед запуском приложения. Кажется, что когда ваш телефон подключен как "Массовое хранилище" к ПК, приложение не может получить доступ к внешнему хранилищу.

Ответ 9

Я сделал очень глупую ошибку. Я уже положил в AndroidManifest.xml

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

а также добавить разрешение в файл Java, так как получить разрешение прагматично. Но есть ошибка Manifest.permission.READ_EXTERNAL_STORAGE. Пожалуйста, используйте Manifest.permission.WRITE_EXTERNAL_STORAGE.

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, requestCode);

Ответ 10

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