Querying Android ContentResolver for gallery files and determining image vs video

Viewed 534

I'm trying to make a simple Android app for my own phone that looks at my Gallery, and for each image/video file:

  • creates a Bitmap thumbnail of the file
  • records the file's absolute path on the phone

Essentially, I'll have the following data model:

public class MediaFileModel {

  private Bitmap thumbnail;
  private String absPath;

  // ctor, getters and setters omitted for brevity
  
}

And I need something that looks at all the files in my Gallery and yields a List<MediaFileModel>. My best attempt is here:

public List<MediaFileModel> getAllGalleryMedia() {

  String[] projection = { MediaStore.MediaColumns.DATA };
  List<MediaFileModel> galleryMedia = new ArrayList<>();
  Cursor cursor = getActivity().getContentResolver().query(
    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
    projection,
    null,
    null,
    null);

  // I believe here I'm iterating over all the gallery files (???)
  while(cursor.moveToNext()) {
    MediaFileModel next = new MediaFileModel();

    // is this how I get the abs path of the current file?!?
    String absPath = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA));

    Bitmap thumbnail = null;
    if (true /* ??? cursor is pointing to a media file that is an image/photo ??? */) {
      thumbnail = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(absPath), 64, 64);
    } else {
      // else we have a video (I assume???)
      thumbnail = ThumbnailUtils.createVideoThumbnail(absPath, MediaStore.Images.Thumbnails.MINI_KIND);
    }

    next.setThumbnail(thumbnail);
    next.setAbsPath(absPath);

    galleryMedia.add(next);
    
  }

  return galleryMedia;
  
}

However I'm not sure if my media query is setup correctly and I'm definitely not sure how to determine whether the file is an image/photo of a video, which I (believe I) need so that I can use the correct method for obtaining the thumbnail Bitmap.

Can anyone help nudge me over the finish line here?

1 Answers

Here is a code I was using for something similar, I hope this will help:

 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(
        getActivity(),
        queryUri,
        projection,
        selection,
        null, 
        MediaStore.Files.FileColumns.DATE_ADDED + " DESC"
);


images.clear();

Cursor imagecursor = cursorLoader.loadInBackground();

if (imagecursor != null) {
    int image_column_index = imagecursor
            .getColumnIndex(MediaStore.Files.FileColumns._ID);
    int type_column_index = imagecursor.getColumnIndex(MediaStore.Files.FileColumns.MIME_TYPE);
    int count = imagecursor.getCount();
    for (int i = 0; i < count; i++) {
        imagecursor.moveToPosition(i);
        int id = imagecursor.getInt(image_column_index);
        String mime_type = imagecursor.getString(type_column_index);
        ImageItem imageItem = new ImageItem();
        imageItem.id = id;
        //lastId = id;

        if(!mime_type.contains("video"))
            imageItem.uriString = MediaStore.Images.Media.EXTERNAL_CONTENT_URI.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(id)).toString();
        else
            imageItem.uriString = MediaStore.Video.Media.EXTERNAL_CONTENT_URI.withAppendedPath(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, String.valueOf(id)).toString();


        images.add(imageItem);
    }

    imagecursor.close();
}
Related