我正在尝试从一个视频文件(标题,语言,艺术家)元数据使用方法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尝试一种解决方案。 然而,该方法loadInBackground()从CursorLoader也返回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
。 它会试图找到一个ContentProvider
权威mnt
不存在。
MediaStore
只能处理content://media/...
尤里斯你应该通过专门弄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
字段保存的路径,视频和您搜索某个视频这种方式。 至少从目前来看,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 */);
这将导致一个CursorIndexOutOfBoundsException
如果你的cursor
有0行和cursor.moveToFirst()
失败,因为没有第一行。 光标在第一行(在-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();
}
我猜你试图找到或者未在数据库索引(重启力索引再次运行)或路径是错误的文件。
或者你使用的路径实际上是在这种情况下MediaStore可能使用不同的路径的符号链接。
使用此摆脱符号链接
String path = "/mnt/sdcard/Movies/landscapes.mp4";
try {
path = new File(path).getCanonicalPath();
} catch (IOException e) {
e.printStackTrace();
}
是的,我现在测试,它抛出IndexOutOfBoundsException异常。 当我使用cursor.getColumnCount()返回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);
}
我更新了你的代码,它的工作原理,只是检查
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);
}