Reputation: 75
My current code uses:
String DirectoryPath = "/storage/emulated/0";
File f = new File(DirectoryPath);
File[] file = f.listFiles();
The problem is that the array comes up as blank for anything outside:
/storage/emulated/0/Android/data/com.example.myProgram
From what I read online this no longer works with android 10+. So how would I list all files in a certain directory? (Making a file explorer as part of an App)
Upvotes: 4
Views: 5415
Reputation: 179
Yes, With old code it won't work. Here i found the solution
List<Uri> filesList = new ArrayList<>();
Uri collection;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
} else {
collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
String[] projection = new String[]{
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.SIZE
};
String selection = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
selection = MediaStore.Images.Media.BUCKET_DISPLAY_NAME +
" =? ";
}
String[] selectionArgs = new String[]{
"Your folder name"
};
String sortOrder = MediaStore.Images.Media.DISPLAY_NAME + " ASC";
Cursor cursor = getApplicationContext().getContentResolver().query(
collection,
projection,
selection,
selectionArgs,
sortOrder
);
if (cursor != null && cursor.moveToFirst()) {
Log.d("continue", "not null");
} else {
Log.d("continue", "null return");
return;
}
// Cache column indices.
int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
int nameColumn =
cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
int sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE);
do {
// Get values of columns for a given Images.
long id = cursor.getLong(idColumn);
String name = cursor.getString(nameColumn);
int size = cursor.getInt(sizeColumn);
Uri contentUri = ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
Log.d("continue", "path-->" + contentUri);
filesList.add(contentUri);
// Stores column values and the contentUri in a local object
// that represents the media file.
} while (cursor.moveToNext());
In the above code, I written for images only if you want any other files audio video you need to replace Images with Audio and Video ...etc
Note: if you convert Uri to file or string, then you can't use those files. You will get an error in android 10
Upvotes: 2
Reputation: 39
Just add this line of code to your manifest in the application tag.
android: requestLegacyExternalStorage= "true"
Upvotes: 2
Reputation: 442
Base on https://developer.android.com/reference/android/os/Environment#getExternalStorageDirectory(), To improve user privacy, direct access to shared/external storage devices is deprecated Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT.
In my case,I need to find images or any kind of documents like .docx,.xls file on user's device so I'm using ACTION_OPEN_DOCUMENT like bellow:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("*/*");
startActivityForResult(intent, REQUEST_CODE_INTENT_GET_CV);
Upvotes: 1
Reputation: 9282
What you described is valid.
Use Storage Access Framework to be able to list all directories.
Upvotes: 1
Reputation: 1134
for get fileNames,try this.
File sdCardRoot = Environment.getExternalStorageDirectory();
File yourDir = new File(sdCardRoot, "path");
for (File f : yourDir.listFiles()) {
if (f.isFile())
String name = f.getName();
// Do your stuff
}
Upvotes: 1