Android - MediaStore.Video.query() is returning null

后端 未结 2 1993
南笙
南笙 2020-12-18 04:52

I\'m trying to retrieve the metadata from a video file (title, language, artist) using the method MediaStore.Video.query(). However, the method is always returning null. The

相关标签:
2条回答
  • 2020-12-18 05:09

    Uri.parse("content://mnt/sdcard/Movies/landscapes.mp4") is not an Uri for MediaStore. It would try to find a ContentProvider for authority mnt which does not exist.

    MediaStore can handle only content://media/... Uris which you should get exclusively via MediaStore, not by using Uri.parse().

    In your case use the following for example

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

    The MediaStore.Video.VideoColumns.DATA field holds the path to the videos and you search for a certain video this way. At least for now, future versions of Android may change that.


    Your second example is using CursorLoader the wrong way. If you call loader.loadInBackground() yourself, you load the data in foreground. See e.g. http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/

    The next thing you do is

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

    This will lead to a CursorIndexOutOfBoundsException if your cursor has 0 rows and cursor.moveToFirst() failed because there is no first row. The cursor stays before the first row (at -1) and that index does not exist. That would mean in your case that the file was not found in the database.

    To prevent that use the return value of moveToFirst - it will only be true if there is a first row.

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

    A more complete example including checks for null and closing the cursor in all cases

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

    I guess the file you try to find is either not indexed in the database (rebooting forces the indexer to run again) or the path is wrong.

    Or the path you use is actually a symlink in which case MediaStore might use a different path.

    Use this to get rid of symlinks

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

    Yes, I tested now and it is throwing IndexOutOfBoundsException. When I'm using cursor.getColumnCount() it returns 1

    cursor.getColumnCount() is the column count, not the row count. It should always be the same as the number of columns you requested in columns. You need to check cursor.getCount() if you want to check the row count.


    Try dumping all the videos known to MediaStore into logcat in case it does not show as expected.

    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 讨论(0)
  • 2020-12-18 05:11

    I updated your code, it works, just check it

    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);
    }
    
    0 讨论(0)
提交回复
热议问题