Sto provando a fornire un'attività in-app che visualizza le miniature delle foto nell'archivio multimediale del dispositivoe consentire all'utente di selezionarne una. Dopo che l'utente effettua una selezione da , l'applicazione legge l'immagine originale a dimensione intera e fa le cose con esso.Come interrogare il fornitore di contenuti MediaStore Android, evitando immagini orfane?
Sto utilizzando il seguente codice per creare un Cursor
su tutte le immagini sul esterno stoccaggio:
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.");
}
}
E il seguente codice per caricare l'immagine in miniatura (è mostrato il codice 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);
}
E il codice seguente per caricare l'immagine originale dall'URL una volta che l'utente effettua una selezione:
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;
}
Il problema riscontrato su alcuni dispositivi Android, incluso il mio telefono personale, è che il cursore che ottengo dalla query in onCreate()
contiene alcune voci per le quali il file immagine a grandezza originale (JPG o PNG) manca. (Nel caso del mio telefono, le immagini sono state importate e successivamente cancellate da iPhoto).
Le voci orfane possono o non possono avere miniature, a seconda se le miniature sono generate prima del file multimediale effettivo quando AWOL. Il risultato finale è che l'app visualizza miniature per immagini che in realtà non esistono.
ho alcune domande:
- C'è una domanda che posso fare per il fornitore di contenuti
MediaStore
che filtrare le immagini con i media mancante nel tornatoCursor
? - Esiste un mezzo o un'API per forzare la scansione di
MediaStore
ed eliminare le voci orfane? Sul mio telefono, ho montato su USB quindi smontato il supporto esterno, che dovrebbe attivare una nuova scansione. Ma le voci orfane rimangono. - Oppure c'è qualcosa di fondamentalmente sbagliato nel mio approccio che sta causando questo problema?
Grazie.