Android:外部存储上的 mkdirs()/mkdir() 返回 false

Posted

技术标签:

【中文标题】Android:外部存储上的 mkdirs()/mkdir() 返回 false【英文标题】:Android: mkdirs()/mkdir() on external storage returns false 【发布时间】:2011-11-04 23:14:19 【问题描述】:

我被这个逼疯了:

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(),但结果是一样的。请帮我。我在谷歌上搜索了很多,并且在这个愚蠢的事情上花了至少 2 天时间。谢谢你的帮助!!

编辑:

对不起大家!我在&lt;application&gt; 标签中添加了&lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/&gt;。这是我的错误!不过谢谢大家的回复。

【问题讨论】:

您的问题使我能够解决自己的 mkdirs() 问题(我缺少 WRITE_EXTERNAL_STORAGE 授权)。原因并不明显,因为没有抛出“permission denied”异常...... 【参考方案1】:

我遇到了同样的问题,我确定我把权限标签放在了正确的位置,但是mkdirs还没有工作,我的系统是Android 6.0,我现在解决了,你可以检查如下:

    确保您将权限标记放入 . 在你的手机中打开“设置/应用”,检查你的应用的权限(我发现我的manifest语句中的权限不在这里),像这样打开权限的开关。(我发现它默认是关闭的“mkdirs”失败)

【讨论】:

在 Android 6.0 中,您在使用某些权限时会请求这些权限。您可以使用函数ActivityCompat.requestPermissions 发出请求。请参阅here 了解更多信息。 在我的情况下,我在清单中请求权限,但不知何故它在应用程序权限中被禁用。你救了我的命,我爱你! ❤❤❤ 出于某种原因,我只需要关闭此权限,然后再次打开它就可以了。【参考方案2】:

我遇到了同样的问题,我已经搜索了一周的所有内容,试图找到答案。我想我找到了,而且我认为这非常简单,您必须将使用许可声明放在正确的位置...

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.company.name" 
    android:versionCode="1"
    android:versionName="0.2">

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

当我将它放在 部分时,它不起作用。

【讨论】:

在我的情况下正确答案。投票 对我不起作用。【参考方案3】:

我知道这是一篇旧帖子,但也许我的回答可以帮助某人。

在处理这个问题几天后,我意识到当手机连接到 PC 时,它总是在开发过程中,SD 卡不可用。因此,任何在其上创建目录或文件的尝试都会失败。 为了让它“更容易”,它的行为似乎因被测电话而异。

我知道这听起来可能是个很傻的问题,但它会花费很多时间,也许其他人可以节省。

【讨论】:

可能在某些设备中,而不是全部 那么如何在我的手机连接的情况下测试 mkdir()??【参考方案4】:

在 OnCreate() 中添加这行代码

ActivityCompat.requestPermissions(this,
            new String[]Manifest.permission.WRITE_EXTERNAL_STORAGE,1);

【讨论】:

我在Manifest 文件中拥有正确的权限,它在 android 7.1 上运行良好,但在 android 9.0 上尝试无法运行,requestPermission 成功了,谢谢!! 这解决了我使用 API 26+ 的问题【参考方案5】:

仅当您的 targetSdkVersion 为 29 或以上时适用

Environment.getExternalStorageDirectory() 在 API 级别 29 中已弃用。

要获得相同的功能,请使用此行

File mediaStorageDir = context.getExternalFilesDir(null);

如果您检查了所有可能的错误,请尝试此修复。

已经在这里回答了 - https://***.com/a/61480077/7764015

【讨论】:

祝福你的心!不知道我是怎么错过的,或者为什么 Android Studio 没有强行警告我已弃用。删除它似乎很重要。 对于 targetSdkVersion 29,可能会有一些差异。 getExternalFilesDir(null) 是在 .../Android/data/ 中使用 app-package-name 创建的应用程序的目录。如果某人的旧应用程序在其他地方创建了某个目录,例如在根目录中。该答案无法涵盖该问题,因为它们是两个不同的目录。临时解决方案应该是这样的:developer.android.com/training/data-storage/... 这个也解决了我的问题,我使用的 targetSdkVersion 大于 29 getExternalFilesDir 将只返回对应用程序自己在外部存储上的私有数据的访问权限。其他应用程序无法访问这些文件/文件夹。【参考方案6】:

回答可能为时已晚,但如果您已经允许 R/W 权限(也允许运行时权限)并且仍然无法正常工作,请在 AndroidManifest.xml

中添加下面提到的行>
<application
........
........
android:requestLegacyExternalStorage="true">

注意:如果您的目标是 Android 10+,则必须这样做

【讨论】:

【参考方案7】:

mkdirs() 仅在创建目录时才返回 true。如果它已经到位,它应该返回 false。所以我敢打赌这个目录已经存在了。

【讨论】:

没有。它没有。我在if (!f.exists()) 中检查它【参考方案8】:

我遇到了同样的问题,我只是想分享我的解决方法。 根据安卓 从 Android 4.4 开始,在应用的私有目录中读取或写入文件不需要 READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE 权限。

因此您可以通过添加 maxSdkVersion 属性来声明仅在较低版本的 Android 上请求权限:

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

但 maxSdkVersion 是问题所在,我刚刚删除了它,现在它可以工作了。

【讨论】:

【参考方案9】:
<application
        .....
        android:requestLegacyExternalStorage="true">

工作得很好。

【讨论】:

虽然这段代码可能会解决问题,但一个好的答案还应该解释代码的什么以及它如何提供帮助。 不。不适合我。【参考方案10】:

放这个

Log.d("MAKE DIR", f.mkdir() + "");

而不是

Log.d("MAKE DIR", f.mkdirs() + "");

或者试试这个

String s=Environment.getExternalStorageDirectory().toString()+"/";
File f = new File(s+"DCIM/work_data");

【讨论】:

【参考方案11】:

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

【讨论】:

我也检查了f.mkdir(),但没有区别。我也检查了文件系统,没有这样的文件夹!!! 我刚刚将您的代码复制并粘贴到我的活动中,它正在创建文件夹。我不知道您为什么遇到问题。【参考方案12】:

如果你有 android 6.0 及更高版本,请确保你的 gradle 文件中的目标 sdk 小于 22:

targetSdkVersion 22

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

【讨论】:

【参考方案13】:

这可能对将来的某人有所帮助。

问题也可能是你写地址“/File/Address/”而不是你应该写

File.separator + "File" + File.separator + "Address" + File.separator

这是一件小而愚蠢的事情,但在浪费了我几个小时之后,这对我有用。

【讨论】:

【参考方案14】:

当 mkdirs() 一直返回 false 时,我试图在外部存储“Test/Test1/Test2”中创建一组子文件夹。事实证明,“测试”是外部存储根目录中文件夹的保留字。这是在摩托罗拉 G (XT1541) 上的,也可能适用于其他设备。

【讨论】:

隐藏目录名总是以.(点)开头。【参考方案15】:

对于新设备,您必须征得用户许可。

您可以在创建文件之前这样做:

            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();
            
        
    


【讨论】:

以上是关于Android:外部存储上的 mkdirs()/mkdir() 返回 false的主要内容,如果未能解决你的问题,请参考以下文章

android-get nullpointerexception 尝试访问外部存储(sdcard)上的视频

Android:将外部存储器上的文件夹设为私有或受保护

Android数据存储(External Storage,外部存储)

Android数据存储(External Storage,外部存储)

Android 10:我都有哪些选择可以将外部存储上的文件保存到名为“/sdcard/my-app/”的目录中

安卓开发 Android studio 读取外部存储上的数据目录