文件存在且IS目录,但listFiles()返回null

Wil*_*son 63 java io android file-permissions file

File.listFiles()建议的文档null只有在调用它的文件不是目录的情况下才会返回.

我有以下内容:

String dir = "/storage/emulated/0";
File f = new File(dir);
Log.v("Files",f.exists()+"");
Log.v("Files",f.isDirectory()+"");
Log.v("Files",f.listFiles()+"");
Run Code Online (Sandbox Code Playgroud)

日志显示:

true
true
null
Run Code Online (Sandbox Code Playgroud)

由于某种原因,即使被识别为有效目录,listFiles(也会返回.我对Android文件层次结构行为并不是很熟悉,所以我猜测问题就在那里.nullFile

作为参考,我正在我的Moto X上进行调试,无论手机是否插入我的电脑,结果都是一样的 - 所以我认为这不会与插入时的安装有关.

Bam*_*amx 87

对于有此问题的人,请将其添加到AndroidManifest.xml:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)

问题解决了:D

编辑:如果这不起作用只是确保路径是否正确

  • 在Marshmallow +上你还需要调用以下内容:ActivityCompat.requestPermissions(activity,new String [] {Manifest.permission.WRITE_EXTERNAL_STORAGE},requestCode); (19认同)
  • 这个答案+5!我想知道为什么没有错误说我在logcat中没有此权限? (2认同)

小智 50

除了其他答案和评论,我建议您检查是否需要

<application android:requestLegacyExternalStorage="true"
Run Code Online (Sandbox Code Playgroud)

在您的清单中。似乎最近的一些api需要它。

无论如何,zapl 的评论相当短,但很有见地。您可以“ls -ld”设备上的目录(通过“adb shell”或其他一些shell)。如果您对该目录具有“r”权限,则可以调用 listFiles()。否则,它返回 null。请注意,如果您知道文件名并且对该目录具有“x”权限,则您可以访问不可读目录下的文件。你可以通过“whoami”和“groups”命令知道你是谁。

  • Android 10 需要 (7认同)
  • requestLegacyExternalStorage 是过渡性的,当您为 SDK 30 构建时,Android 11 不支持 requestLegacyExternalStorage:https://developer.android.com/training/data-storage/use-cases#opt-out-in-Production-app (2认同)

var*_*jsi 21

对于Android 版本23或更高版本,您需要在onresume方法中以编程方式提供运行时权限,如下所示,

public final String[] EXTERNAL_PERMS = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE
};

public final int EXTERNAL_REQUEST = 138;

requestForPermission();

public boolean requestForPermission() {

    boolean isPermissionOn = true;
    final int version = Build.VERSION.SDK_INT;
    if (version >= 23) {
        if (!canAccessExternalSd()) {
            isPermissionOn = false;
            requestPermissions(EXTERNAL_PERMS, EXTERNAL_REQUEST);
        }
    }

    return isPermissionOn;
}

public boolean canAccessExternalSd() {
    return (hasPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE));
}

private boolean hasPermission(String perm) {
    return (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this, perm));

}
Run Code Online (Sandbox Code Playgroud)


小智 12

对于有此问题的用户,您可以将其添加到AndroidManifest.xml:

android:name="android.permission.READ_EXTERNAL_STORAGE" 
Run Code Online (Sandbox Code Playgroud)

你也应该给予许可

设置>应用> "您的应用名称" >权限>存储


msk*_*app 8

从File'listFiles'方法文档:如果此抽象路径名不表示目录,或者发生I/O错误,则返回null.

所以可能发生了I/O错误.检查该目录的权限,运行java程序的用户是否有权读取该目录?如果没有,那就有你的答案.如果他们这样做,那么该目录可能是空的.

顺便说一句,你不应该使用+""将某些东西转换为字符串,这是一种不好的做法,因为它比String.valueOf慢.我会使用apache的StringUtils将该数组连接成一个字符串,但这需要将该jar添加到类路径中.


小智 5

只需在清单中添加权限uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" 即可解决您的问题。


小智 5

  1. 项目清单

将其添加到您的 AndroidManifest.xml <application android:requestLegacyExternalStorage="true" .../> 它对我有用。