Ich versuche, eine In-App-Aktivität bereitzustellen, die Miniaturansichten von Fotos im Medienspeicher des Geräts anzeigt und dem Benutzer die Auswahl eines Mediums ermöglicht. Nachdem der Benutzer eine Auswahl getroffen hat, liest die Anwendung das ursprüngliche Bild in voller Größe und macht damit etwas.Wie wird der Android MediaStore Content Provider abgefragt, um verwaiste Bilder zu vermeiden?
ich den folgenden Code bin mit einem Cursor
über alle Bilder auf dem externen Speicher zu erstellen:
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.");
}
}
und den folgenden Code, um das Thumbnail-Bild zu laden (Android 2.x-Code wird angezeigt) :
// ...
// 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);
}
und der folgende Code, um das Originalbild aus der URL zu laden, sobald der Benutzer eine Auswahl trifft:
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;
}
Das Problem, das ich auf einigen Android-Geräten, einschließlich meines eigenen persönlichen Telefons sehe, ist, dass der Cursor, den ich von der Abfrage in onCreate()
erhalte, ein paar Einträge enthält, für die die tatsächliche Bilddatei in voller Größe (JPG oder PNG) wird vermisst. (Im Fall meines Telefons wurden die Bilder importiert und anschließend von iPhoto gelöscht).
Die verwaisten Einträge können oder können keine Miniaturansichten haben, abhängig davon, ob Miniaturbilder vor der eigentlichen Mediendatei generiert wurden, wenn AWOL. Das Ergebnis ist, dass die App Miniaturansichten für Bilder anzeigt, die nicht wirklich existieren.
Ich habe ein paar Fragen:
- Gibt es eine Abfrage, die ich an die
MediaStore
Content-Provider machen kann, die Bilder mit fehlenden Medien in den zurückCursor
herausfiltern? - Gibt es eine Möglichkeit, oder eine API, die
MediaStore
zum erneuten Scannen erzwingen und die verwaisten Einträge zu beseitigen? Auf meinem Handy habe ich USB-gemountet und dann das externe Medium abgehängt, welches einen Rescan auslösen soll. Die verwaisten Einträge bleiben jedoch erhalten. - Oder gibt es etwas grundsätzlich falsch mit meinem Ansatz, der dieses Problem verursacht?
Danke.