0

大家晚上好。我已经坚持了几天。我有一个 android 应用程序,它允许您添加图像并将它们显示在便笺中。我刚刚将手机升级到 Android 10,新的 SAF 规则似乎让我陷入困境。以前在 android 10 之前,如果将图像移动到另一个文件夹,我不必再次请求该 URI 的权限,URI 没有更改,我将继续访问该图像。现在看来 URI 发生了变化,我必须请求新 URI 的权限。

此外,在将数据从旧手机传输到新手机时,我希望能够维护我保存的图像,并且不会丢失对这些数据的引用。

我现在在哪里:

我之前只是将内容 URI 存储在 Room 中。我相信我需要存储内容 URI 以及显示名称。然后我可以通过查询 MediaStore 来获取新的 Content URI。从那里我无法获得对我获得的新内容 URI 的权限。如果我在这个 URI 上请求 persistentPermissions,我只会得到一个“无权限异常”。我已请求 READ_EXTERNAL_STORAGE 并且可以获得我的应用程序可以访问的有效内容 Uri

是否有操作或者我可以在内容 URI 上请求这些权限?有没有办法使用 ACTION_OPEN_DOCUMENT 打开特定的内容 URI,以便用户可以再次选择文件并再次授予我权限?更好的是,有没有一种方法可以使用 ACTION_OPEN_DOCUMENT 从我提供的内容 URI 列表中打开图像列表,并允许用户再次授予所有这些图像的权限?

这是我用来尝试重新获得对已移动(或重新导入到新手机)contentUri 的访问权限的代码(使用现在只是硬编码的文件名)

ni.myList.iterator().forEach { it ->
    
    val notExist = application.contentResolver.getType(Uri.parse(it.fileUri)) == null

    if(notExist){

        val projection = arrayOf(
                MediaStore.Images.Media._ID, //TODO store the new content uri and ask permissions for the image.
        )

        val selection = "${MediaStore.Images.Media.DISPLAY_NAME} = ?"

        val selectionArgs = arrayOf("IMG_20201216_162211.jpg")

        val sortOrder = "${MediaStore.Images.Media._ID} DESC"

        var id = -1L

        getApplication<Application>().contentResolver.query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection,
                selection,
                selectionArgs,
                sortOrder
        )?.use { cursor ->
            if(cursor.moveToFirst()){
                id = cursor.getLong(0)
            }
        }

        if(id != -1L){
            val newContentUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)
            it.fileUri = newContentUri.toString()
            
     //application.contentResolver.takePersistableUriPermission(Uri.parse(newContentUri.toString()), Intent.FLAG_GRANT_READ_URI_PERMISSION)
     //Above just throws Exception

            val intent = Intent().apply{
                putExtra(Intent.EXTRA_MIME_TYPES, arrayListOf("image/*"))
                data = Uri.parse(newContentUri.toString())
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) //This just opens it in image display app. No option to grant permissions
            }
            
            
/* This just opens Picker without the intended file
            val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply{
                putExtra(Intent.EXTRA_MIME_TYPES, arrayListOf("image/*"))
                data = Uri.parse(newContentUri.toString())
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
            }                               
*/                      

            mMainActivityHelper.startActivityForResult(intent, 10110)
        }
    }
    
}
4

1 回答 1

0

跟进这个。android的版本有太多的场景和差异。我能够真正拥有图像并且不会丢失它的唯一方法是在应用程序本地存储中制作它的副本。这是一个很大的失望,因为它不必要地增加了我的应用程序的大小,但是 id 相当大的应用程序大小然后是很多缺陷或解释如何工作

于 2021-01-08T02:56:35.000 回答