Uri.parse("content://mnt/sdcard/Movies/landscapes.mp4")
は の Uri ではありませんMediaStore
。存在しないContentProvider
for 権限を見つけようとします。mnt
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
パスが保持され、この方法で特定の動画を検索します。少なくとも今のところ、Android の将来のバージョンでそれが変わる可能性があります。
2番目の例は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 */);
これは、行が 0で、最初の行がないために失敗したCursorIndexOutOfBoundsException
場合につながります。カーソルは最初の行の前 (-1) にとどまり、そのインデックスは存在しません。これは、ファイルがデータベースで見つからなかったことを意味します。cursor
cursor.moveToFirst()
それを防ぐには、最初の行がある場合に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);
}