Рассмотрим сценарий, как на этой картинке:
Три фото, одно из них большой GIF-файл (3MP).
Я запрашиваю MediaStore, чтобы получить соответствующие миниатюры. Если я инициализирую курсор через CursorLoader с этим sortOrder:
MediaStore.Images.Media.DATE_ADDED + " DESC""
Что происходит? MediaStore возвращает предыдущую успешно полученную миниатюру:
Ожидаемое поведение: когда MediaStore не может получить миниатюру данного изображения по какой-либо причине, он должен вернуть NULL в соответствии со своим документом Javadoc: "... Возвращает экземпляр Bitmap. Он может быть нулевым если исходное изображение, связанное с origId, не существует или недостаточно памяти."
Если я инициализирую курсор этим sortOrder:
MediaStore.Images.Media.DATE_ADDED + " ASC""
Он работает нормально:
Однако я не могу просто изменить sortOrder, поскольку требуется сначала показывать самые новые изображения.
Below is my sample code and here is the complete sample project as well as три изображения, используемые для воспроизведения.
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);
}
}
Я что-то упускаю? Кто-нибудь знает, что может быть не так?
Я все равно заполнил ошибку в Android.
ИЗМЕНИТЬ
Похоже, что эта проблема исправлена в Lollipop. последний комментарий в этой теме).
mOrigId
для каждого полученного изображения, оно может быть одинаковым для изображения 2 и 3. Или есть 4-е изображение, которое перезаписывает данные. В вашем коде есть несколько причин, которые могут вызвать такую ошибку. Тем более, что вы получаете только идентификатор изображения в своем запросе ASC/DESC, а затем разрешаете изображение во втором несвязанном запросе. - person zapl   schedule 30.11.2012Thumbnails.getThumbnail
, если вы используете правильные идентификаторы. - person zapl   schedule 01.12.2012/mnt/sdcard/DCIM/.thumbnails/
, а микроминиатюры — в специальный файл (.thumbdata3-[random number]
), большие миниатюры сохраняются в виде файлов .jpg. Вы можете проверить, что с ними в порядке, и, возможно, удалить их + принудительно остановить и удалить данные для приложения Media Storage (или переведенного) в настройках системы > приложения > все приложения. Это должно сбросить всю базу данных мультимедиа. - person zapl   schedule 03.12.2012