0

doing a query with MediaStore.Images.Media does not show all images whether it is querying internal content or external content

The results (the thumbnails and the location those thumbnails are retrieved from) are not the same across even mainstream devices. Devices with no SD card and only internal storage have different image results, Samsung devices have different kinds of results, Google devices have different kinds of results.

Specifically with this code that is used around stackoverflow as a solution,

            final String[] columns = {MediaStore.Images.Thumbnails._ID};
            final String orderBy = MediaStore.Images.Media._ID;
            Cursor imagecursor = context.getContentResolver().query(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
                    null, null, orderBy);
            if (imagecursor != null) {
                int image_column_index = imagecursor
                        .getColumnIndex(MediaStore.Images.Media._ID);
                int count = imagecursor.getCount();
                for (int i = 0; i < count; i++) {
                    imagecursor.moveToPosition(i);
                    int id = imagecursor.getInt(image_column_index);
                    ImageItem imageItem = new ImageItem();
                    imageItem.id = id;
                    lastId = id;
                    imageItem.img = MediaStore.Images.Thumbnails.getThumbnail(
                            context.getApplicationContext().getContentResolver(), id,
                            MediaStore.Images.Thumbnails.MINI_KIND, null);
                    images.add(imageItem);
                }
                imagecursor.close();

I look at the code and it seems sound, but I need a better solution because results vary, and on some devices I have no idea where the resulting thumbnails have been pulled from

CQM
  • 42,592
  • 75
  • 224
  • 366
  • getThumbnail images don't exist until they are created. You'll get thumbnails out of your question to answer query all images. – danny117 Sep 29 '14 at 06:12
  • @danny117 "You'll get thumbnails out of your question to answer query all images" what? this doesn't seem like a coherent sentence to me, are you saying that I am only querying for thumbnails but instead I should be querying for a different image accessor? – CQM Sep 29 '14 at 14:28
  • you have example code to get a thumbnail image. The thumbnail images may be created on the fly by os. getThumbnail method checks if the thumbnails of the specified image (origId) has been created. It will be blocked until the thumbnails are generated. Therefore the thumbnails may not have been created and so they don't exist there not on the device. What do you want all the images or all the thumbnails? – danny117 Sep 29 '14 at 16:13
  • @danny117 I want all the images. I didn't realize these issues with retrieving thumbnails, but ultimately I only want the images and dont really care about thumbnails. I thought thumbnails would save memory but it may not be a good solution at all. Can you post better code for getting just all the images? – CQM Sep 29 '14 at 17:28
  • the code above has some problems. It would be more accurate to use the data column and do a file.exists() on it before getting the thumbnail because some image file may have been deleted with code. – danny117 Sep 30 '14 at 13:20

1 Answers1

2

As @danny117 pointed out to me, trying to get THUMBNAILS was a flawed assumption. One cannot rely on the existence of thumbnails for every image in the android system.

So I ultimately retrieve all images based on mime type, and use the Files MediaStore

 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, // Selection args (none).
            MediaStore.Files.FileColumns.DATE_ADDED + " DESC" // Sort order.
    );


    images.clear();
    /*
        final String[] columns = {MediaStore.Images.ImageColumns._ID, MediaStore.Images.ImageColumns.DATE_ADDED};
        final String orderBy = MediaStore.Images.Media.DATE_ADDED + " DESC";
        Cursor imagecursor = getActivity().getContentResolver().query(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
            null, null, orderBy);
    */

    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);
        }

        //add ImageItem at top of list

        imagecursor.close();
    }
CQM
  • 42,592
  • 75
  • 224
  • 366
  • I want to get only 20 images from the gallery that should be the most recent click, do you have a solution for that also my app is very slow when I'm using Cursor imagecursor = getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, null, orderBy); can the access time be improved, if you have a fix please reply, http://stackoverflow.com/questions/36417861/getting-the-recent-images-from-gallery-using-cursor – HAXM Apr 05 '16 at 13:09