2010-09-09 44 views
36

Tôi đang cố gắng cung cấp Hoạt động trong ứng dụng hiển thị hình thu nhỏ của ảnh trong cửa hàng phương tiện của thiết bị và cho phép người dùng chọn một. Sau khi người dùng thực hiện lựa chọn , ứng dụng sẽ đọc hình ảnh có kích thước đầy đủ gốc và thực hiện mọi thứ với nó.Cách truy vấn Nhà cung cấp nội dung Android MediaStore, tránh hình ảnh mồ côi?

Tôi đang sử dụng đoạn mã sau để tạo ra một Cursor trên tất cả các hình ảnh trên bên ngoài lưu trữ:

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

Và đoạn mã sau để tải các hình ảnh thu nhỏ (mã Android 2.x được hiển thị) :

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

Và đoạn mã sau để tải ảnh gốc từ URL khi người dùng thực hiện một lựa chọn:

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

Sự cố tôi thấy trên một số thiết bị Android, bao gồm điện thoại cá nhân của mình, là con trỏ tôi nhận được từ truy vấn trong onCreate() chứa một số mục nhập có tệp hình ảnh có kích thước thật (JPG hoặc PNG) bị thiếu. (Trong trường hợp điện thoại của tôi, hình ảnh đã được nhập và sau đó bị xóa bởi iPhoto).

Các mục nhập mồ côi có thể có hoặc không có hình thu nhỏ, tùy thuộc vào hình thu nhỏ được tạo trước tệp phương tiện thực khi AWOL. Kết quả cuối cùng là ứng dụng hiển thị hình thu nhỏ cho hình ảnh không thực sự tồn tại.

Tôi có một vài câu hỏi:

  1. Có một truy vấn tôi có thể thực hiện với các nhà cung cấp nội dung MediaStore rằng sẽ lọc ra hình ảnh với thiếu phương tiện truyền thông trong trở Cursor?
  2. Có phương tiện hay API để buộc MediaStore quét lại và loại bỏ các mục nhập mồ côi không? Trên điện thoại của tôi, tôi gắn USB rồi tháo gắn phương tiện bên ngoài, phương tiện này được kích hoạt để quét lại. Nhưng những đứa trẻ mồ côi vẫn còn.
  3. Hoặc có điều gì đó sai về cơ bản với cách tiếp cận của tôi gây ra sự cố này không?

Cảm ơn.

Trả lời

60

OK, tôi đã tìm thấy sự cố với mẫu mã này.

Trong phương pháp onCreate(), tôi đã có dòng này:

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

Vấn đề ở đây là nó truy vấn cho các hình nhỏ, chứ không phải là những hình ảnh thực tế. Ứng dụng máy ảnh trên thiết bị HTC không tạo hình thu nhỏ theo mặc định và do đó truy vấn này sẽ không trả về hình ảnh chưa được tính toán hình thu nhỏ.

Thay vào đó, truy vấn cho những hình ảnh thực tế bản thân:

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

này sẽ trả về một con trỏ chứa tất cả những hình ảnh kích thước đầy đủ trên hệ thống.Sau đó, bạn có thể gọi:

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

sẽ trả lại hình thu nhỏ có kích thước trung bình cho hình ảnh có kích thước đầy đủ, tạo nó nếu cần. Để có hình thu nhỏ có kích thước vi mô, chỉ cần sử dụng MediaStore.Images.Thumbnails.MICRO_KIND thay thế.

Điều này cũng giải quyết được vấn đề tìm hình thu nhỏ có tham chiếu treo lơ lửng với hình ảnh có kích thước đầy đủ gốc.

7

Xin lưu ý rằng mọi thứ sẽ sớm thay đổi, phương thức managedQuery không được chấp nhận. Sử dụng CursorLoader thay vì (kể từ api cấp 11).

Các vấn đề liên quan