2012-11-28 44 views
5

Tôi đang cố truy xuất siêu dữ liệu từ tệp video (tiêu đề, ngôn ngữ, nghệ sĩ) bằng phương thức MediaStore.Video.query(). Tuy nhiên, phương thức luôn trả về null. Mã bên dưới:Android - MediaStore.Video.query() trả về null

String[] columns = { 
    MediaStore.Video.VideoColumns._ID, 
    MediaStore.Video.VideoColumns.TITLE, 
    MediaStore.Video.VideoColumns.ARTIST 
}; 

Cursor cursor = MediaStore.Video.query(getApplicationContext().getContentResolver(), videoUri,columns); 

if (cursor != null) { 
    cursor.moveToNext(); 
} 

String title = cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.TITLE)); 

Bất kỳ đề xuất nào về cách trả về siêu dữ liệu video bằng Android?

Cập nhật ==

Như tôi đã tìm kiếm ở nhiều nơi, tôi đã cố gắng một giải pháp sử dụng CursorLoader. Tuy nhiên, phương thức loadInBackground() từ CursorLoader cũng trả về null. Mã được hiển thị bên dưới:

String[] columns = { 
       MediaStore.Video.VideoColumns.TITLE 
     }; 

     Uri videoUri = Uri.parse("content://mnt/sdcard/Movies/landscapes.mp4"); 

     CursorLoader loader = new CursorLoader(getBaseContext(), videoUri, columns, null, null, null); 

     Cursor cursor = loader.loadInBackground(); 

     cursor.moveToFirst(); 

     String title = cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.TITLE)); 
+0

là những gì 'videoUri'? 'MediaStore.Video.Media.EXTERNAL_CONTENT_URI'? – zapl

Trả lời

13

Uri.parse("content://mnt/sdcard/Movies/landscapes.mp4") không phải là Uri cho MediaStore. Nó sẽ cố gắng tìm một số ContentProvider cho quyền hạn mnt không tồn tại.

MediaStore chỉ có thể xử lý content://media/... Uris mà bạn sẽ nhận được độc quyền qua MediaStore, không phải bằng cách sử dụng Uri.parse().

Trong trường hợp bạn sử dụng sau đây ví dụ

Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 
String[] columns = { 
     MediaStore.Video.VideoColumns._ID, 
     MediaStore.Video.VideoColumns.TITLE, 
     MediaStore.Video.VideoColumns.ARTIST 
    }; 

String selection = MediaStore.Video.VideoColumns.DATA + "=?"; 
String selectionArgs[] = { "/mnt/sdcard/Movies/landscapes.mp4" }; 

Cursor cursor = context.getContentResolver().query(uri, columns, selection, selectionArgs, null); 

Trường MediaStore.Video.VideoColumns.DATA giữ đường dẫn đến video và bạn tìm kiếm một video nào đó theo cách này. Ít nhất là bây giờ, các phiên bản tương lai của Android có thể thay đổi điều đó.


Ví dụ thứ hai của bạn đang sử dụng CursorLoader sai cách. Nếu bạn tự gọi loader.loadInBackground(), bạn nạp dữ liệu vào nền trước. Xem ví dụ http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/

Điều tiếp theo bạn cần làm là

Cursor cursor = getCursor(); 
    cursor.moveToFirst(); 
    String title = cursor.getString(/* some index */); 

này sẽ dẫn đến một CursorIndexOutOfBoundsException nếu cursor có 0 hàng và cursor.moveToFirst() bạn không thành công vì không có hàng đầu tiên. Con trỏ nằm trước hàng đầu tiên (tại -1) và chỉ mục đó không tồn tại. Điều đó có nghĩa là trong trường hợp của bạn tập tin không được tìm thấy trong cơ sở dữ liệu.

Để ngăn điều đó sử dụng giá trị trả lại là moveToFirst - nó sẽ chỉ là true nếu có hàng đầu tiên.

Cursor cursor = getCursor(); // from somewhere 
    if (cursor.moveToFirst()) { 
     String title = cursor.getString(/* some index */); 
    } 

Một ví dụ hoàn chỉnh hơn bao gồm cả kiểm tra các null và đóng cursor trong mọi trường hợp

Cursor cursor = getCursor(); // from somewhere 
    String title = "not found"; 
    if (cursor != null) { 
     if (cursor.moveToFirst()) { 
      title = cursor.getString(/* some index */); 
     } 
     cursor.close(); 
    } 

Tôi đoán các tập tin bạn cố gắng để tìm được một trong hai không lập chỉ mục trong cơ sở dữ liệu (khởi động lại lực lượng indexer để chạy lại) hoặc đường dẫn sai.

Hoặc đường dẫn bạn sử dụng thực sự là một liên kết tượng trưng trong trường hợp đó MediaStore có thể sử dụng một đường dẫn khác.

Sử dụng này để thoát khỏi symlink

String path = "/mnt/sdcard/Movies/landscapes.mp4"; 
    try { 
     path = new File(path).getCanonicalPath(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

Vâng, tôi đã kiểm tra ngay bây giờ và nó được ném IndexOutOfBoundsException. Khi tôi đang sử dụng cursor.getColumnCount(), nó trả về 1

cursor.getColumnCount() là số cột, không phải là số hàng. Nó phải luôn giống với số cột bạn yêu cầu trong columns. Bạn cần phải kiểm tra cursor.getCount() nếu bạn muốn kiểm tra số lượng hàng.


Hãy thử đổ tất cả các video đã biết cho MediaStore thành logcat trong trường hợp nó không hiển thị như mong đợi.

public static void dumpVideos(Context context) { 
    Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 
    String[] projection = { MediaStore.Video.VideoColumns.DATA }; 
    Cursor c = context.getContentResolver().query(uri, projection, null, null, null); 
    int vidsCount = 0; 
    if (c != null) { 
     vidsCount = c.getCount(); 
     while (c.moveToNext()) { 
      Log.d("VIDEO", c.getString(0)); 
     } 
     c.close(); 
    } 
    Log.d("VIDEO", "Total count of videos: " + vidsCount); 
} 
+0

Con trỏ đang trở về khác với null. Tuy nhiên, khi tôi đang gọi "cursor.getString (cursor.getColumnIndex (MediaStore.Video.VideoColumns.TITLE))" nó ném một NullPointerException. –

+0

@DaniloSantos nếu dòng đó đang ném NPE thì 'con trỏ' là' null'. Bạn có chắc chắn rằng nó không phải là một số 'IndexOutOfBoundsException'? – zapl

+0

Có, tôi đã thử nghiệm ngay bây giờ và nó đang ném 'IndexOutOfBoundsException'. Khi tôi đang sử dụng 'cursor.getColumnCount()' nó trả về ** 1 **. –

2

tôi cập nhật mã của bạn, nó hoạt động, chỉ cần kiểm tra xem nó

public static void dumpVideos(Context context) { 
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 
String[] projection = { MediaStore.Video.VideoColumns.DATA }; 
Cursor c = context.getContentResolver().query(uri, projection, null, null, null); 
int vidsCount = 0; 
if (c != null) { 
    c.moveToFirst(); 
    vidsCount = c.getCount(); 
    do { 
     Log.d("VIDEO", c.getString(0)); 
    }while (c.moveToNext()); 
    c.close(); 
} 
Log.d("VIDEO", "Total count of videos: " + vidsCount); 
} 
Các vấn đề liên quan