有了Scoped Storage,getExternalStoragePublicDirectory
已被弃用,Android文档显示
此方法在API 29级中已弃用。为了提高用户隐私,不赞成直接访问共享/外部存储设备。当应用程序以Build.VERSION_CODES.Q为目标时,从此方法返回的路径将不再可供应用程序直接访问。应用程序可以通过迁移到Context#getExternalFilesDir(String(、MediaStore或Intent#ACTION_OPEN_DOCUMENT等替代方案来继续访问存储在共享/外部存储上的内容。
但是setDestinationInExternalPublicDir
并不被弃用。目前,我正在使用downloadManager
下载pdf,并将其保存在以Downloads目录为根目录的文件夹中(通过将dir作为directory_Downloads传递到setDestinationInExternalPublicDir
(。然后,我使用不推荐使用的getExternalStoragePublicDirectory()
方法创建了一个FILE
对象,并激发了所有适当应用程序处理PDF查看的意图。
我的问题是,当我将requestLegacyExternalStorage
标志保持为true时,它可以正常工作(我的目标sdk是29(。然而,当我省略它时,它有时工作得很好,但其他时候PDF查看器会打开文件,然后立即关闭它。我试图在应用程序中读取文件,看看出了什么问题,但我得到了拒绝访问的异常。这是有道理的,因为对于作用域存储,getExternalStoragePublicDirectory()
返回不可访问的路径。但是,这种间歇性的方法怎么会像其他时候一样运作良好呢?
更重要的是,我不明白为什么我设置的requestLegacyExternalStorage
标志会有任何效果。我所做的只是使用DownloadManager
中不推荐使用的setDestinationInExternalPublicDir
方法将pdf保存到Download
目录中的子文件夹中。然后我创建一个FILE(是的,我知道通过一个不推荐使用的getExternalStoragePublicDirectory
,它可能不可访问-但我不在乎,因为我没有访问它(,从中获取uri并激发意图-因此,行为不应该仅仅取决于pdf查看器应用程序是否可以访问旧文件夹(也就是说,如果它们在API<=28或29上,requestLegacyExternalStorage
设置为true(?-这只是为了理解这个概念,当然我需要处理它并将其存储在某个可访问的位置。
这就引出了我的最后一个问题。为了处理这个问题,我可以选择使用MediaStore.Downloads
,它也可以在下载目录下下载文件。我还能用DownloadManager
在那个位置下载吗。Android文档说,即使scoped storage
激发意图并授予其他应用程序权限,我们所需要做的就是授予这个权限:FLAG_GRANT_READ_URI_PERMISSION
(我已经在做了(。那么,这是否意味着所有路径都可以通过这种方式访问意向接收应用程序?如果不是,那么如果下载目录中的MediaStore.Downloads
存储,并且其他应用程序可以通过SAF
访问它,那么它是否不应该通过意向激发来访问?如果是,为什么我当前的实现间歇性失败。
任何线索都将不胜感激。谢谢
然后,我使用不推荐使用的getExternalStoragePublicDirectory((方法创建一个FILE对象,并激发所有适当应用程序处理PDF查看的意图。
这不是我们要走的路。
相反,您应该为ACTION_DOWNLOAD_COMPLETE注册一个广播接收器。
在onReceive((中,您可以获得下载文件的uri。
将该uri与授予读取权限标志一起用于您的意图ACTION_VIEW。