Android: разрешение во время выполнения предоставлено для записи в хранилище, но по-прежнему отказано (например, onRequestPermissionsResult) - PullRequest
0 голосов
/ 01 декабря 2018

Я хочу записать изображение в устройство, используя публичное внешнее хранилище.Таким образом, я 1) написал в манифесте теги разрешений и 2) использовал checkSelfPermission для запроса разрешений при необходимости.Но у меня все еще есть это исключение: java.io.FileNotFoundException: /storage/emulated/03b3d97bd-5186-4506-97dc-9994b7ce0761 (Permission denied).

Почему?Я уже прочитал https://developer.android.com/guide/topics/permissions/overview#normal-dangerous, но он не отвечает на мой вопрос.

Формализация проблемы

Я предоставил разрешения на хранение на моем устройстве Android.Таким образом, мое условие if (permissionCheck != PackageManager.PERMISSION_GRANTED) { (см. Ниже) правильно НЕ выполнено, а else выполнено.И этот else содержит строку для сохранения файла в хранилище: однако он возвращает это исключение ...

Источники

Цель состоит в том, чтобы вызвать saveImageAndShareIt, если пользователь предоставилразрешение.

Манифест

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

Обычно чтение должно быть неявно распознано благодаря разрешению на запись.

В DialogFragment

Ниже,метод onRequestPermissionsResult.saveImageAndShareIt вызывается, если пользователь согласился предоставить разрешение.

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    System.out.println("onrequestPR");

    if (grantResults.length > 0) {
        if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            System.out.println("onrequestPR accepted");
            saveImageAndShareIt();
        }
    }
}

onRequestPermissionsResult вызывается requestPermissions, представленным ниже:

if (Build.VERSION.SDK_INT >= 23) {
    int permissionCheck = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
    } else {
        System.out.println("last_case1");
        saveImageAndShareIt();
        System.out.println("last_case2");
    }
} else {
    System.out.println("peperoni");
    saveImageAndShareIt();
    System.out.println("pizza");
}

То есть, если пользователь имеетуже предоставлено разрешение, нет необходимости вызывать requestPermissions и, таким образом, saveImageAndShareIt вызывается напрямую (другими словами: onRequestPermissionsResult не нужно выполнять для вызова saveImageAndShareIt).

saveImageAndShareIt

Исключение составляет экземпляр FileOutputStream.

private void saveImageAndShareIt() {
    OutputStream output;
    try {
        System.out.println("siasi1");
        output = new FileOutputStream(Environment.getExternalStorageDirectory() + image_uuid);
        byte[] buffer = new byte[1024];
        int bytesRead;
        BitmapDrawable bitmapDrawable = (BitmapDrawable) temp.getDrawable();
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmapDrawable.getBitmap().compress(Bitmap.CompressFormat.JPEG, 100, stream);
        byte[] imageInByte = stream.toByteArray();
        ByteArrayInputStream bis = new ByteArrayInputStream(imageInByte);
        while ((bytesRead = bis.read(buffer, 0, buffer.length)) >= 0) {
            output.write(buffer, 0, bytesRead);
        }
        output.close();
        System.out.println("siasi2");
        intent_share.putExtra(Intent.EXTRA_STREAM, Uri.parse(Environment.getExternalStorageDirectory() + image_uuid));
        activity.startActivity(Intent.createChooser(intent_share, "Share to"));
        System.out.println("siasi3");
    } catch(IOException e) {
        e.printStackTrace();
    }
}

Трассировка стека

W / System.err: java.io.FileNotFoundException: / storage / emulated / 03b3d97bd-5186-4506-97dc-9994b7ce0761 (в доступе отказано) W / System.err: в java.io.FileOutputStream.open0 (собственный метод) в java.io.FileOutputStream.opream (FileOutJutStut.utava.put): 287) W / System.err: в java.io.FileOutputStream. (FileOutputStream.java:223) W / System.err: в java.io.FileOutputStream. (FileOutputStream.java:110) в com.example ...ClipboardDialogFragment.saveImageAndShareIt (ClipboardDialogFragment.java:115) в com.example ... ClipboardDialogFragment.access $ 300 (ClipboardDialogFragment.java:42) W / System.err: в com.example ... ClipboardDialogFragment $ 1 $ 2 $ 1.onTaskCompleted (ClipboardDialogFragment.java:75) W / System.err: в com.example ...DownloadImageTask.onPostExecute (DownloadImageTask.java:34) на com.example ... DownloadImageTask.onPostExecute (DownloadImageTask.java:10) W / System.err: на android.os.AsyncTask.finish (AsyncTask.java:695) и на.os.AsyncTask.-wrap1 (неизвестный источник: 0) W / System.err: at android.os.AsyncTask $ InternalHandler.handleMessage (AsyncTask.java:712) W / System.err: at android.os.Handler.dispatchMessage(Handler.java:105) на android.os.Looper.loop (Looper.java:164) на android.app.ActivityThread.main (ActivityThread.java:6944) W / System.err: на java.lang.reflect.Method.invoke (собственный метод) в com.android.internal.os.Zygote $ MethodAndArgsCaller.run (Zygote.java:327) в com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1374)

1 Ответ

0 голосов
/ 01 декабря 2018

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

Вам необходимо использовать DocumentsProvider или получить еще одно разрешение / uri через StorageVolume ипроанализируйте его с помощью DocumentsContract ( пример проекта ).

Редактировать: в зависимости от вашего исключения:

 /storage/emulated/03b3d97bd-5186-4506-97dc-9994b7ce0761

Внешний каталог по умолчанию - /storage/emulated/0Похоже, вы забыли добавить разделитель после имени каталога:

output = new FileOutputStream(Environment.getExternalStorageDirectory() +"/"+ image_uuid);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...