Android-MediaStore.Video.query()返回null [英] Android - MediaStore.Video.query() is returning null

查看:171
本文介绍了Android-MediaStore.Video.query()返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用MediaStore.Video.query()方法从视频文件(标题,语言,艺术家)中检索元数据.但是,该方法始终返回null.代码如下:

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 code is bellow:

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返回视频元数据的任何建议?

Any suggestion about how to return video metadata using android?

==更新

当我在许多地方搜索时,我使用CursorLoader尝试了一种解决方案.但是,来自CursorLoader的loadInBackground()方法也返回null.代码显示如下:

As I searched in many places, I tried one solution using CursorLoader. However, the method loadInBackground() from CursorLoader is also returning null. The code is showed bellow:

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

推荐答案

Uri.parse("content://mnt/sdcard/Movies/landscapes.mp4")不是MediaStore的Uri.它将尝试为权限mnt找到一个不存在的ContentProvider.

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只能处理content://media/... Uris,您只能通过MediaStore而不是通过Uri.parse()来获取.

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

MediaStore.Video.VideoColumns.DATA字段保存视频的路径,您可以通过这种方式搜索特定的视频.至少到目前为止,未来的Android版本可能会对此进行更改.

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.

您的第二个示例错误地使用了CursorLoader.如果您自己调用loader.loadInBackground(),则会将数据加载到前台.参见例如 http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/

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/

接下来要做的是

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

如果您的cursor有0行并且cursor.moveToFirst()由于没有第一行而失败,这将导致CursorIndexOutOfBoundsException.光标停留在第一行之前(-1),并且该索引不存在.在您的情况下,这意味着在数据库中找不到该文件.

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.

为防止使用该值,请使用moveToFirst的返回值-仅在有第一行的情况下才为true.

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

一个更完整的示例,包括检查null并在所有情况下关闭cursor

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.

或者您使用的路径实际上是符号链接,在这种情况下,MediaStore可能使用其他路径.

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

使用它摆脱符号链接

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


是的,我现在进行了测试,并且它抛出IndexOutOfBoundsException.当我使用cursor.getColumnCount()时,它返回1

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

cursor.getColumnCount()是列数,而不是行数.它应始终与您在columns中请求的列数相同.如果要检查行数,则需要检查cursor.getCount().

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.

尝试将MediaStore已知的所有视频转储到logcat中,以防它们未能按预期显示.

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

这篇关于Android-MediaStore.Video.query()返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆