I'm trying to build a Gallery-like app which will perform the following functions on External storage:
- List all the folder that has images inside it
- List all the images that available to the public (will not probe the files inside
Android/data
)
So far I can list all the images, and folders that have images. However, I later find that these images and folders are not the newest ones: they are not getting refreshed after I put some pictures (say I simply do some screenshots or download some pictures).
And new pictures are not appear even after I call MediaScannerConnection.scanFile
.
Except the MediaScannerConnection
, I've also tried the expensive Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
method with the specified folders, and no luck.
I've browsing on StackOverflow as well as various of sources with people discussing this issue, but none of them can offer a working method.
Sources I've checked/tried:
- http://droidyue.com/blog/2014/01/19/scan-media-files-in-android/
- Trigger mediascanner on specific path (folder), how to?
Code:
How I list all the images:
private String[] projectionThumbnail = new String[]{MediaStore.Images.Thumbnails._ID, MediaStore.Images.Thumbnails.IMAGE_ID, MediaStore.Images.Thumbnails.DATA};
private Uri uriThumbnail = MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI;
private String[] projectionFull = new String[]{MediaStore.Images.Media._ID, MediaStore.Images.Media.BUCKET_DISPLAY_NAME, MediaStore.Images.Media.DATA};
private Uri uriFull = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch (id) {
case LOADER_ALL_IMAGES:
return new CursorLoader(getActivity(), uriThumbnail, projectionThumbnail, null, null, MediaStore.Images.Thumbnails._ID + " DESC");
default:
return null;
}
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
switch (loader.getId()) {
case LOADER_ALL_IMAGES:
adapter.changeCursor(cursor);
break;
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.changeCursor(null);
}
// And here's how I init the CursorLoader
LoaderManager lm = getActivity().getLoaderManager();
lm.initLoader(LOADER_ALL_IMAGES, null, this);
Here's how I start scanning the images, I intend to scan the whole External storage, but for now, I'll just scan DCIM, PICTURES and DOWNLOADS just for experiment
File dcim = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File pictures = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File downloads = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
MediaScannerConnection.scanFile(this,
new String[]{dcim.getAbsolutePath(), pictures.getAbsolutePath(), downloads.getAbsolutePath()}, new String[]{"image/*", "image/*", "image/*"},
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
Question:
I did my test on Stock 5.0.2 and 4.4, same result on both of them.
- Am I doing anything wrong?
- Why does the MediaScanner not working?
Note:
Interestingly, if I open Instagram and open "select gallery" from there. The gallery content is getting refreshed. So it means Instagram is doing the "gallery refreshing" very well so that my app can also receive the newest gallery content, how do they do that?