【问题标题】:Cannot create directory in external storage although permissions are apparently set correctly尽管权限显然设置正确,但无法在外部存储中创建目录
【发布时间】:2016-01-23 03:40:18
【问题描述】:

我有

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

在我的清单文件中,但是尝试创建目录时失败

    Log.d(LOG_STRING, android.os.Environment.getExternalStorageState() );
    java.io.File folder = new java.io.File(Environment.getExternalStorageDirectory() + java.io.File.separator + "test");
    boolean success = true;
    if (!folder.exists()) {
        success = folder.mkdir();
    }
    if (success) {
        Log.d(LOG_STRING, "Created directory");
    } else {
        Log.d(LOG_STRING, "FAILED WHILE CREATING DIRECTORY");
    }

外部存储状态为“mounted”,但无法创建test目录,输出为"FAILED WHILE CREATING DIRECTORY"

在手机中浏览“应用信息”,“修改或删除你的U盘内容”权限被标记为为我的应用激活。

这可能是什么原因?手机的一些特殊设置?这是一款搭载 Android 4.3 (API18) 的三星 GT-I9506。需要注意的是getExternalStorageDirectory不在SD卡上,而是在内部存储(/storage/emulated/0/)上。


更新:

与同事交谈,这款设备在 root 后似乎经历了几次调整(以允许特定应用程序直接在 SD 卡上写入)。可能不值得进一步调查,我将简单地切换到另一个设备。我会保留设备一段时间,如果有人会给出答案,我会快速测试它是否能解决问题。


更新 2:(赏金结束)

问题仍未解决,但如前所述,这很可能是这台设备特有的问题。无法在任何路径上写入,无论是外部存储还是内部存储,甚至在getExternalCacheDir() 返回的路径中也是如此。

【问题讨论】:

  • 如果您不在 kitkat 上,这应该不是问题。您可以尝试按照此处的说明调试 sdcard 状态并发布结果吗? developer.android.com/intl/es/reference/android/os/…
  • @bonnyz 我知道这不是完整的测试,但作为第一个快速反馈,在尝试创建目录之前,以下返回 true:Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState() )(根据您链接的代码,应该授予写入权限)。
  • 是的,你是对的。您是否设法在其他设备上进行了测试?
  • /system/etc/permissions/platform.xml 中可能有问题。
  • @bonnyz 使用 Galaxy Note 4 (API21) 就可以了。

标签: java android galaxy


【解决方案1】:

就我而言,我必须进入Settings -&gt; Apps -&gt; NameOfApp -&gt; Permissions 并激活存储权限。如果我拥有 AndroidManifest.xml 的所有权限,我不知道为什么默认情况下会停用此功能。我正在使用装有 Android Marshmallow 6.0 的 Moto G(第 3 代)。

【讨论】:

  • 我发现了它为什么默认禁用。由于Marshmallow,您必须在运行时请求权限。见this nice tutorial
【解决方案2】:

您首先需要使用file.mkdirs() 而不是folder.mkdir()

如果它也不起作用,那么你需要检查你是否可以访问 sdcard。

为了检查你可以使用下面的方法。

boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();

if (Environment.MEDIA_MOUNTED.equals(state)) {

    // We can read and write the media
    mExternalStorageAvailable = mExternalStorageWriteable = true;

} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {

    // We can only read the media
    mExternalStorageAvailable = true;
    mExternalStorageWriteable = false;

} else {

    // Something else is wrong. It may be one of many other states, but all we need
    //  to know is we can neither read nor write
    mExternalStorageAvailable = mExternalStorageWriteable = false;

}

阅读官方document

希望能给你一些线索。

【讨论】:

  • 我已经收到了来自 bonnyz 的 the same suggestionMadhukar Hebbar...
  • 最后一个建议,看看有什么问题。尝试硬编码路径“/mnt/sdcard”而不是“Environment.getExternalStorageState()”。
  • 我也无法在“mnt/sdcard”中创建目录。
  • 您是否阅读了问题的最后一部分(更新)以及问题下方的 cmets? :) 是的,我做到了,并且该代码适用于其他设备。
  • 我的意思是其他设备,但具有相同的型号和 API **Samsung GT-I9506 with Android 4.3 (API18) ** .
【解决方案3】:

你可以试试这个代码。我还在 Lg g2 mini 上模拟了 sd 卡,我只能访问我的包文件夹中的外部卡

for(File f : getExternalFilesDirs(null)){
    try {
        File f2 = new File(f.getAbsolutePath(), "testFile");

        Log.d("test log", "file path " + f2.getAbsolutePath());
        f2.createNewFile();
        Log.d("test log", "file exist " + f2.exists());
    } catch (IOException e) {
        Log.d("test log", "error");
    }
}

输出是:

D/test log? file path /storage/emulated/0/Android/data/my.awesome.package/files/testFile
D/test log? file exist true
D/test log? file path /storage/external_SD/Android/data/my.awesome.package/files/testFile
D/test log? file exist true

【讨论】:

  • 在哪里可以找到getExternalFilesDirs?我尝试使用android.os.Environment.getExternalFilesDirs(null) 无济于事......
  • 对不起,它是从活动中调用的,您可以直接从上下文中调用它,它来自 api 19。在旧版本上,这个问题可能不存在,所以没关系。 (不利)这样做的好处是,当您的应用程序被卸载时,它创建的所有文件也会被删除。
  • 恐怕我们在这里处理的是 api 18
  • 你很幸运,它来自 api 19 developer.android.com/guide/topics/manifest/… 。如果这篇文章是对的,你甚至不需要 19 api 的写权限
  • 我在哪方面是幸运的? :)
【解决方案4】:

试试这个:

     final File externalStoragePublicDirectory = Environment.getExternalStorageDirectory();
     File file = new File(externalStoragePublicDirectory, "test");
     file.mkdirs();

【讨论】:

  • 结果不变。
  • 你能在模拟器或任何其他设备上试试这个。我在模拟器中试了一下,效果很好。
  • 很明显代码不是问题。问题一定出在我正在使用的设备的某些配置中。无论如何感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 2017-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-20
  • 2019-06-15
相关资源
最近更新 更多