在 Android 应用中重新启动后尝试打开文件夹时出现权限错误

Posted

技术标签:

【中文标题】在 Android 应用中重新启动后尝试打开文件夹时出现权限错误【英文标题】:Permission error when trying to open folder after restart in Android app 【发布时间】:2019-11-17 00:02:37 【问题描述】:

我的应用中有一个首选项页面,要求用户提供保存文件的位置。这个地方使用存储访问框架作为 URI 返回,我可以使用它在活动之间存储文件。问题是在我重启手机后,我从 sharedPreferences 中检索了 URI,然后我收到了这个:

DocumentFile: Failed query: java.lang.SecurityException: Permission Denial: opening provider com.android.externalstorage.ExternalStorageProvider from ProcessRecord (pid=23302, uid=10334) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs

这是启动意图的代码:

 folderPicker = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)        
 folderPicker.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
 startActivityForResult(folderPicker, READ_REQUEST_BY_USER)

和onActivityResult:

    val takeFlags: Int = folderPicker.flags and (Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
    activity!!.contentResolver!!.takePersistableUriPermission(uri, takeFlags)
    val sharedPref = PreferenceManager.getDefaultSharedPreferences(activity?.baseContext)
    with (sharedPref.edit()) 
    putString("savePathURI", uri.toString())
    commit()
    

这就是我尝试重新访问文件夹的方式:

var uri = PreferenceManager.getDefaultSharedPreferences(this).getString("savePathURI","")                
var getSelectedDocument = DocumentFile.fromTreeUri(applicationContext, Uri.parse(uri))!!
var params = BridgeParams(applicationContext, links, filesDir.absolutePath, button, getResources(), progressBar3, getSelectedDocument, contentResolver)

编辑:我注意到调用 contentResolver.persistedUriPermissions 总是返回一个空数组,即使我在之后调用它:

activity!!.contentResolver!!.takePersistableUriPermission(uri, takeFlags)

【问题讨论】:

【参考方案1】:

问题是我需要为ACTION_OPEN_DOCUMENT_TREE 添加额外的标志:

folderPicker = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)        
folderPicker.addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION
or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
or Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
or Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
)
startActivityForResult(folderPicker, READ_REQUEST_BY_USER)

【讨论】:

非常有趣的是,我的应用程序在不需要这样做的情况下长时间运行良好。【参考方案2】:

您需要拨打takePersistableUriPermissiononActivityResult

见:https://developer.android.com/reference/android/content/ContentResolver.html?authuser=1#takePersistableUriPermission(android.net.Uri,%2520int)

【讨论】:

我的代码中已经有了它。不过我想知道......它似乎永远不会被应用。调用 contentResolver.persistedUriPermissions 会返回一个空数组,即使我在 takePersistableUriPermission 之后立即调用它 标志是什么?? 哪些标志?该问题的所有代码均可用。

以上是关于在 Android 应用中重新启动后尝试打开文件夹时出现权限错误的主要内容,如果未能解决你的问题,请参考以下文章

Android:应用程序重新启动后,保存在 getFilesDir() 中的文件消失

关闭和重新打开应用程序后,Android 画布游戏循环中断 onResume()

如何避免两次启动 Android 应用程序,从 Eclipse 运行到真实设备

禁用启动器活动后,android重新安装失败

在应用程序被杀死并重新启动后,Android 应用程序黑暗主题消失了

关闭并重新打开应用程序时Android崩溃