Доступ запрещен при использовании Uri, полученного из OnActivityResult с использованием библиотеки Glide - PullRequest
1 голос
/ 10 января 2020

Я уже объявил READ_EXTERNAL_STORAGE в манифесте Android с использованием тега метки-полномочий и использования-разрешения-sdk-23. Я также запросил у пользователя разрешения READ_EXTERNAL_STORAGE. Я также использовал флаг FLAG_GRANT_READ_URI_PERMISSION.

Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
            photoPickerIntent.setType("image/*");
            photoPickerIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            if (photoPickerIntent.resolveActivity(getPackageManager()) != null) {
                startActivityForResult(photoPickerIntent, REQUEST_IMAGE_GALLERY);
            }

Вот как я запрашиваю фотографию у пользователя для получения в onActivityResult. Я также использую библиотеку glide для получения фотографии от пользователя.

requestMgr.load(new File(uri.getPath())).into(imageView);

Это то, что написано после того, как я проверил, является ли намерение, которое я получаю от onActivityResult, нулевым.

 if(intent != null){
     Uri uri = intent.getData();
     requestMgr.load(new File(uri.getPath())).into(imageView);
 } else {
     displayImageStorageErrorMessage();
     loadProfileImage();
} 

loadProfileImage () - это просто запасной вариант на случай, если что-нибудь произойдет, когда я попытаюсь загрузить изображение. Glide.with () записывается до проверки намерения, потому что я также использую его для того, когда пользователь хочет взять себя ie.

Однако imageView не отображает изображение, которое было выбрано пользователь. В результате, после того, как я присоединяю запросник к Glide, получается следующее:

java.io.FileNotFoundException: open failed: EACCES (Permission denied)
        at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:315)
        at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:220)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1498)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1420)
        at com.bumptech.glide.load.data.AssetFileDescriptorLocalUriFetcher.loadResource(AssetFileDescriptorLocalUriFetcher.java:20)
        at com.bumptech.glide.load.data.AssetFileDescriptorLocalUriFetcher.loadResource(AssetFileDescriptorLocalUriFetcher.java:11)
        at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:44)
        at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
        at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
        at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
        at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
        at com.bumptech.glide.load.engine.SourceGenerator$1.onLoadFailed(SourceGenerator.java:83)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.startNextOrFail(MultiModelLoader.java:167)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.onLoadFailed(MultiModelLoader.java:154)
        at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:49)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
        at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
        at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
        at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
        at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
        at com.bumptech.glide.load.engine.SourceGenerator$1.onLoadFailed(SourceGenerator.java:83)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.startNextOrFail(MultiModelLoader.java:167)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.onLoadFailed(MultiModelLoader.java:154)
        at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:49)
        at com.bumptech.glide.load.model.MultiModelLoader$MultiFetcher.loadData(MultiModelLoader.java:100)
        at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
        at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
        at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
        at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)
        at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:393)

Есть ли что-то, чего мне не хватает в разрешениях, которые я еще не сделал?

1 Ответ

1 голос
/ 10 января 2020

Проблема № 1: ACTION_PICK не использует тип MIME

Проблема № 2: ACTION_PICK действительно использует Uri, указывающий коллекцию, из которой вы выбираете, и вы не предоставляете один

Проблема № 3: ACTION_PICK, скорее всего, вернет content Uri через onActivityResult(), а не что-то с путем к файловой системе

Проблема № 4: setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) бессмысленно поскольку вы не предоставляете content Uri другому приложению, не говоря уже о том, для которого у вас есть разрешение на чтение, которое вы можете предоставить

Для решения этих проблем замените свой первый фрагмент кода на что-то вроде:

        Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
        photoPickerIntent.setType("image/*");

        if (photoPickerIntent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(photoPickerIntent, REQUEST_IMAGE_GALLERY);
        }

Замените второй фрагмент кода на что-то вроде:

if(intent != null){
     Uri uri = intent.getData();
     requestMgr.load(uri).into(imageView);
 } else {
     displayImageStorageErrorMessage();
     loadProfileImage();
} 
...