异步任务期间未授予Android存储访问框架持久权限 [英] Android storage access framework persistable permission not granted during asyntask

查看:64
本文介绍了异步任务期间未授予Android存储访问框架持久权限的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里设置了意图标志:

I set the intent flags here:

public void createAlbum(View view) {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
    intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
    String intentChooserDialog = getResources().getString(R.string.pick_image_dialog);
    startActivityForResult(Intent.createChooser(intent, intentChooserDialog), PICK_IMAGE);
}

在我的活动结果中,我设置了持久权限,如下所述这里:

Here in my activity result I set the persistable permissions as they are explained here:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_IMAGE) {
        // Get image selection
        if (data != null) {
            ClipData clipData = data.getClipData();
            if (clipData != null) {
                int clipDataCount = clipData.getItemCount();
                if (clipDataCount > 1) {
                    int clipIndex = 0;
                    BitmapUri[] bitmapUris = new BitmapUri[clipDataCount];
                    while (clipIndex < clipDataCount) {
                        ClipData.Item item = clipData.getItemAt(clipIndex);
                        Uri uri = item.getUri();
                        int takeFlags = data.getFlags();
                        takeFlags &= Intent.FLAG_GRANT_READ_URI_PERMISSION;
                        getContentResolver().takePersistableUriPermission(uri, takeFlags);
                        BitmapUri bitmapUri = new BitmapUri(Uri.decode(uri.toString()),            data.getFlags());
                        bitmapUris[clipIndex] = bitmapUri;
                        clipIndex++;
                    }
                    DatabaseAlbumWriter dab = new DatabaseAlbumWriter(this);
                    dab.execute(bitmapUris);
                }
            } else {
                int oneImageSelected = 1;
                BitmapUri[] bitmapUris = new BitmapUri[oneImageSelected];
                Uri uri = data.getData();
                int takeFlags = data.getFlags();
                takeFlags &= Intent.FLAG_GRANT_READ_URI_PERMISSION;
                getContentResolver().takePersistableUriPermission(uri, takeFlags);
                BitmapUri bitmapUri = new BitmapUri(Uri.decode(uri.toString()), data.getFlags());
                bitmapUris[0] = bitmapUri;
                DatabaseAlbumWriter dab = new DatabaseAlbumWriter(this);
                dab.execute(bitmapUris[0]);
            }
        }
    }
}

将内容样式Uri保存到sqlite3数据库后,我想将它们加载到gridview中,但按照

After the content style Uri’s are saved to a sqlite3 database, I want to load them in a gridview, but asynchronously as described here. Here is my implementation of decodeSampledBitmapFromResource from the training guide. An object with a decoded String of the Uri and the persistable permission from the original intent are passed in. These values were saved in the database and loaded here again.

        protected Bitmap decodeSampledBitmapFromResource(BitmapUri bitmapUri, int reqWidth, int reqHeight) {
        Bitmap bitmap = null;
        Uri uri = Uri.parse(bitmapUri.getStringUri());
        int permissions = bitmapUri.getPermissions();
        permissions &= Intent.FLAG_GRANT_READ_URI_PERMISSION;
        try {
            getContentResolver().takePersistableUriPermission(uri, permissions);
            ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r");
            FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
            // First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            Rect rect = new Rect(-1,-1,-1,-1);
            BitmapFactory.decodeFileDescriptor(fileDescriptor, rect, options);
            // Calculate inSampleSize
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
            // Decode bitmap with inSampleSize set
            options.inJustDecodeBounds = false;
            bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor, rect, options);
            parcelFileDescriptor.close();
        } catch (NullPointerException | SecurityException | IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }
}

在这里我得到这个错误:

It is here that I get this error:

05-08 14:17:40.850 2728-2813/com.example.app W/System.err: java.lang.SecurityException: No persistable permission grants found for UID 10058 and Uri 0 @ content://com.android.providers.media.documents/document/image:32
05-08 14:17:40.850 2728-2813/com.example.app W/System.err:     at android.os.Parcel.readException(Parcel.java:1599)
05-08 14:17:40.850 2728-2813/com.example.app W/System.err:     at android.os.Parcel.readException(Parcel.java:1552)
05-08 14:17:40.850 2728-2813/com.example.app W/System.err:     at android.app.ActivityManagerProxy.takePersistableUriPermission(ActivityManagerNative.java:4217)
05-08 14:17:40.850 2728-2813/com.example.app W/System.err:     at android.content.ContentResolver.takePersistableUriPermission(ContentResolver.java:1703)
05-08 14:17:40.850 2728-2813/com.example.app W/System.err:     at com.example.app.AlbumCreator$BitmapWorkerTask.decodeSampledBitmapFromResource(AlbumCreator.java:395)
05-08 14:17:40.850 2728-2813/com.example.app W/System.err:     at com.example.app.AlbumCreator$BitmapWorkerTask.doInBackground(AlbumCreator.java:343)
05-08 14:17:40.850 2728-2813/com.example.app W/System.err:     at com.example.app.AlbumCreator$BitmapWorkerTask.doInBackground(AlbumCreator.java:329)

如果在活动结果中从具有BitmapFactory.decodeFileDescriptor的parcelFileDescriptor加载位图,则不会出现此错误.因此,据我所知,AsyncTask是具有不同特权的其他用户.有人知道如何为AsyncTask分配持久权限吗?我宁愿不在UI线程上加载位图.

If I load the bitmap from a parcelFileDescriptor with BitmapFactory.decodeFileDescriptor in the activity result I do not get this error. So, from what I can tell, the AsyncTask is a different user with different privileges. Anyone know how to assign persistable permissions to an AsyncTask? I’d rather not load bitmaps on the UI thread.

这是我的清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app">
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".AlbumCreator"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!--
             ATTENTION: This was auto-generated to add Google Play services to your project for
             App Indexing.  See https://g.co/AppIndexing/AndroidStudio for more information.
        -->
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <activity
            android:name=".AlbumEditor"
            android:label="@string/title_activity_album_editor"
            android:parentActivityName=".AlbumCreator">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.example.app.AlbumCreator" />
        </activity>
    </application>
</manifest>

推荐答案

我解决了自己的问题.如果查看我的代码,可以看到我使用了intent.getData().然后我坚持那个uri的许可.当我保存uri供以后使用时,我对其进行了解码. Uri.decode(uri.toString().

I solved my own problem. If you look at my code you can see that I used intent.getData(). Then I persisted the permission with that uri. When I saved the uri for later use I decoded it. Uri.decode(uri.toString().

已编码的Uri:content://com.android.providers.media.documents/document/image%3A32 解码:content://com.android.providers.media.documents/document/image:32

Encoded Uri: content://com.android.providers.media.documents/document/image%3A32 Decoded: content://com.android.providers.media.documents/document/image:32

因此,我改为使用intent.getDataString(),然后使用Uri.parse()为takePersistableUriPermission()方法创建一个Uri.然后,我从意图中将初始数据字符串保存在数据库中,以保留编码后的组件.

So, I instead used intent.getDataString(), then used Uri.parse() to create a Uri for the takePersistableUriPermission() method. Then I saved the initial data string from the intent in the database which keeps the encoded components.

这篇关于异步任务期间未授予Android存储访问框架持久权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆