MediaStore.Images.Thumbnails.getThumbnail returns wrong thumbnail instead of NULL

拜拜、爱过 提交于 2019-12-09 14:40:54

问题


Consider the scenario as in this picture:

Three photos, one of them is a large GIF file (3MP).

I'm querying MediaStore in order to retrieve the correspondent thumbnails. If I initialize the Cursor via CursorLoader with this sortOrder:

MediaStore.Images.Media.DATE_ADDED + " DESC""

What happens: MediaStore returns the previous successfully retrieved thumbnail:

Expected behaviour: when MediaStore cannot retrieve the thumbnail of a given image for some reason it has to return NULL, as per its Javadoc: "... Returns A Bitmap instance. It could be null if the original image associated with origId doesn't exist or memory is not enough."

If I initialize the Cursor with this sortOrder:

MediaStore.Images.Media.DATE_ADDED + " ASC""

It runs just fine:

However I can't simply change the sortOrder since the requirement is to show the newest pictures first.

Below is my sample code and here is the complete sample project as well as the three images used to reproduce.

package com.example.getimagefrommediastore;

import android.app.Activity;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.content.CursorLoader;
import android.widget.ImageView;
import android.widget.TextView;

public class GetThumbnailsFromMediaStoreSampleActivity extends Activity {

TextView mThumb_id_01;
TextView mThumb_id_02;
TextView mThumb_id_03;
ImageView mImg_01;
ImageView mImg_02;
ImageView mImg_03;
boolean isThumb01 = true; // Simple flag to control this example
boolean isThumb02 = true;
Cursor mCursorLoader;
int mColumnIndex;
long mOrigId; // Original image id associated with thumbnail of interest

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Just initializing views
    mThumb_id_01 = (TextView) findViewById(R.id.thumb_id_01);
    mThumb_id_02 = (TextView) findViewById(R.id.thumb_id_02);
    mThumb_id_03 = (TextView) findViewById(R.id.thumb_id_03);
    mImg_01 = (ImageView) findViewById(R.id.thumb_01);
    mImg_02 = (ImageView) findViewById(R.id.thumb_02);
    mImg_03 = (ImageView) findViewById(R.id.thumb_03);

    // Initializing CursorLoader
    mCursorLoader = initializeCursorLoader();
    mColumnIndex = mCursorLoader.getColumnIndex(MediaStore.Images.Media._ID);

    // Go thru all the images in the device (EXTERNAL_CONTENT_URI)
    // In this example there are only three images
    for (int i = 0; i < mCursorLoader.getCount(); i++) {
        mCursorLoader.moveToPosition(i);
        mOrigId = mCursorLoader.getInt(mColumnIndex);

        // Update views
        chooseViewToUpdate();
    }
}

private Cursor initializeCursorLoader() {
    String[] COLUMNS = {
            MediaStore.Images.Thumbnails._ID, MediaStore.Images.Media.DATA
    };

    CursorLoader cursorLoader = new CursorLoader(
    GetThumbnailsFromMediaStoreSampleActivity.this, // Context
    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, // Uri
    COLUMNS, // Projection
    null, // Selection
    null, // Selection Args

    // Sort Order: DESC = newest first
    // Sort Order: ASC = oldest first

    MediaStore.Images.Media.DATE_ADDED + " DESC");

    // *** NOTE ***
    // With:
    //
    // MediaStore.Images.Media.DATE_ADDED + " ASC"
    //
    // It runs just fine (MediaStore returns 'null' for invalid thumbnails)
    // The problem seems to reside on the " DESC" tag.
    //
    // How bizarre is that?

    return cursorLoader.loadInBackground();
}

private void chooseViewToUpdate() {
    if (isThumb01) {
        updateUI(mThumb_id_01, mImg_01);
        isThumb01 = false;
    } else if (isThumb02) {
        updateUI(mThumb_id_02, mImg_02);
        isThumb02 = false;
    } else {
        updateUI(mThumb_id_03, mImg_03);
    }
}

private void updateUI(TextView textView, ImageView imgView) {
    textView.setText("ID:" + String.valueOf(mOrigId));

    Bitmap mediaStoreThumbmail = MediaStore.Images.Thumbnails.getThumbnail(
            this.getContentResolver(),
            mOrigId,
            MediaStore.Images.Thumbnails.MICRO_KIND, null);

    if (mediaStoreThumbmail != null) {
        imgView.setImageBitmap(mediaStoreThumbmail);
    }
}

Am I missing something? Does anyone have an idea what may be wrong?

I filled a bug against Android anyway.

EDIT

It seems that this issue is fixed in Lollipop. (The last comment on that thread).


回答1:


I"m just guessing here. When you ask for the MICRO_KIND the os is creating a new image which gets next in line on DESC cursor producing the same image again.

One work around is to load an ArrayList for the image id's. Then to go after the thumbnails working from the ArrayList.

Possibility try your code using the MINI_KIND and bmoptions.inSampleSize = 2;

 final BitmapFactory.Options bmOptions = new BitmapFactory.Options();
            bmOptions.inSampleSize =2;



                    Bitmap bm = MediaStore.Images.Thumbnails.getThumbnail(
                            context.getContentResolver(), newImageId,
                            MediaStore.Images.Thumbnails.MINI_KIND,
                            bmOptions);



回答2:


After three years, it seems that this issue is fixed in Lollipop. (The last comment on that thread).
Therefore I'm answering my own question.



来源:https://stackoverflow.com/questions/13651871/mediastore-images-thumbnails-getthumbnail-returns-wrong-thumbnail-instead-of-nul

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!