Storage Access Framework持久权限不起作用 [英] Storage Access Framework persist permissions not working

查看:120
本文介绍了Storage Access Framework持久权限不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Android Storage Access Framework访问SD卡上的某些文件.对我来说,保持此权限很重要,以便在设备重新启动后能够编辑文件.

I use Android Storage Access Framework to access some files on SD card. It is important for me to persists this permissions, to be able to edit files after reboot of device.

因此,根据存储访问框架文档,我使用了Persist权限,该权限授予用户即使设备已重新启动,仍然可以通过您的应用继续访问文件.

So according to Storage Access Framework documentation I use Persist permissions that gives the user continued access to the files through your app, even if the device has been restarted.

但是,一段时间后,我注意到某些用户的权限被撤销.因为当我尝试使用SAF进行书写时会得到android.system.ErrnoException: open failed: EACCES (Permission denied) 在该异常之后,我检查使用mContext.getContentResolver().getPersistedUriPermissions()的权限,但是返回空列表.我确定用户为我提供了正确的权限,并且该权限适用于当前安装的SD卡,因为我在数据库中跟踪了此操作.

However, after some time I noticed that for some users permissions were somehow revoked. Because when I am trying to use SAF for writing I get android.system.ErrnoException: open failed: EACCES (Permission denied) after that exception I check what permissions do I have using mContext.getContentResolver().getPersistedUriPermissions() however it return empty list. I am sure that user provide me with the right permissions and that permissions are for the currently installed Sd card, because I track this actions in the database.

当前,在这种情况下,我正在显示文档选择器,以便用户可以再给我一次新的权限,但是要求用户执行相同的操作通常对用户不友好.

Currently, in this case I am showing document picker so user can provide me one more time with new permissions, but asking user to perform same action often is not user friendly.

什么会导致撤销权限?以及我如何防止这种撤销?

What can cause the revoke of permissions? And how I can prevent this revoke?

我已经在所有设备上测试了手机的多次重启,更改时间,删除了插入sd卡的操作,但是并没有丢失任何安全保护权限.

I have tested on all my devices multiple reboots of the phone, changing time, removing inserting sd card, but was not able to lost any of saf permissions.

我有下一个用于获取权限的代码:

I have next code for obtaining permissions:

private void openDocumentTree() {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        startActivityForResult(intent, REQUEST_CODE);
    }

public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE) {
            Uri treeUri = data.getData();
            final int takeFlags = data.getFlags() & ( 
                    Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            mContext.getContentResolver().takePersistableUriPermission(treeUri,
                    takeFlags);

                    //this is my internal class for saving and restoring tree uri permissions.
                    final Permission permission = Permission.from(treeUri);
                    mPermissionDao.save(permission);
        }
    }

推荐答案

请求ACTION_OPEN_DOCUMENT_TREE时需要其他标志.

openDocumentTree应该看起来像

private void openDocumentTree() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
    intent.addFlags(
        Intent.FLAG_GRANT_READ_URI_PERMISSION
        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
        | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
        | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
    startActivityForResult(intent, REQUEST_CODE);
}

查看 FLAG_GRANT_PERSISTABLE_URI_PERMISSION 查看全文

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