gpt4 book ai didi

Android - MediaStore.Video.query() 返回 null

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:26:34 24 4
gpt4 key购买 nike

我正在尝试使用 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));

最佳答案

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

MediaStore 只能处理 content://media/... Uris,你应该通过 MediaStore 获取它,而不是使用 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 字段包含视频的路径,您可以通过这种方式搜索某个视频。至少就目前而言, future 版本的 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 */);

如果您的 cursor 有 0 行并且 cursor.moveToFirst() 因为没有第一行而失败,这将导致 CursorIndexOutOfBoundsException。游标停留在第一行之前(-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();
}

我想您尝试查找的文件没有在数据库中建立索引(重新启动会强制索引器再次运行)或路径错误。

或者您使用的路径实际上是一个符号链接(symbolic link),在这种情况下 MediaStore 可能会使用不同的路径。

使用它来摆脱符号链接(symbolic link)

    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() 是列数,而不是行数。它应该始终与您在 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);
}

关于Android - MediaStore.Video.query() 返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13613443/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com