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

标签 android storage-access-framework

我使用 Android 存储访问框架来访问 SD 卡上的一些文件。保留此权限对我来说很重要,以便能够在设备重启后编辑文件。

所以根据Storage Access Framework documentation我使用 Persist 权限,让用户可以通过您的应用继续访问文件,即使设备已重新启动也是如此。

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

目前,在这种情况下,我正在显示文档选择器,以便用户可以再次向我提供新权限,但要求用户执行相同的操作通常对用户来说并不友好。

什么会导致权限被撤销?我怎样才能防止这种撤销?

我已经在我的所有设备上测试了多次重启手机、更改时间、移除插入的 SD 卡,但没有丢失任何 saf 权限。

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

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 的文档和 FLAG_GRANT_PREFIX_URI_PERMISSION

关于android - 存储访问框架持久权限不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32563428/

相关文章:

android - ListView、CustomBaseAdapter 中的静态 header

Android - 对新添加的 ImageView 和 TextView 设置约束

java - 在不使用 findFiles() 的情况下获取作为文档树子项的 DocumentFile

android - 7 个线程/runnable 是不是太多了?是什么让我的应用程序变慢了?

android - android中的onSensorChanged在模拟器中不断被触发

android - 在Android中授予应用程序权限时是否有可能获得回调

android - 将 EXIF 数据写入使用 DocumentFile 类保存的图像

java - 如何在 android API 19 (KitKat) 中保留权限?

Android:使用存储访问框架获得的 URI 中的 Intent 选择器打开文件

android - 有没有办法选择一个 zip 文件以使用存储访问框架打开?