getExternalFilesDir(null) 返回 null。

23

我又遇到了一个之前被问过并且回答过的问题,但在我的实现中仍然无法正常运行。

我正是在主活动的 onCreate 方法的开头立即调用了 getExternalFilesDir(null)。无论我在模拟器上还是在我的手机上(三星 Galaxy Plus),它每次都返回 null。

是的,我在我的 AndroidManifest.xml 文件中有<uses-permission android:name="android.permissions.WRITE_EXTERNAL_STORAGE" />这一行,而且在调用之前我已经检查了外部存储状态,并且它是已挂载的。

这是我 onCreate() 方法内的前三行代码。实际上,它们就在 super.onCreate()setContentView() 调用之后。

String state = Environment.getExternalStorageState();
File extFiles = getExternalFilesDir(null);
File locFiles = getFilesDir();

所以,一旦这三行代码被执行,这些变量的值如下:

state == "mounted"
extFiles == null
locFiles == "/data/data/com.mypackage.name/files"

有人知道为什么会出现这种情况吗?

-----编辑-----

所以我尝试了另一种方法;不是使用getExternalFilesDir(null),而是使用File basePath = new File(Environment.getExternalStorageDirectory(), "myAppName");

虽然这不是理想的做法,我也知道Android文档说应该使用getExternalFilesDir(),我也同意这样做。但鉴于对我来说这个方法不起作用,我不得不尝试其他方法。这次函数确实返回了一个有效的文件对象,因此,在上述行之后,basePath的路径为/mnt/sdcard/myAppName,目前看起来还不错。当我使用DDMS进行检查时,可以看到/mnt/sdcard存在,但/mnt/sdcard/myAppName不存在,这是意料之中的。所以我调用了boolean result = basePath.mkdirs();

但是这返回false,当我在文件系统上检查时,可以确认myAppName子文件夹没有被创建。当我通过DDMS手动创建文件夹并将文件放入其中时,我可以从我的应用程序中读取这些文件,但我无法在该文件夹中写任何文件。

请帮忙!我已经束手无策了。


你尝试过使用特定类型,比如 MUSIC 吗? - njzk2
是的,我也尝试过那个方法,但它也返回了 null - Dewald Swanepoel
  1. 在Eclipse中清理/构建项目。
  2. 完全卸载/重新安装应用程序。同样的事情会发生吗?
- Geobits
好的,我刚刚尝试了一下,它也没有帮助。我发现另一个可能相关的奇怪事情。我将编辑原始问题以反映这一点。 - Dewald Swanepoel
4个回答

35
如果您发布问题时没有拼写错误,那么您可能会对此感到非常恼火: 应该是

5
先生,你是我新的好朋友!我爱你 :-) 天哪,我因为这个愚蠢的打字错误浪费了一整天。顺便说一下,在你发帖之前的几分钟,我发现我没有得到我请求的权限,但我想不出为什么。我添加了这行代码: (checkCallingOrSelfPermission("android.permission.WRITE_EXTERNAL_STORAGE") == PackageManager.PERMISSION_GRANTED) 它的结果是false。编译器会生成任何输出来指示当你在清单中有这些类型的错误时吗? - Dewald Swanepoel
5
据我所知,在 Android Studio 中,按住 Ctrl(Mac 上是 Cmd 键)并将鼠标悬停在已知权限上时,会出现下划线提示。但由于您可能会请求其他应用程序的权限,而这些应用程序的代码可能不在您手中,因此很难确定给定的权限是否存在拼写错误。 - FunkTheMonk

23

这是来自安卓文档:

返回外部存储上应用程序文件所在目录的路径。 如果当前未挂载外部存储,则返回null,因此无法确保路径存在;在可用时需要再次调用此方法。

另一种选择是检查外部存储是否可用:

String state = Environment.getExternalStorageState();
File filesDir;

// Make sure it's available
if (Environment.MEDIA_MOUNTED.equals(state)) {
    // We can read and write the media
    filesDir = getExternalFilesDir(null);
} else {
    // Load another directory, probably local memory
    filesDir = getFilesDir();
}

3
我正在检查媒体是否已经安装。如果函数返回空值,因为"外部存储当前未安装",那么我上面代码中state的值为什么会是**"已安装"**? - Dewald Swanepoel
4
注意!getExternalFilesDir()方法仅适用于API8及以上版本,而getFilesDir()方法在API19+(KitKat)上也无法使用。请小心处理 :) - Sdghasemi

0
我的问题是我打开了一个FileOutputStream,然后在关闭FileOutputStream之前,我打开了一个FileInputStream来查看文件中已有的内容。
我把打开FileInputStream的操作放到打开FileOutputStream之前,这解决了我的问题。

-1

删除一行

uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"   

AndroidManifest.xml 文件中。
在 Eclipse 中,将 XML 编辑器切换到“Android Manifest Permissions”,然后在“Permission”选项卡中添加一个。
uses-permission "android.permission.WRITE_EXTERNAL_STORAGE" 

只需点击几下。

然后尝试运行您的应用程序。


看起来 Eclipse(可能取决于版本、状态或设置的差异)可以忽略在 AndroidManifest.xml 中直接描述的某些单词。


感谢您的建议。您说得对,我的回答看起来像是在闲聊中表示同意。


抱歉,那似乎更像是一个“我也有这个问题”的评论,而不是对问题的回答。如果您想回答问题,请考虑重新措辞或添加更多细节。 - Harry

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