【问题标题】:Marshmallow upgrade issue (external SD card)Marshmallow 升级问题(外置 SD 卡)
【发布时间】:2016-02-10 17:49:00
【问题描述】:

我已根据本论坛其他地方的指南更新了我的应用,以使用 Android 6.0 权限模型访问外部 SD 卡。虽然从新安装应用程序时应用程序/权限工作正常,但如果我从以前的版本(依赖于 AndroidManifest.xml 中设置的权限)升级应用程序,应用程序将被拒绝访问 SD 卡 - 我需要卸载现有的版本并重新安装它以重新获得访问权限。

谁能解释为什么当我替换已安装的应用版本时,此应用更新会“破坏”外部 SD 卡权限?

我使用的代码(在我的 MainActivity 的 onCreate 方法中)是:

if (Build.VERSION.SDK_INT >= 23) {
    // For Marshmallow devices check permissions for accessing External SD card
    if (Build.VERSION.SDK_INT >= 23) {
        if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            logger.info("Permission is granted");
            return;
        } else {

            logger.info("Permission is revoked");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            return;
        }
    }
    else { //permission is automatically granted on sdk<23 upon installation
        logger.info("Permission is granted");
        return;
    }
}

编辑: 当应用程序从 Lollipop 设备上的先前版本升级时,此代码返回“InvalidSourceFolder”:

File f = new File("/storage/external_SD/DCIM/Camera");
File file[] = f.listFiles();
//If file is null then the source folder isn't valid
if (file == null) {
    return "InvalidSourceFolder";
}

【问题讨论】:

  • 我应该补充一点,这是指在运行 Android 5.* (Lollipop) 的手机上升级应用程序
  • “应用程序被拒绝访问 SD 卡”——首先,您在此处显示的代码与 removable storage 无关。它适用于external storage。第二,你为什么要检查Build.VERSION.SDK_INT &gt;= 23两次?第三,您没有向我们显示任何文件访问代码,也没有显示您在访问外部存储之前如何确认您拥有权限,因此我们不知道“被拒绝访问”是什么意思。
  • “SD 卡”是指外部 SD 卡。对 SDK 23 的仔细检查是一个错字 - 道歉。 “拒绝访问”是指下面的代码返回“InvalidSourceFolder”
  • “我的意思是外置SD卡”——WRITE_EXTERNAL_STORAGE与“外置SD卡”无关,也就是removable storage
  • 您的评论似乎与此处给出的建议不一致:stackoverflow.com/questions/32629792/…

标签: android android-sdcard android-6.0-marshmallow android-permissions


【解决方案1】:

读取/写入外部 SD 卡需要获得什么权限?

从 Android 4.4 开始,您通常无法“读取/写入外部 SD 卡”。

欢迎您在Context 上使用getExternalFilesDirs()getExternalCacheDirs()getExternalMediaDirs()(注意复数形式)。 如果设备支持removable storage,那么从这些方法返回的路径的第二个和后续条目将位于removable storage(您称之为“外部 SD 卡”)上。使用这些目录不需要任何权限。

除此之外,您无法直接访问可移动存储的文件系统。主要的例外是搭载早期版本 Android(例如 Android 4.3)并升级到 Android 4.4(或更高版本)的设备。次要例外是未合法随 Play 商店提供的设备。作为兼容性测试的一部分,搭载 Android 4.4+ 且合法拥有 Play 商店的设备无法提供对可移动媒体的直接文件系统访问。

请注意,我们也欢迎您使用存储访问框架(例如,ACTION_OPEN_DOCUMENT)。这允许用户选择放置文件的位置,并且不仅支持可移动存储,还支持云存储服务(例如,Google Drive、Dropbox)。但是,您只使用来自ContentResolver 的流,而不是文件。

【讨论】:

  • 到目前为止,该应用已经能够在Android 4.3、4.4和5.1上从外部SD卡中读取文件夹和文件。它一直在使用以“/ storage”为前缀的文件路径(如上面的示例)来执行此操作。在这样做时,我想我一直在利用一种解决方法。我不明白的是,为什么通过安装包含上述 Android 6.0 代码的应用程序更新(即 /storage... 位置不返回任何文件)来“破坏”这种方法,而如果我卸载以前的应用程序版本和安装新版本(使用 v6.0 代码)它工作正常。希望这是有道理的?
  • @user1175461:“这样做我想我一直在利用一种解决方法”——您使用的设备可能符合我引用的两个例外之一。 “我不明白的......” - 您必须询问您的设备制造商或自定义 ROM 作者为什么会发生更改。您将在大多数配备 Play Store 的 Android 4.4+ 设备上体验到您的最终状态(无直接文件系统访问权限)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-14
相关资源
最近更新 更多