2012-11-28 152 views
5

我試圖使用MediaStore.Video.query()方法從視頻文件(標題,語言,藝術家)檢索元數據。但是,該方法始終返回null。代碼是波紋管:Android - MediaStore.Video.query()返回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)); 

任何有關如何使用android返回視頻元數據的建議?

==更新

正如我搜索在很多地方,我用CursorLoader嘗試一種解決方案。但是,CursorLoader的loadInBackground()方法也返回null。該代碼是波紋管顯示:

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

是什麼'videoUri'? 'MediaStore.Video.Media.EXTERNAL_CONTENT_URI'? – zapl

回答

13

Uri.parse("content://mnt/sdcard/Movies/landscapes.mp4")不是MediaStore的URI。它會嘗試找到ContentProvider,對於不存在的權威mnt

MediaStore只能處理content://media/...只能通過MediaStore獲取的Uris,而不能使用Uri.parse()

在您的情況使用以下例如

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

MediaStore.Video.VideoColumns.DATA字段保存的路徑,視頻和您搜索某個視頻這種方式。至少現在,未來的Android版本可能會改變這一點。


你的第二個例子是以錯誤的方式使用CursorLoader。如果您自己調用loader.loadInBackground(),則會在前臺加載數據。見例如http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/

你做的下一件事是

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

這將導致CursorIndexOutOfBoundsException如果您cursor有0行和cursor.moveToFirst()失敗,因爲沒有第一行。光標停留在第一行之前(在-1處)並且該索引不存在。這意味着在你的情況下,該數據庫中找不到該文件。

要防止使用返回值moveToFirst - 如果有第一行,它將僅爲true

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

一個更完整的示例包括檢查null和關閉在所有情況下cursor

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

我猜你試圖找到或者未在數據庫索引(重啓力索引的文件再次運行)或路徑錯誤。

或者您使用的路徑實際上是符號鏈接,在這種情況下MediaStore可能會使用不同的路徑。

使用此擺脫符號鏈接

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

是的,我測試的現在,它是扔IndexOutOfBoundsException異常。當我使用cursor.getColumnCount()時,它返回1

cursor.getColumnCount()是列計數,而不是行計數。它應該始終與您在columns中請求的列數相同。如果您想檢查行數,您需要檢查cursor.getCount()


傾銷嘗試已知的所有MediaStore到logcat中的情況下,預期它不顯示視頻。

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

遊標返回與null不同。但是,當我調用「cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.TITLE))」時,它會引發NullPointerException。 –

+0

@DaniloSantos如果該行正在拋出NPE,則'cursor'爲'null'。你確定它不是'IndexOutOfBoundsException'嗎? – zapl

+0

是的,我現在測試並拋出'IndexOutOfBoundsException'。當我使用'cursor.getColumnCount()'時,它返回** 1 **。 –

2

我更新了你的代碼,它的工作原理,只是檢查

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