40

我被这个逼疯了:

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 天。谢谢你的帮助!!

编辑:

对不起大家!我已经添加<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><application>标签。这是我的错误!不过谢谢大家的回复。

4

15 回答 15

63

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

  1. 确保您将权限标签放入 .
  2. 在你的手机中打开“设置/应用程序”,检查你的应用程序的权限(我发现我的清单声明中的权限不在这里),像这样打开权限的开关。(我发现它默认是关闭的,这使得“mkdirs”失败的)

在此处输入图像描述

于 2016-06-13T02:59:02.663 回答
31

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

<?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" />

当我将它放在 <application></application> 部分时,它不起作用。

于 2011-11-18T11:59:54.517 回答
16

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

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

我知道这听起来可能是一个非常愚蠢的问题,但它花费了大量时间,也许其他人可以节省。

于 2012-10-23T14:08:57.607 回答
13

在 OnCreate() 中添加这行代码

ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
于 2017-04-12T09:10:57.430 回答
13

仅当您的targetSdkVersion 为 29 或更高时才适用

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

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

File mediaStorageDir = context.getExternalFilesDir(null);

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

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

于 2020-04-28T12:24:48.430 回答
8

回答可能为时已晚,但如果您已经允许 R/W 权限(也允许运行时权限)并且仍然不起作用,请在您的AndroidManifest.xml中添加下面提到的行

<application
........
........
android:requestLegacyExternalStorage="true">

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

于 2020-09-05T20:08:32.370 回答
6

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

于 2011-08-27T05:51:00.673 回答
3

我有同样的问题,我只是想分享我的修复。根据 android 从 Android 4.4 开始,在应用程序的私有目录中读取或写入文件不需要 READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE 权限。

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

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

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

于 2016-06-09T10:27:52.190 回答
3
<application
        .....
        android:requestLegacyExternalStorage="true">

运作良好。

于 2020-10-08T07:42:40.560 回答
2

把这个

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");
于 2011-08-27T04:40:36.637 回答
2

您的代码对我来说运行良好。您的代码没有任何问题。只要您使用一个目录f.mkdir()而不是f.mkdirs() 您可以在mnt => Sd card => DCIM => work_data

于 2011-08-27T05:02:09.983 回答
2

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

targetSdkVersion 22

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

于 2016-09-22T19:51:41.713 回答
1

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

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

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

这是一件如此小而愚蠢的事情,但在浪费了我数小时的时间后,这对我有用。

于 2014-12-16T22:07:29.517 回答
0

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

于 2018-06-05T05:50:50.430 回答
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();
            }
        }
    }

}
于 2019-08-26T16:28:12.313 回答