Невозможно записать образ на SD-карту Android (отказано в доступе)

Я получаю следующую ошибку, когда пытаюсь записать в файл:

java.io.FileNotFoundException: /storage/extSdCard/DCIM/Camera/20160314_231954.jpg: ошибка открытия: EACCES (отказано в доступе)

Код, который я использую для его написания, таков:

//  The correctURIString was obtained earlier, in my example here, it is:
//  /storage/extSdCard/DCIM/Camera/20160314_231954.jpg
file = new File(correctURIString);
out1 = new FileOutputStream(file);
//The b is a Bitmap that I was creating (rotating 90 Degrees)
b.compress(Bitmap.CompressFormat.JPEG, 90, out1);

Прежде всего, позвольте мне рассказать вам, что я сделал до сих пор:

Мой манифест IS включает запросы разрешений;

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

И они расположены сразу за тегом Application.

Я также пробовал все рекомендации в этих темах:

1) java.io.filenotfoundexception open failed eacces (разрешение отклонено) на устройстве

2) Отказано в доступе при записи на SD-карту

3) Исключение "не удалось открыть: EACCES (отказано в доступе)" на Android< /а>

4) Получение поворота из ExifInterface всегда возвращает 0

5) Исключение Android: java.io.IOException: open ошибка: EACCES (отказано в доступе)

Проблема здесь в том, что если я использую свою программу просмотра файлов (кстати, Astro File Manager), чтобы найти эту точную фотографию, ФАКТИЧЕСКОЕ местоположение будет указано как:

"3261-3265/DCIM/Camera/20160314_231954.jpg"

Что не соответствует тому, что я получаю от попыток получить абсолютные пути. Код, который я использую для получения абсолютного пути:

public String getAbsolutePath(Uri uri) {
    if(Build.VERSION.SDK_INT >= 19){
        String id = uri.getLastPathSegment();
        //Custom function here, just keeps the numbers (removes everything else)
        id = StringUtilities.keepNumbersOnly(id);
        final String[] imageColumns = {MediaStore.Images.Media.DATA };
        final String imageOrderBy = null;
        Uri tempUri = getUri();
        Cursor imageCursor = getActivity().getContentResolver().query(tempUri, imageColumns,
                MediaStore.Images.Media._ID + "=" + id, null, imageOrderBy);
        if (imageCursor.moveToFirst()) {
            return imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
        }else{
            return null;
        }
    }else{
        String[] projection = { MediaStore.MediaColumns.DATA };
        Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
        if (cursor != null) {
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } else
            return null;
    }
}

Этот абсолютный путь для этой конкретной фотографии возвращается как:

/storage/extSdCard/DCIM/Camera/20160314_231954.jpg

Как видите, это абсолютное местоположение не соответствует фактическому, следовательно, оно не работает. Я не уверен, как заставить это работать правильно.

Кто-нибудь знает, как правильно получить правильный абсолютный путь?

Спасибо за помощь всем.

-Сил

Изменить: это было помечено как дубликат со ссылкой на эту ссылку:

java.io.filenotfoundexception open failed eacces (отказано в доступе) на устройстве

Что уже обсуждалось в вопросе, где я указал, что безуспешно пробовал ответы там. (см. вопрос)

По состоянию на 2 марта 2017 г. это не было решено, но хотелось бы уточнить, что это не дубликат.


person PGMacDesign    schedule 16.03.2016    source источник
comment
На какой версии Android вы используете это? 6.0?   -  person Pztar    schedule 16.03.2016
comment
Являются ли ваши запросы разрешений в вашем манифесте вне тега приложения? Если нет, как спрашивает/намекает @Pztar, если вы используете версию 6.0, вам нужно изучить явный запрос разрешения.   -  person zgc7009    schedule 16.03.2016
comment
Я запускаю это на Jelly Bean, у меня есть другой раздел приложения, обрабатывающий определенные запросы Marshmallow. А что касается расположения запросов разрешений в манифесте, как я упоминал в своем посте, они расположены сразу за тегом приложения.   -  person PGMacDesign    schedule 16.03.2016
comment
Я не думаю, что вы должны разделять их в зависимости от версии. Я думаю, что вам нужно обрабатывать разрешения для всех скомпилированных сборок API 23 одинаково. Могу ошибаться, не особо вникал. Кроме того, извините, я пропустил эту строку ранее, просто распространенная ошибка с разрешениями.   -  person zgc7009    schedule 16.03.2016
comment
Совершенно верно zgc, довольно распространенная ошибка. Что касается работы с Marshmallow, я сокращал рассказ, но если коротко, то я поленился и написал класс, который запускается при открытии приложения. Если пользователь отказывает в разрешениях, которые я запрашиваю, это не позволит им перейти в приложение, поэтому по своей природе они должны разрешить это к тому времени, когда они попадут в приложение.   -  person PGMacDesign    schedule 16.03.2016
comment
Правильно ли вы (1) читаете файл '/storage/extSdCard/DCIM/Camera/20160314_231954.jpg', (2) поворачиваете изображение и (3) когда вы записываете его обратно по тому же пути, вы получаете сообщение об ошибке ?   -  person k3b    schedule 16.03.2016
comment
Да K3B, точно правильно.   -  person PGMacDesign    schedule 16.03.2016
comment
@Silmarilos У меня такая же проблема, вы нашли решение этой проблемы?   -  person Ankesh kumar Jaisansaria    schedule 05.04.2016
comment
К сожалению, я так и не нашел решения. Лучшее, что я мог сделать, это сказать пользователю, что он не может использовать эту фотографию.   -  person PGMacDesign    schedule 05.04.2016