【问题标题】:mkdirs returns false for directory on sd card while the parent directory is writable当父目录可写时,mkdirs 为 sd 卡上的目录返回 false
【发布时间】:2011-05-03 00:27:09
【问题描述】:

在启动我的android应用程序时,我需要在sd卡上创建一个目录,对于少数用户这会失败,我无法弄清楚它的原因......

(我发现了由于缺少 WRITE_EXTERNAL_STORAGE 权限而导致的类似问题,它存在并且几乎适用于所有用户,所以我认为这不是原因)

我已经简化了前面的情况以便更容易解释,如果创建目录失败,我会运行一个测试用例,尝试在 sdcard 上创建一个 .test 目录:

new File(Environment.getExternalStorageDirectory(), ".test").mkdir() -> false
new File(Environment.getExternalStorageDirectory(), ".test").mkdirs() -> false

相关目录的文件属性:

/sdcard/.test (exists=false canWrite=false canRead=false canExecute=err isDirectory=false isFile=false)

/sdcard (exists=true canWrite=true canRead=true canExecute=err isDirectory=true isFile=false)

/ (exists=true canWrite=false canRead=true canExecute=err isDirectory=true isFile=false)

getExternalStorageState=mounted

(canExecute 返回 err 因为测试是在 sdk

非常欢迎提出建议和想法...

【问题讨论】:

  • 你能在你试图创建目录的地方显示代码吗?例如,如果你有硬连线/sdcard,那可能就是你的问题。
  • @CommonsWare:我正在使用 Environment.getExternalStorageDirectory() 并考虑在解决此问题后切换到 Context.getExternalFilesDir(null) ......我将使用代码编辑我的原始帖子.. 感谢您的快速回复!
  • 请记住,getExternalFilesDir() 仅适用于 Android 2.2,并且在该版本中已损坏。在可预见的未来,我会坚持你目前的策略。
  • 你找到解决方案了吗?

标签: android mkdir android-sdcard


【解决方案1】:

当您在清单中没有权限时,这很常见。

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

对我来说,这是唯一的错误。

【讨论】:

  • 我只对极少数用户有这个问题,而且我的 AndroidManifest.xml 在清单标签内有 WRITE_EXTERNAL_STORAGE 权限,所以很抱歉这不是原因..
【解决方案2】:

我遇到了一个类似的问题,花了几个小时才意识到出了什么问题。它在 Sumsung Mega 上不起作用,但在其他手机上运行良好。 我确实拥有 WRITE_EXTERNAL_STORAGE 权限,并且 getExternalStorageDirectory 已安装且可用。但仍然没有创建目录。 有什么帮助? 我刚刚重启了设备!它有帮助! 很遗憾,以前没有人建议过这个。希望这会有所帮助!

【讨论】:

    【解决方案3】:

    首先,从技术上讲,mkdirs() 返回 false 并不意味着它失败了,它只是意味着它没有创建目录。 如果目录已经存在,那么 mkdirs() 将继续返回 false。

    其次,在 Android 6 中,您不仅需要:

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

    你还需要一些等价物:

    ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
    

    有关检查权限的更多信息,请参阅:
    https://github.com/googlesamples/android-RuntimePermissions

    【讨论】:

    • 如果没有授予权限怎么办?如何正确申请?
    【解决方案4】:

    我在尝试在 SDCard 上创建目录时也遇到了问题。我发现正在发生的事情是我的代码可以在某些手机和模拟器上正常工作。但是其他手机会报错。

    我认为某些手机存在问题,Atrix 和 Bionic 就是两个例子。

    这些手机在使用 Environment.getExternalStorageDirectory() 代码时实际上返回 /mnt/sdcard。

    但在这些手机上,SD 卡实际上是 /mnt/sdcard-ext。

    因此,某些制造商似乎破坏了 getExternalStorageDirectory 代码,并且不知何故返回了错误的位置。

    我花了很长时间才弄清楚这一点,因为我的代码可以在许多不同的设备上运行,但仍然有一些用户报告它失败了。

    【讨论】:

      【解决方案5】:

      我的问题是我使用mkdir 创建多目录路径,而我每次都得到false。一旦我使用mkdirs,我的问题就解决了

      【讨论】:

        【解决方案6】:

        我遇到了同样的问题。设置了权限,路径也是默认路径(/mnt/sdcard),但我的 android 被安装为外部存储设备,用于快速浏览 SD 卡。 但是,这会干扰其他应用程序。

        我在深入 adb shell 时发现了这一点:

        $ cd /mnt   
        $ cd sdcard
        cd: can't cd to sdcard
        $ ls -l
        d--------- system   system            2011-12-07 01:59 sdcard
        

        卸载我得到的映像后:

        $ ls -l                   
        drwxrwxr-x system   sdcard_rw          2011-12-07 11:46 sdcard
        

        正如您在挂载时看到的那样,sdcard 位于系统用户组中,根本没有权限。卸载后该组更改为 sdcard_rw 并授予读写权限。

        【讨论】:

          【解决方案7】:

          我知道这是一个旧帖子,但我认为我仍然可以提供建议。如果您在开发时正在运行您的应用程序(即手机通过 USB 插入 PC),那么很可能 SD 卡已被 PC 挂载。您必须卸载它(您可以从手机或 PC 进行)以获得写入权限,这需要已在清单中设置。

          【讨论】:

            【解决方案8】:

            我以为我在调试应用程序时遇到了这个问题。它失败了,因为在调试时主机计算机安装了 SD 卡。从计算机上卸载使应用程序再次运行。

            【讨论】:

            • 也许我错了,但从技术上讲,这与我的答案相同,只是字数更少……:|
            【解决方案9】:

            这些用户的 SD 卡可能已损坏,因此以只读方式安装。如果可能,您应该与他们核实一下,看看是否有其他东西可以向其写入文件。鉴于您拥有 WRITE_EXTERNAL_STORAGE 权限,您应该可以轻松修改 SD 卡(并且 SD 卡中所有内容的权限都是此类应用程序的世界读/写权限,因此没有什么可以弄乱文件权限而导致他们麻烦) )。

            【讨论】:

            【解决方案10】:

            当符号链接 /storage/emulated/0 不知何故丢失时,我遇到了这个问题。我所做的是使用相机应用程序拍照。我观察到图片详细信息说它在 /storage/emulated/0 中,尽管文件资源管理器中不存在该目录。然后我重新启动了手机。重新启动后,目录显示在文件资源管理器中。

            【讨论】:

              【解决方案11】:

              我遇到了类似的问题。除了 Q (10) 之外,我的相机应用在所有 android 版本中都运行良好。

              问题是我使用 Environment.getExternalStorageDirectory(); 并且它在 android Q(以后)中已弃用。解决方案很简单,使用最新版本支持的东西context.getExternalFilesDir()

              这是我如何让它在所有设备上工作:-

              public static boolean createDirectory(Context context, String directoryPath) {
                  File folder;
              
                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
                      folder = new File(context.getExternalFilesDir(null), directoryPath);
                  else
                      folder = new File(Environment.getExternalStorageState(), directoryPath);
              
                  if (!folder.exists()) {
                      return folder.mkdirs();
                  }
              
                  return true;
              }
              

              【讨论】:

                【解决方案12】:

                由于引入了范围存储,如果您以 SDK 29 或更高版本(build.gradle 中的 targetSdkVersion)为目标,也会发生这种情况。 如果是这种情况,请将您的目标 SDK 更改为 28 或更低版本或添加:android:requestLegacyExternalStorage="true" 到您的清单,在应用程序键下。

                【讨论】:

                  【解决方案13】:

                  我在使用 mkdirs() 时遇到了类似的问题,但是因为运行命令:

                  mkdir 一/二

                  在 Linux 上失败,然后 API (http://download.oracle.com/javase/1.4.2/docs/api/java/io/File.html#mkdirs()) 随后也失败。我想这意味着没有办法在 Android 上使用 mkdirs?我(可能相当老套)的解决方法是分别创建每个必要的目录:

                  String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
                  new File(extStorageDirectory + "/one/").mkdirs();
                  new File(extStorageDirectory + "/one/two/).mkdirs();
                  

                  【讨论】:

                    【解决方案14】:

                    我在虚拟设备上遇到了这个问题。对我来说,问题是我没有为虚拟设备定义外部存储。希望对某人有所帮助。

                    【讨论】:

                      猜你喜欢
                      • 2015-01-25
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2019-05-16
                      • 2015-06-03
                      • 1970-01-01
                      相关资源
                      最近更新 更多