2012-11-28 15 views
5

Sto cercando di recuperare i metadati da un file video (titolo, lingua, artista) utilizzando il metodo MediaStore.Video.query(). Tuttavia, il metodo restituisce sempre null. Il codice è sotto:Android - MediaStore.Video.query() restituisce 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)); 

Qualsiasi suggerimento su come restituire il video metadati utilizzando Android?

Aggiornamento ==

Come ho cercato in molti posti, ho provato uno soluzione utilizzando CursorLoader. Tuttavia, il metodo loadInBackground() da CursorLoader restituisce anche null. Il codice viene mostrato sotto:

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

ciò che è 'videoUri'? 'MediaStore.Video.Media.EXTERNAL_CONTENT_URI'? – zapl

risposta

13

Uri.parse("content://mnt/sdcard/Movies/landscapes.mp4") non è un URI per MediaStore. Proverebbe a trovare un ContentProvider per l'autorizzazione mnt che non esiste.

MediaStore può gestire solo content://media/... Uris che si dovrebbe ottenere esclusivamente tramite MediaStore, non utilizzando Uri.parse().

Nel tuo caso utilizzare il seguente ad esempio

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

Il campo MediaStore.Video.VideoColumns.DATA detiene il percorso per i video e si cerca un determinato video in questo modo. Almeno per ora, versioni future di Android potrebbero cambiarlo.


Il secondo esempio è utilizzando CursorLoader nel modo sbagliato. Se chiami tu stesso lo loader.loadInBackground(), carichi i dati in primo piano. Vedi per es. http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/

La prossima cosa che devi fare è

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

Questo porterà a un CursorIndexOutOfBoundsException se i vostri cursor ha 0 righe e cursor.moveToFirst() fallito perché non c'è prima fila. Il cursore rimane prima della prima riga (a -1) e quell'indice non esiste. Ciò significherebbe nel tuo caso che il file non è stato trovato nel database.

Per evitare che utilizzare il valore di ritorno di moveToFirst - sarà solo true se c'è una prima riga.

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

Un più completo esempio compresi i controlli per null e chiusura del cursor in tutti i casi

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

Credo che il file si tenta di trovare o non è indicizzato nel database (il riavvio forze l'indicizzatore di eseguire di nuovo) o il percorso è sbagliato.

Oppure il percorso che si utilizza è in realtà un collegamento simbolico nel qual caso MediaStore potrebbe utilizzare un percorso diverso.

Utilizzare questo per sbarazzarsi di link simbolici

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

Sì, ho provato ora e sta gettando IndexOutOfBoundsException. Quando sto usando cursor.getColumnCount() restituisce 1

cursor.getColumnCount() è il numero di colonne, non il conteggio delle righe. Dovrebbe essere sempre uguale al numero di colonne richiesto in columns. È necessario controllare cursor.getCount() se si desidera controllare il conteggio delle righe.


Prova di dumping tutti i video noti per MediaStore in logcat nel caso in cui non mostra come previsto.

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

Il cursore sta tornando diverso da null. Tuttavia, quando chiamo "cursor.getString (cursor.getColumnIndex (MediaStore.Video.VideoColumns.TITLE))" lancia una NullPointerException. –

+0

@DaniloSantos se quella linea sta lanciando NPE allora 'cursor' è' null'. Sei sicuro che non sia un po 'di "IndexOutOfBoundsException"? – zapl

+0

Sì, l'ho provato ora e lancia "IndexOutOfBoundsException". Quando sto usando 'cursor.getColumnCount()' restituisce ** 1 **. –

2

ho aggiornato il codice, funziona, basta controllare

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