当父目录可写时,mkdirs 对于 sd 卡上的目录返回 false

发布于 2024-09-30 03:34:36 字数 874 浏览 1 评论 0原文

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

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

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

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

相关目录的文件属性:

/sdcard/.test(存在= 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=已安装

(canExecute 返回 err 因为测试是在 sdk <9 上运行的)

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

When starting my android application, I need to create a directory on the sd card, for a small number of users this fails and I can't figure out the reason for it...

(I've found similar problems caused by the WRITE_EXTERNAL_STORAGE permission missing, it's there and it works for almost all users so I don't think this is reason)

I've simplified the previous situation to make it easier to explain, if creating a directoy fails, I run a test case where I try to make a .test directory on the sdcard:

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

File properties of the relevant directories:

/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 returns err because the test is run on sdk < 9)

Suggestions and ideas are very welcome...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

懷念過去 2024-10-07 03:34:37

当您的清单中没有权限时,这种情况很常见。

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

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

It is common when you don't have a permission in your manifest.

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

As for me it was the only wrong thing.

倾城°AllureLove 2024-10-07 03:34:37

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

I had a simillar problem and spent several hours to realise what is wrong. It didn't work on Sumsung Mega, but for other phones it worked fine.
I really had WRITE_EXTERNAL_STORAGE permission and getExternalStorageDirectory is mounted and available. But still the directory wasn't created.
What helped ?
I just restarted the divice! And it helped!
It's a pity that nobody adviced this before. Hope this will help!

淡淡绿茶香 2024-10-07 03:34:37

首先,从技术上讲, 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

First of all, technically mkdirs() returning false doesn't mean that it failed, it just meant that it didn't make the directories.
If the directories already exist then mkdirs() will continue to return false.

Secondly, in Android 6, not only do you need:

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

You also need some equivalent of:

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

For more info on checking permissions, see:
https://github.com/googlesamples/android-RuntimePermissions

仙气飘飘 2024-10-07 03:34:37

我在尝试在 SDCard 上创建目录时也遇到了问题。我发现发生的事情是我的代码在某些手机以及模拟器上运行良好。但是其他手机会报告错误。

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

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

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

因此,看起来有些制造商已经破坏了 getExternalStorageDirectory 代码,并且以某种方式返回了错误的位置。

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

I have had issues trying to create directories on the SDCard as well. I found what was happening is that my code would work fine on some phones, and also the emulator. However other phones would report errors.

I believe there is an issue with certain phones, the Atrix and the Bionic are two examples.

These phones when using the Environment.getExternalStorageDirectory() code actually return /mnt/sdcard.

However on these phones the SD card is actually /mnt/sdcard-ext.

So somewhere along the lines it looks like some manufactures have broken the getExternalStorageDirectory code, and somehow its returning a false location.

I had a heck of a time figuring this out because my code worked on many different devices, and still some users reported it failed.

心不设防 2024-10-07 03:34:37

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

My problem was that I was using mkdir for creating a multiple directories path and I got false everytime. Once I used mkdirs my problem got resolved

趁微风不噪 2024-10-07 03:34:37

我也有同样的问题。设置了权限,路径也是默认路径(/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

正如您所看到的,安装时 SD 卡位于系统用户组中,并且根本没有权限。卸载后,组更改为 sdcard_rw,并授予读写权限。

I had the same problem. The permission was set and also the path was the default one (/mnt/sdcard) but my android was mounted as an external storage device for quick browsing the SD card.
However this interferes with other apps.

I figured this out when diving into the adb shell:

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

after unmounting the image I've got:

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

As you can see while mounted the sdcard is in the system user group and there are no permissions at all. After unmounting the group is changed to sdcard_rw and permissions to read and write are granted.

感情洁癖 2024-10-07 03:34:37

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

I know this is an old posting but I thought I can still offer a suggestion. If you're running your app while developing (ie. the phone is plugged into the PC via USB), then chances are, the SD card has been mounted by the PC. You have to unmount it (you can do it from the phone or from the PC) in order to gain write permission, this requires that has been set in the manifest.

流云如水 2024-10-07 03:34:37

我以为我在调试应用程序时遇到了这个问题。失败是因为调试时上位机挂载了SD卡。从计算机上卸载后,该应用程序再次运行。

I thought I was having this problem while debugging an app. It was failing because the SD Card was mounted by the host computer while debugging. Unmounting from the computer made the app work again.

云朵有点甜 2024-10-07 03:34:37

这些用户的 SD 卡可能已损坏,因此以只读方式安装。如果可能的话,您应该与他们联系,看看是否有其他东西可以向其中写入文件。鉴于您拥有 WRITE_EXTERNAL_STORAGE 权限,您应该可以轻松地修改 SD 卡(并且 SD 卡中所有内容的权限对于此类应用程序来说都是全局读/写的,因此没有任何东西可以扰乱文件权限而给它们带来麻烦)。

It is possible that these users have an SD card that is corrupt and thus mounted read-only. If possible, you should check with them to see if anything else can write files to it. Given that you have the WRITE_EXTERNAL_STORAGE permission, you should have no trouble making modifications to the SD card (and the permissions of everything in the SD card is world read/write for such apps, so nothing can mess with file permissions to cause them trouble either).

笨笨の傻瓜 2024-10-07 03:34:37

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

I ran into this problem when the symlink /storage/emulated/0 was somehow missing. What I did was use the camera app to take a picture. I observed that the pictures details said it was within /storage/emulated/0, though that directory did not exist from the file explorer. Then I rebooted the phone. After reboot the directory showed up in file explorer.

命硬 2024-10-07 03:34:37

我也有类似的问题。我的相机应用程序在除 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;
}

I was having a similar problem. My camera app was working fine in all the android versions but Q (10).

The issue was that I using Environment.getExternalStorageDirectory(); and its deprecated in android Q (onwards). The solution was simple, using something that was supported in the latest version which will be context.getExternalFilesDir()

Here is how I get it working in all the devices:-

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;
}
爱你是孤单的心事 2024-10-07 03:34:37

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

This can also happen if you target SDK 29 or greater(targetSdkVersion in build.gradle) due to the introduction of scoped storage.
If that is the case, either change your target SDK to 28 or lower or add: android:requestLegacyExternalStorage="true"
to your manifest, under Application key.

云朵有点甜 2024-10-07 03:34:37

我在使用 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();

I experienced a similar problem when using mkdirs(), however because running the command:

mkdir one/two

fails on Linux, then the API (http://download.oracle.com/javase/1.4.2/docs/api/java/io/File.html#mkdirs()) subsequently fails too. I guess this means there is no way to use mkdirs on Android? My (probably rather hacky) work-around was to create each necessary directory separately:

String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
new File(extStorageDirectory + "/one/").mkdirs();
new File(extStorageDirectory + "/one/two/).mkdirs();
念﹏祤嫣 2024-10-07 03:34:37

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

I ran into this issue on virtual device. For me the issue was that I had defined no external storage for the virtual device. Hopefully helps someone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文