如何查询的Andr​​oid MediaStore内容提供商,避免孤立的图片?孤立、提供商、内容、图片

2023-09-12 21:54:05 作者:简简单单╰'

我想提供一个在应用程序的活动这在显示照片缩略图 设备的媒体商店,并允许用户选择一个。用户进行之后一个 选择时,应用程序会读取原来的全尺寸图像和做的事情。

I'm trying to provide an in-app Activity which displays thumbnails of photos in the device's media store, and allow the user to select one. After the user makes a selection, the application reads the original full-size image and does things with it.

我用下面的code在外部的所有图像来创建一个光标 存储:

I'm using the following code to create a Cursor over all the images on the external storage:

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.");
    }
}

和以下code加载缩略图(安卓2.X code表示):

And the following code to load the thumbnail image (Android 2.x code is shown):

// ...
// 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);
}

和以下code,一旦用户进行选择加载从URL中的原始图像:

And the following code to load the original image from the URL once the user makes a selection:

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擦除)。

The problem I'm seeing on some Android devices, including my own personal phone, is that the cursor I get from the query in onCreate() contains a few entries for which the actual full-sized image file (JPG or PNG) is missing. (In the case of my phone, the images had been imported and subsequently erased by iPhoto).

的孤立条目可以或可以不具有缩略图,根据是否在实际的媒体文件时之前擅离职守生成缩略图。最终的结果是,该应用显示缩略图实际上不存在的图像。

The orphaned entries may or may not have thumbnails, depending upon whether thumbnails where generated before the actual media file when AWOL. The end result is that the app displays thumbnails for images that don't actually exist.

我有几个问题:

有一个查询我可以对 MediaStore 内容提供商将过滤掉 在返回的光标?缺少的媒体形象 有没有一种方式,或API强制 MediaStore 来重新扫描,并消除孤儿作品?在我的手机,我USB安装,然后卸载了外部媒体,这应该是触发重新扫描。但是,孤儿项保持不变。 或者是有什么根本性的错误与我的做法是造成这个问题? Is there a query I can make to the MediaStore content provider that will filter out images with missing media in the returned Cursor? Is there a means, or an API to force the MediaStore to rescan, and eliminate the orphan entries? On my phone, I USB-mounted then unmounted the external media, which is supposed to trigger a rescan. But the orphan entries remain. Or is there something fundamentally wrong with my approach that's causing this problem?

感谢。

推荐答案

好了,我已经找到了问题,这个code样品。

Okay, I've found the problem with this code sample.

的onCreate()的方法,我有这样一行:

In the onCreate() method, I had this line:

mImageCursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
                             projection, selection, selectionArgs, null );

这里的问题是,它的查询的缩略图,而不是实际的图像。在HTC设备上的相机应用默认不创建缩略图,因此该查询将无法返回还没有缩略图计算图像。

The problem here is that it's querying for the thumbnails, rather than the actual images. The camera app on HTC devices does not create thumbnails by default, and so this query will fail to return images that do not already have thumbnails calculated.

相反,查询实际图像本身:

Instead, query for the actual images themselves:

mImageCursor = managedQuery( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                             projection, selection, selectionArgs, null );

这将返回一个包含所有系统上的全尺寸图像的光标。然后,您可以拨打:

This will return a cursor containing all the full-sized images on the system. You can then call:

Bitmap bm = MediaStore.Images.Thumbnails.getThumbnail(context.getContentResolver(),
        imageId, MediaStore.Images.Thumbnails.MINI_KIND, null);

这将返回中型缩略图关联的完整大小的图片,生成,如果有必要的。要获得微小尺寸的缩略图,只要使用 MediaStore.Images.Thumbnails.MICRO_KIND 代替。

此也解决发现有悬挂提到原始全尺寸图像的缩略图的问题

This also solved the problem of finding thumbnails that have dangling references to the original full-sized images.