Android-MediaStore.Video.query()返回null [英] Android - MediaStore.Video.query() is returning 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屋!