安卓:在外部存储上使用mkdirs()/mkdir()返回false

47

我为此而疯狂:

Log.d("STATE", Environment.getExternalStorageState());
File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "work_data");
Log.d("PATH", f.getAbsolutePath());
if (!f.exists()) {
    Log.d("MAKE DIR", f.mkdirs() + "");
}

输出日志看起来像这样:

STATE     mounted
PATH      /mnt/sdcard/DCIM/work_data
MAKE DIR  false

我确保添加了正确的权限:

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

但我不知道为什么它不能创建文件夹。我也逐步使用了 mkdir() 但结果仍然相同。请帮助我。我已经Google了很多并且至少花了两天时间在这件事上。感谢您的帮助!

编辑:

对不起大家!我在<application>标签中添加了<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>,这是我的错误!但是非常感谢大家的回复。


你的问题让我解决了使用mkdirs()时遇到的问题(我缺少WRITE_EXTERNAL_STORAGE授权)。由于没有抛出“权限被拒绝”异常,所以原因并不明显... - Sébastien
是的,我也认同你的想法。安卓过于复杂化了创建文件夹和文件这样简单的任务,真是疯狂。 - Paul McCarthy
16个回答

2
如果您使用的是 Android 6.0 或更高版本,请确保 gradle 文件中的目标 SDK 小于 22:
targetSdkVersion 22

或者你需要实现运行时权限。


2

你的代码对我来说运行得很好。你的代码没有任何问题。 只是如果你要创建一个目录,请使用f.mkdir()而不是f.mkdirs() 你可以在mnt => Sd card => DCIM => work_data中看到你的文件夹。


我也检查了f.mkdir(),但没有任何区别。我还在文件系统中检查了一下,没有这样的文件夹!!! - MHM
我刚刚在我的活动中复制并粘贴了你的代码,它正在工作,它正在创建文件夹。我不知道为什么你会遇到问题。 - Dharmendra

1
这可能会帮助将来的某个人。
问题也可能在于您编写了地址“/File/Address/”,而应该编写
File.separator + "File" + File.separator + "Address" + File.separator

这虽然是一件微小而愚蠢的事情,但在浪费了数小时的时间后,它对我起到了作用。


1
如果您的目标是Android api 29,则需要在AndroidManifest.xml中添加以下内容:

<application android:requestLegacyExternalStorage="true">

这将启用旧版外部存储权限模型,使您的应用程序可以继续访问共享外部存储。

0

当mkdirs()一直返回false时,我尝试在外部存储器'Test/Test1/Test2'中创建一组子文件夹。结果发现,'Test'是外部存储器根目录中一个文件夹的保留字。这是在Motorola G(XT1541)上发现的,可能也适用于其他设备。


隐藏目录名总是以 .(点)开头。 - jiwopene

0
对于新设备,您必须请求用户权限。
在创建文件之前,您可以像这样执行:
            boolean hasPermission = (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
        if (!hasPermission) {
            //ask permission
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    REQUEST_WRITE_STORAGE);
        }
        else {

           //you have permission, create your file
        }

在用户操作后,您可以处理结果。

  @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode)
    {
        case 1: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                //you have permission, create your file
                //reload my activity with permission granted or use the features what required the permission
            } else
            {
                Toast.makeText(MainActivity.this, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
            }
        }
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接