I'm using the android.content.CursorLoader class to create two Cursor objects to access media stored on the user of my app's device. I'd like to give the user a grid view of their stored images and video which preserves order from the Android Gallery app.
Currently I'm using one Cursor to access Images and one to access Video. With this approach, all images precede all videos (i.e. they are in two separate groups). Is there a way to access both Images and Video from the same Cursor? If not, is there a better way to access these media on the device?
For reference, here is the code I am using:
For Images:
CursorLoader cursorLoader = new CursorLoader(
mContext,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
IMAGE_PROJECTION,
null,
null,
MediaStore.Images.Media._ID + " desc"
);
mImageCursor = cursorLoader.loadInBackground();
And Video:
CursorLoader cursorLoader = new CursorLoader(
mContext,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
VIDEO_PROJECTION,
null,
null,
MediaStore.Video.Media._ID + " desc"
);
mVideoCursor = cursorLoader.loadInBackground();
After lots of research and playing around with source code, I'm finally a bit more familiar with the Android filesystem. To get a single Cursor which can access information about both Images and Video I used the following:
// Get relevant columns for use later.
String[] projection = {
MediaStore.Files.FileColumns._ID,
MediaStore.Files.FileColumns.DATA,
MediaStore.Files.FileColumns.DATE_ADDED,
MediaStore.Files.FileColumns.MEDIA_TYPE,
MediaStore.Files.FileColumns.MIME_TYPE,
MediaStore.Files.FileColumns.TITLE
};
// Return only video and image metadata.
String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE
+ " OR "
+ MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
Uri queryUri = MediaStore.Files.getContentUri("external");
CursorLoader cursorLoader = new CursorLoader(
this,
queryUri,
projection,
selection,
null, // Selection args (none).
MediaStore.Files.FileColumns.DATE_ADDED + " DESC" // Sort order.
);
Cursor cursor = cursorLoader.loadInBackground();
Related
ContentResolver contentResolver = context.getContentResolver();
Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = contentResolver.query(uri, null, selection, null, MediaStore.Audio.Media.TITLE + " ASC");
I want to sort audio by title name but running the above code ,i get capital letter audio first and then all the small letter audio.
how do i get absolute sort order,not mixed ordered list?
like from A to z
Try with
Cursor cursor = contentResolver.query(uri, null, selection, null, MediaStore.Audio.Media.TITLE + " COLLATE NOCASE ASC");
See if this works. I have not tried it, Just read somewhere long time back.
How can I query multiple specified file types when querying the MediaStore?
I have successfully set up querying only mp3 files with a specifed meme type but I would like to know how I can do more than 1.
Here's what I am doing to query only 1 file type:
String selectionMimeType = MediaStore.Files.FileColumns.MIME_TYPE
+ "=?";
String[] selectionArgsPdf = new String[] { MimeTypeMap.getSingleton()
.getMimeTypeFromExtension("mp3"), };
CursorLoader(getActivity(),
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
SONG_SUMMARY_PROJECTION, selectionMimeType,
selectionArgsPdf, MediaStore.Audio.Media.DISPLAY_NAME);
How can I query only mp3 and another file type? thanks.
The following edit will do the job
Audio.Media.DATA + " like ? OR " + Audio.Media.DATA + " like ? ";
String[] selectionArgsPdf = new String[]{ "%mp3","%wav" };
CursorLoader(getActivity(), MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
SONG_SUMMARY_PROJECTION, selectionMimeType,
selectionArgsPdf, MediaStore.Audio.Media.DISPLAY_NAME);
And first of all thanks for your help.
I think this should be a rather trivial question for somebody not new to querying Content Providers.
I need to query MediaStore.Images.Media to obtain ALL the images on the device, both on internal storage and on an sd card.
This is the query I have in mind:
String[] proj = { MediaStore.Images.Media.DATA };
actualimagecursor =
managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj,null, null, null);
the point is that I want to query both EXTERNAL_CONTENT_URI and INTERNAL_CONTENT_URI.
Is it possible to perform it with a single query?
Sorry this is too old to help, but you can use MergeCursor to combine the two queries.
Cursor[] cursors = new Cursor[2];
cursors[0] = mActivity.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DATA,
MediaStore.Images.Media.ORIENTATION,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.BUCKET_ID,
MediaStore.Images.Media.MIME_TYPE ,
},
null,
null,
MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC"
);
cursors[1] = mActivity.getContentResolver().query(
MediaStore.Images.Media.INTERNAL_CONTENT_URI,
new String[]{
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DATA,
MediaStore.Images.Media.ORIENTATION,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.BUCKET_ID,
MediaStore.Images.Media.MIME_TYPE
},
null,
null,
MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC"
);
Cursor cursor = new MergeCursor(cursors);
It's not possible to retrieve both results with a single query since the query is permofmed in a specific location (internal or external). You need yo instantiate two dirrefent Cursors.
I was just curious about what the MediaStore.Images.Media.MINI_THUMB_MAGIC column contains. Does it have anything to do with the image's thumbnail? Thank you.
See MediaStore.Images.ImageColumns from the Android developers ref. for the doc -- which says it returns "the mini thumb id".
Also see Displaying Thumbnail Photos on Map for how to use this ID:
long thumbId = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.ImageColumns.MINI_THUMB_MAGIC));
String[] args = new String[]{String.valueOf(thumbId)};
Cursor ct = managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Thumbnails._ID + "= ?", args, null);
MINI_THUMB_MAGIC returns a random number and you can not get thumbnail id from this. Use MediaStore.Images.Media._ID, it is the same number as MediaStore.Images.Thumbnails.IMAGE_ID
ArrayList<String> ids; // ArrayList of MediaStore.Images.Media._ID
String selection = MediaStore.Images.Thumbnails.IMAGE_ID + " IN (" + TextUtils.join(",", ids) + ")";
Cursor cursor2 = resolver.query(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
new String[]{{MediaStore.Images.Thumbnails.DATA,MediaStore.Images.Thumbnails.IMAGE_ID}},
selection,
null,
null);
I'm trying to create a list that shows both audio and video from the mediastore. However, I'm not sure how to create such a query - is it even possible to get information for both audio and video at the same time?
So to query for video and audio I do this:
String[] projV = { MediaStore.Video.Media._ID,
MediaStore.Video.Media.DATA,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.DURATION,
MediaStore.Video.Media.DATE_TAKEN };
Cursor videoCursor = getActivity().managedQuery(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projV, null,
null, null);
String[] projA = { MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.MIME_TYPE,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.DATE_ADDED };
Cursor audioCursor = getActivity().managedQuery(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projA, null,
null, null);
I looked into using CursorJoiner or MergeCursor, but I'm not sure how to use these or even certain its the right solution.
So my question is; Is there a way to construct a query for the mediaStore that returns a cursor with information for both audio and video or do I need to something more complex such as using CursorJoiner or MergeCursor.
As I mentioned at the start, my goal is to have a list displaying all the audio and video in the mediastore - is this the right approach or am I looking at it from a wrong angle?
Thanks.
It is possible from API-11 by using MediaStore.Files with an appropriate selection clause.
public Loader<Cursor> onCreateLoader(int id, Bundle bundle)
{
final String PROJECTION[] = {FileColumns._ID, FileColumns.DATA, FileColumns.DATE_ADDED};
final String ORDER = FileColumns.DATE_ADDED + " DESC";
final String SELECTION = "(" + FileColumns.MEDIA_TYPE + "=" + FileColumns.MEDIA_TYPE_VIDEO +") OR (" + FileColumns.MEDIA_TYPE + "=" + FileColumns.MEDIA_TYPE_IMAGE + ")";
return new CursorLoader(getActivity(), Files.getContentUri("external"), PROJECTION, SELECTION, null, ORDER);
}
Prior to that you can use a MergeCursor if you don't care about sort order. Look at MatrixCursor if you need to manage sort order. Alternatively wrap your cursors in a CursorWrapper that implements order logic.