无法概念化 Android 文件系统访问

Trouble Conceptualizing Android File System Access

我希望我的应用程序在启动时自动从文件加载数据,然后为用户显示该数据的摘要。我以为这很简单,但是...

我差一点就成功了,但发现将数据文件放在 Android Studio 提供的模拟 Android 上会很棘手。所以我将文件的基本版本作为资产放入包中。我的代码检查了该文件,如果未找到,则将文件从 assets 复制到 phone 存储。到目前为止一切顺利,但后来我意识到这并不能真正满足要求,因为用户无法自定义文件(通过另一个应用程序或将文件的新版本放在她 phone 上)。

我发现我需要使用 "external" 存储(这不是真正的外部存储,它只是共享/public 存储)。所以我使用 getExternalStoragePublicDirectory() 来访问 Documents 文件夹。在将资产文件复制到 Documents 文件夹的代码部分,当我尝试创建目标文件时得到 "java.io.IOException: No such file or directory"。

这真的让我很震惊,因为我在它之前使用了 mkdirs() 来确保文件夹存在并且我首先尝试创建文件。

在 S/O 上查了很多遍之后,看来我的问题可能是我没有在 Documents 文件夹中读取/写入的权限。所以这是我无法理解它应该如何工作的地方。

在我的 Activity 的 OnCreate() 中,我想从我的文件中加载数据。但我需要先检查权限。这肯定是第一次失败,因为用户之前从未授予我的应用程序此权限。

那么我需要请求权限。但这意味着我不能再在 OnCreate() 方法中加载我的数据,因为我将在回调方法 (onRequestPermissionsResult) 中异步获取用户的响应。

如果用户对我的请求说 'No',我需要确保应用正常退出。如果她说'Yes',那么……什么?此时我处于回调中,我的 OnCreate() 方法不再是 运行。我怎样才能重新设置我的 Activity?

如果我在回调方法中加载数据文件,那只适用于用户必须授予权限的初始情况。但在那之后,我的应用程序(很可能)不会失去许可,所以我的应用程序不需要请求它。在这种情况下永远不会执行回调。所以我的数据文件必须加载...在哪里?

但是所有这一切只有在用户 运行 Android 6.0 或更高版本时才会发生。如果它是 Android 的早期版本,那么我的应用程序可以在我的 Activity 的 OnCreate() 方法中加载数据。

哎呀……头好痛!

这一切应该如何运作?我不需要相关方法的 link。我需要一个概念模型 - 图表真的很有帮助!


解法如下:Permissions Conceptual Diagram

How can I get back to setting up my Activity?

将依赖文件 I/O 的 "setting up my Activity" 代码移至单独的方法。在 onCreate() 中,检查您是否有权限,如果有,请调用该方法来设置您的 activity。如果没有,请调用 requestPermissions()。在 onRequestPermissionsResult() 中,如果您现在拥有权限,请调用该方法来设置您的 activity。

参见 this sample app,它使用运行时权限从外部存储执行磁盘 I/O。权限处理逻辑隔离在 AbstractPermissionsActivity 中,让主要 activity class 处理真正的业务逻辑。

If it's an earlier version of Android, then my app can load the data in my Activity's OnCreate() method.

好吧,您应该在后台线程上执行此磁盘 I/O。您可以从 onCreate().

开始 I/O

如果您分别使用 ContextCompatActivityCompat 来检查和请求权限,您的代码将在旧设备上 "do the right thing",就像那些 class 那样版本检查。