Je suis en train d'offrir une Activité app qui affiche des vignettes de photos dans la du périphérique de stockage, et de permettre à l'utilisateur d'en choisir un. Après que l'utilisateur a fait une la sélection, l'application lit l'original de la taille de l'image et fait des choses avec elle.
J'utilise le code suivant pour créer un Cursor
sur toutes les images sur l'extérieur
stockage:
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.");
}
}
Et le code suivant pour charger l'image miniature (Android 2.x code est affiché):
// ...
// 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);
}
Et le code suivant pour charger l'image d'origine à partir de l'URL une fois que l'utilisateur effectue une sélection:
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;
}
Le problème que je vois sur certains appareils Android, y compris mon propre téléphone, c'est que l'
curseur-je obtenir à partir de la requête en onCreate()
contient quelques entrées pour lesquelles l'effectif complet de la taille de fichier image (JPG ou PNG) est manquant. (Dans le cas de mon téléphone, les images avaient été importés et, par la suite effacé par iPhoto).
Les orphelins entrées peuvent ou peuvent ne pas avoir les vignettes, selon que les vignettes où générés avant la réelle fichier de média lors de la AWOL. Le résultat final est que l'application affiche des vignettes pour les images qui n'existe pas réellement.
J'ai quelques questions:
- Est-il une requête que je peux apporter à l'
MediaStore
fournisseur de contenu qui filtre des images avec le manque de supports dans le retour de l'Cursor
? - Est-il un moyen ou une API pour forcer l'
MediaStore
afin de relancer l'analyse, et d'éliminer les entrées orphelines? Sur mon téléphone, j'USB-monté puis démonté le support externe, qui est censé déclencher une nouvelle analyse. Mais les entrées orphelines rester. - Ou est-il quelque chose de fondamentalement mauvais dans mon approche qui est à l'origine de ce problème?
Merci.