Uri.parse("content://mnt/sdcard/Movies/landscapes.mp4")
không phải là Uri cho MediaStore
. Nó sẽ cố gắng tìm một số ContentProvider
cho quyền hạn mnt
không tồn tại.
MediaStore
chỉ có thể xử lý content://media/...
Uris mà bạn sẽ nhận được độc quyền qua MediaStore
, không phải bằng cách sử dụng Uri.parse()
.
Trong trường hợp bạn sử dụng sau đây ví dụ
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);
Trường MediaStore.Video.VideoColumns.DATA
giữ đường dẫn đến video và bạn tìm kiếm một video nào đó theo cách này. Ít nhất là bây giờ, các phiên bản tương lai của Android có thể thay đổi điều đó.
Ví dụ thứ hai của bạn đang sử dụng CursorLoader
sai cách. Nếu bạn tự gọi loader.loadInBackground()
, bạn nạp dữ liệu vào nền trước. Xem ví dụ http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/
Điều tiếp theo bạn cần làm là
Cursor cursor = getCursor();
cursor.moveToFirst();
String title = cursor.getString(/* some index */);
này sẽ dẫn đến một CursorIndexOutOfBoundsException
nếu cursor
có 0 hàng và cursor.moveToFirst()
bạn không thành công vì không có hàng đầu tiên. Con trỏ nằm trước hàng đầu tiên (tại -1) và chỉ mục đó không tồn tại. Điều đó có nghĩa là trong trường hợp của bạn tập tin không được tìm thấy trong cơ sở dữ liệu.
Để ngăn điều đó sử dụng giá trị trả lại là moveToFirst
- nó sẽ chỉ là true
nếu có hàng đầu tiên.
Cursor cursor = getCursor(); // from somewhere
if (cursor.moveToFirst()) {
String title = cursor.getString(/* some index */);
}
Một ví dụ hoàn chỉnh hơn bao gồm cả kiểm tra các null
và đóng cursor
trong mọi trường hợp
Cursor cursor = getCursor(); // from somewhere
String title = "not found";
if (cursor != null) {
if (cursor.moveToFirst()) {
title = cursor.getString(/* some index */);
}
cursor.close();
}
Tôi đoán các tập tin bạn cố gắng để tìm được một trong hai không lập chỉ mục trong cơ sở dữ liệu (khởi động lại lực lượng indexer để chạy lại) hoặc đường dẫn sai.
Hoặc đường dẫn bạn sử dụng thực sự là một liên kết tượng trưng trong trường hợp đó MediaStore có thể sử dụng một đường dẫn khác.
Sử dụng này để thoát khỏi symlink
String path = "/mnt/sdcard/Movies/landscapes.mp4";
try {
path = new File(path).getCanonicalPath();
} catch (IOException e) {
e.printStackTrace();
}
Vâng, tôi đã kiểm tra ngay bây giờ và nó được ném IndexOutOfBoundsException. Khi tôi đang sử dụng cursor.getColumnCount(), nó trả về 1
cursor.getColumnCount()
là số cột, không phải là số hàng. Nó phải luôn giống với số cột bạn yêu cầu trong columns
. Bạn cần phải kiểm tra cursor.getCount()
nếu bạn muốn kiểm tra số lượng hàng.
Hãy thử đổ tất cả các video đã biết cho MediaStore thành logcat trong trường hợp nó không hiển thị như mong đợi.
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);
}
là những gì 'videoUri'? 'MediaStore.Video.Media.EXTERNAL_CONTENT_URI'? – zapl