3

我正在模拟器上测试我的应用程序。我有一个导出功能,可以在其中创建并写入外部存储下载目录中的文件。而且我还有一个导入功能,可以从外部存储的下载目录中读取文件。

来自Android 文档

如果设备运行 Android 5.1 或更低版本,或者您的应用的目标 SDK 为 22 或更低版本: 如果您在清单中列出危险权限,则用户必须在安装应用时授予该权限;如果他们不授予权限,则系统根本不会安装该应用程序。

如果设备运行 Android 6.0 或更高版本,并且您的应用的目标 SDK 为 23 或更高版本:应用必须在清单中列出权限,并且必须在应用运行时请求它需要的每个危险权限。用户可以授予或拒绝每个权限,即使用户拒绝权限请求,应用程序也可以继续以有限的功能运行。

我的模拟器在 Android 6.0 上运行,我的应用程序的目标 SDK 是 25,因此我还必须在应用程序运行时请求它需要的每个危险权限。我这样做是为了导出功能,一切正常。但是,当我实现导入功能时,我没有在运行时请求权限。奇怪的是,我仍然可以从外部存储的许可中读取数据,而无需在运行时请求和授予 READ_EXTERNAL_STORAGE。根据这个Android 文档,READ_EXTERNAL_STORAGE 是一个危险的权限。

为了验证,我确保在开始使用该功能之前禁用权限,并在完成后再次验证该权限仍未被授予。虽然我对这种行为感到满意,因为它在运行时无需我请求许可就可以工作,但根据文档,我不相信这种行为是预期的。这就是为什么我想知道是什么导致了这种情况,并在发布应用程序的任何更改之前找出问题所在。

这是我的清单的代码片段:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

我选择要读取的文件的代码片段:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.setType("text/*");
            startActivityForResult(intent, GET_FILE_RESULT_CODE);

我从上面的代码片段中读取文件的代码片段(exportFile 只是来自 onActivityResult 的 URI):

    BufferedReader br;
    try {
        br = new BufferedReader(new InputStreamReader(context.getContentResolver().openInputStream(exportFile)));
        String line;
        // Skip first header line
        br.readLine();
        while ((line = br.readLine()) != null) {...}

谢谢!

4

2 回答 2

2

这里有一个很好的解释,

READ_EXTERNAL_STORAGE

提供对外部存储的受保护读取访问。默认情况下,在 Android 4.1 中,所有应用程序仍然具有读取权限。这将在未来的版本中进行更改,以要求应用程序使用此权限明确请求读取访问权限。如果您的应用程序已经请求写入权限,它也会自动获得读取权限。有一个新的开发人员选项可以打开读取访问限制,以便开发人员根据 Android 未来的行为来测试他们的应用程序。

简而言之,READ_EXTERNAL_STORAGE仅在 Jelly Bean(16 级)中存在。因此,除非您使用的是 Jelly Bean 手机并设置开发人员选项“保护 USB 存储”,否则不会有问题。

于 2017-05-09T03:33:22.087 回答
0

要知道,Android Runtime Permissions是分组的,因为你已经在manifest中申请了WRITE_EXTERNAL_STORAGE权限,所以不需要再申请READ_EXTERNAL_STORAGE权限了。它们是同一个组。

于 2017-05-09T03:14:12.977 回答