File exists and IS directory, but listFiles() returns null

JavaAndroidFileIoFile Permissions

Java Problem Overview


The documentation for File.listFiles() suggests that null will ONLY be returned in the case that the file calling it is not a directory.

I have the following:

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

The log reads:

true
true
null

For some reason, listFiles() is returning null even though the File is recognized as a valid directory. I'm not super familiar with Android file hierarchy behavior, so I would guess the problem lies in there.

For reference, I'm debugging on my Moto X, and results are the same whether the phone is plugged in to my computer or not - so I don't think it has to do with mounting when plugged in.

Java Solutions


Solution 1 - Java

For those with this problem, add this to AndroidManifest.xml:

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

Problem solved :D

EDIT: If this does not work just make sure if path is correct

Solution 2 - Java

In addition to other answers and comments, I'd suggest you check whether you need

<application android:requestLegacyExternalStorage="true"

in your manifest. It seems that some recent apis need it.

Anyway, zapl's comment is rather short but quite insightful. You can "ls -ld" the directory on the device (via "adb shell" or some other shells). If you have "r" permission on the directory, you can call listFiles(). Otherwise, it returns null. Note that you can access files under the unreadable directory if you know the file names and have "x" permission on the directory. You can know who you are by "whoami" and "groups" commands.

Solution 3 - Java

For android version 23 or higher, you need to give run time permission programmatically in onresume method as below,

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

}

Solution 4 - Java

For those with this problem you to give read permission, add this to AndroidManifest.xml:

android:name="android.permission.READ_EXTERNAL_STORAGE" 

and you should also grant permission from

Settings > Apps > "Your app name" > Permissions > storage

Solution 5 - Java

From the File 'listFiles' method documentation: Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs.

So perhaps an I/O error occurred. Check the permissions on that directory, does the user running the java program have the permission to read that directory? If not, there is your answer. If they do, then perhaps the directory is empty.

BTW you should not use +"" to convert something to a string, it's a bad practice since it's slower than String.valueOf. I would use apache's StringUtils to join that array into a string, but that requires adding that jar to your classpath.

Solution 6 - Java

Just add the permission in manifest uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" and your problem will be resolved.

Solution 7 - Java

@tamo's answer resolved my issue, i compile exoplayer on ANQ, and set :

build.gradle :

android {
compileSdkVersion 29
buildToolsVersion '29.0.0'

defaultConfig {
    minSdkVersion 16
    targetSdkVersion 29
}

manifest.xml :

  <application
  android:name="com.google.android.exoplayer.demo.ExoPlayerDemoApplication"
  android:label="@string/application_name"
  android:icon="@drawable/ic_launcher"
  android:largeHeap="true"
  android:allowBackup="false"
  android:requestLegacyExternalStorage="true">

i check android develop site, it's already explain this : https://developer.android.com/training/data-storage/compatibility

if you target API 29 or higher, just follow google's setting.

Solution 8 - Java

  1. List item

Add this in your AndroidManifest.xml It worked for me.

Solution 9 - Java

My problem was that for some reason the android:sharedUserId="android.uid.system" attribute was not allowing the app to read /sdcard/ on a specific device.

As I needed to do only a quick test, I removed the sharedUserId attribute, tested and added it back.

Solution 10 - Java

First make sure that you are asking the permission for reading the external storage

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

if you want you can the Dexter library for asking permission it is very easy to ask permission using the dexter library

here is the link to that

Dexter library

then after that add the following tag in the tag in the manifest

android:requestLegacyExternalStorage="true"

then the listFiles() function will not return null array

Solution 11 - Java

I had a same problem in java but not in android where i am reading config file with path in quotes. I solved my issue with just removing quotes

So you can do it by String replace function or give it without quotes

String someString= "C:\path"; someString=someString.replace(""","");

Solution 12 - Java

In the manifest file at the <uses-permission .... > section, add this line android:name="android.permission.READ_EXTERNAL_STORAGE". I think this may solve your problem.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWilsonView Question on Stackoverflow
Solution 1 - JavaBamsBamxView Answer on Stackoverflow
Solution 2 - JavatamoView Answer on Stackoverflow
Solution 3 - Javavarotariya vajsiView Answer on Stackoverflow
Solution 4 - JavaRavi JoshiView Answer on Stackoverflow
Solution 5 - JavamsknappView Answer on Stackoverflow
Solution 6 - JavakamalView Answer on Stackoverflow
Solution 7 - Javafranke.wuView Answer on Stackoverflow
Solution 8 - Javamalware_656View Answer on Stackoverflow
Solution 9 - JavathiagolrView Answer on Stackoverflow
Solution 10 - Javauser10814186View Answer on Stackoverflow
Solution 11 - JavaSomnath SarodeView Answer on Stackoverflow
Solution 12 - JavaRajan MenonView Answer on Stackoverflow