如何查询 Android MediaStore Content Provider,避免孤立图像? [英] How to query Android MediaStore Content Provider, avoiding orphaned images?

查看:27
本文介绍了如何查询 Android MediaStore Content Provider,避免孤立图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试提供一个应用内活动,它在设备的媒体商店,并允许用户选择一个.用户创建后选择,应用程序读取原始全尺寸图像并对其进行处理.

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.

我正在使用以下代码在外部的所有图像上创建一个 Cursor存储:

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

以及以下用于加载缩略图的代码(显示的是 Android 2.x 代码):

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

以下代码用于在用户进行选择后从 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).

孤立条目可能有也可能没有缩略图,这取决于缩略图是否在 AWOL 时在实际媒体文件之前生成.最终结果是该应用显示实际不存在的图像的缩略图.

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.

我有几个问题:

  1. 是否可以向 MediaStore 内容提供者进行查询以过滤掉返回的 Cursor 中缺少媒体的图像?
  2. 有没有办法或 API 来强制 MediaStore 重新扫描并消除孤立条目?在我的手机上,我安装了 USB,然后卸载了外部媒体,这应该会触发重新扫描.但孤立条目仍然存在.
  3. 或者我的方法有什么根本性的错误导致了这个问题?
  1. Is there a query I can make to the MediaStore content provider that will filter out images with missing media in the returned Cursor?
  2. 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.
  3. Or is there something fundamentally wrong with my approach that's causing this problem?

谢谢.

推荐答案

好的,我已经找到了这个代码示例的问题.

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 代替.

which will return the medium-sized thumbnail for the associated full-size image, generating it if necessary. To get the micro-sized thumbnail, just use MediaStore.Images.Thumbnails.MICRO_KIND instead.

这也解决了查找对原始全尺寸图像有悬空引用的缩略图的问题.

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

这篇关于如何查询 Android MediaStore Content Provider,避免孤立图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆