存储访问框架持久权限不起作用

Ros*_*hak 8 android storage-access-framework

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

因此,根据Storage Access Framework文档,我使用Persist权限,即使设备已重新启动,也可以通过您的应用程序继续访问文件.

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

目前,在这种情况下,我正在显示文档选择器,因此用户可以再次为我提供新的权限,但要求用户执行相同的操作通常不是用户友好的.

什么可以导致撤销权限?我怎么能防止这种撤销?

我已经在我的所有设备上测试了多次手机重启,更换时间,删除插入SD卡,但无法丢失任何安全权限.

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

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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

Pet*_*ran 5

请求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);
}
Run Code Online (Sandbox Code Playgroud)

查看FLAG_GRANT_PERSISTABLE_URI_PERMISSIONFLAG_GRANT_PREFIX_URI_PERMISSION 的文档