デバイスのメディアストアにある写真のサムネイルを表示し、ユーザーが写真を選択できるようにするアプリ内アクティビティを提供しようとしています。ユーザーが選択した後、アプリケーションは元のフルサイズの画像を読み取り、それを使用して処理を行います。
次のコードを使用しCursor
て、外部ストレージにすべての画像を作成しています。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView( R.layout.image_select );
mGridView = (GridView) findViewById( R.id.image_select_grid );
// Query for all images on external storage
String[] projection = { MediaStore.Images.Media._ID };
String selection = "";
String [] selectionArgs = null;
mImageCursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
projection, selection, selectionArgs, null );
// Initialize an adapter to display images in grid
if ( mImageCursor != null ) {
mImageCursor.moveToFirst();
mAdapter = new LazyCursorAdapter(this, mImageCursor, R.drawable.image_select_default);
mGridView.setAdapter( mAdapter );
} else {
Log.i(TAG, "System media store is empty.");
}
}
そして、サムネイル画像をロードするための次のコード(Android 2.xコードが表示されています):
// ...
// Build URI to the main image from the cursor
int imageID = cursor.getInt( cursor.getColumnIndex(MediaStore.Images.Media._ID) );
Uri uri = Uri.withAppendedPath( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
Integer.toString(imageID) );
loadThumbnailImage( uri.toString() );
// ...
protected Bitmap loadThumbnailImage( String url ) {
// Get original image ID
int originalImageId = Integer.parseInt(url.substring(url.lastIndexOf("/") + 1, url.length()));
// Get (or create upon demand) the micro thumbnail for the original image.
return MediaStore.Images.Thumbnails.getThumbnail(mContext.getContentResolver(),
originalImageId, MediaStore.Images.Thumbnails.MICRO_KIND, null);
}
そして、ユーザーが選択したら、URLから元の画像をロードする次のコード:
public Bitmap loadFullImage( Context context, Uri photoUri ) {
Cursor photoCursor = null;
try {
// Attempt to fetch asset filename for image
String[] projection = { MediaStore.Images.Media.DATA };
photoCursor = context.getContentResolver().query( photoUri,
projection, null, null, null );
if ( photoCursor != null && photoCursor.getCount() == 1 ) {
photoCursor.moveToFirst();
String photoFilePath = photoCursor.getString(
photoCursor.getColumnIndex(MediaStore.Images.Media.DATA) );
// Load image from path
return BitmapFactory.decodeFile( photoFilePath, null );
}
} finally {
if ( photoCursor != null ) {
photoCursor.close();
}
}
return null;
}
自分の携帯電話を含む一部のAndroidデバイスで見られる問題は、クエリから取得したカーソルにonCreate()
、実際のフルサイズの画像ファイル(JPGまたはPNG)が欠落しているエントリがいくつか含まれていることです。(私の電話の場合、画像はインポートされ、その後iPhotoによって消去されました)。
孤立したエントリには、AWOL時に実際のメディアファイルの前にサムネイルが生成されたかどうかに応じて、サムネイルが含まれる場合と含まれない場合があります。その結果、アプリは実際には存在しない画像のサムネイルを表示します。
少し質問があります:
MediaStore
返されたメディアが欠落している画像を除外するコンテンツプロバイダーに対して行うことができるクエリはありますCursor
か?MediaStore
を強制的に再スキャンし、孤立したエントリを削除する手段またはAPIはありますか?私の電話では、USBにマウントしてから、外部メディアをアンマウントしました。これにより、再スキャンがトリガーされます。しかし、孤立したエントリは残ります。- それとも、この問題を引き起こしている私のアプローチに根本的に何か問題がありますか?
ありがとう。