Reputation: 3042
I'm creating an Android app, and I want to list the files in a directory. I do this by calling
File[] files = path.listFiles(new CustomFileFilter());
path
is a File
object, which is created by calling
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
When I then try to get the length of the files
array by calling
int length = files.length;
This line gives me a NullPointerException
, because files
is null.
I have checked if the path
which I try to list the files in exists by calling
System.out.println("Path exists: " + path.exists());
And when I run the app, it prints
Path exists: true
in the Android Studio console, so the directory exists.
I've also printed the path name, which is
/storage/emulated/0/Download
So the path
is a directory, and not a file.
I have no idea about why I'm getting a NullPointerException
, because the path
is a directory.
EDIT: The CustomFileFilter
class looks like this:
public class CustomFileFilter implements FileFilter {
// Determine if the file should be accepted
@Override
public boolean accept(File file) {
// If the file isn't a directory
if(file.isDirectory()) {
// Accept it
return true;
} else if(file.getName().endsWith("txt")) {
// Accept it
return true;
}
// Don't accept it
return false;
}
}
Upvotes: 8
Views: 13537
Reputation: 1177
make sure you followed the Saeed Masoumi’s answer, and if you still have the problem it is because you have set Target API 29 or higher.
add this property in your application tag of Manifest file and it will work.
android:requestLegacyExternalStorage="true"
According to google’s App compatibility features for data storage :
Before your app is fully compatible with scoped storage, you can temporarily opt out by using one of the following methods:
<manifest ... >
<!-- This attribute is "false" by default on apps targeting
Android 10 or higher. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
To test how an app targeting Android 9 or lower behaves when using scoped storage, you can opt in to the behavior by setting the value of requestLegacyExternalStorage to false.
Upvotes: 5
Reputation: 9121
For those who are working on android SDK>23, you need to grant the permissions by code: use something like:
boolean grantedAll = ContextCompat.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
if (!grantedAll)
{
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
Upvotes: 3
Reputation: 8916
Add this to AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
This permission allow you to read files; if you don't use this permission then listFiles()
and list()
will both throw NullPointerException
.
And here is an example of showing all files in /storage/emulated/0/Download
:
String dir = "/storage/emulated/0/Download/";
File f = new File(dir);
String[] files = f.list();
for(int i=0; i<files.length; i++){
Log.d("tag", files[i]);
}
Upvotes: 9