where to close the cursor? - android

i have a cursor that I am using in the following code. But I want to close the cursor after it is used and no longer needed. The problem is that the cursor is used in the return statement, but I can't close it after the return statement because that is unreachable code. It is used in the return statement so I can't close it above that line. How do I close the cursor? This is not like the old managedQuery, I assume that you have to close it.
public String getPath(Uri uri) {
String[] projection = { MediaStore.Audio.Media.DATA };
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
// cursor.close() <--- not possible because it is unreachable code after return
}

You can assign it to a String object then close cursor and return it.
cursor.moveToFirst();
String result = cursor.getString(column_index);
cursor.close();
return result;

Would using a finally block work for you? I'm not experienced in your particular problem but could you put your cleanup in the finally block that would otherwise be bypassed by the return statement:
http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html
Just an idea! Don't shoot me if not!

Try - Finally to the rescue...
public String getPath(Uri uri) {
Cursor cursor = null;
try {
String[] projection = { MediaStore.Audio.Media.DATA };
cursor = getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
finally {
if (cursor != null)
cursor.close(); // close the cursor
}
}
NOTE
Just noted another answer below..
If you're inside an activity, you can call startManaginCursor() and pass the cursor instance so Android will manage its lifetime. If you don't have access to Android Application Context (ex: code is in a utility class) use above method. (and sprinkle a bit of some error handling ;) )

if (this.daoDatabase != null) {
final Cursor genericCursor = this.daoDatabase.query(this.tableName, null, null, null, null, null, orderByCriteria);
if (genericCursor != null) {
if (genericCursor.moveToFirst()) {
do {
// do stuff...
} while (genericCursor.moveToNext());
}
genericCursor.close();
}
}

Related

How to display the media title in a listview?

How can I get media titles from COntentResolver. i tried but it no works, i want to display media titles in my listView .
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null) {
int ind = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
do {
String T = cursor.getString(ind);
abcl.add(T);
Log.i("SOngName", T);
} while (cursor.moveToNext());
}
but this gives me error of IndexOutOfBondsExceptions, my error logcat is
please any one guide , thanks
well first of all you should go for Cursor Documentation in android . it will tell you that after using the cursor is not null check; you have to move cursor to the start of first row on incoming result set.
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null) {
if(cursor.MoveToFirst()){
int ind = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
do {
String T = cursor.getString(ind);
abcl.add(T);
Log.i("SOngName", T);
} while (cursor.moveToNext());
}
}

Cursor always returning null on query

I'm using an Intent to select a file from my Android device. When shown the Chooser, I select the Astro file manager and then procede to select a file (a video in this case).
I get back a URI (content://com.metago.astro.filecontent/file/file/sdcard/Download/video_video.mp4) and I'm trying to process it with the following:
Cursor cursor = null;
final String column = null;
final String[] projection = null;
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
// Never enters here because cursor always null
L.p("Hi!");
}
} catch (Exception e) {
L.p(e.getMessage()); // Never hit
} finally {
if (cursor != null)
cursor.close();
}
however cursor always returns null . Any idea why this happens?

EXCEPTION DETAILS: java.lang.IllegalStateException: Process 3188 Exceeded cursor quota 100, will kill it with Rom MIUI

I use this code to load thumbnail on Sdcard, something device work good, but with device use rom MIUI then it have problem
"EXCEPTION DETAILS:
java.lang.IllegalStateException: Process 3188 exceeded cursor quota 100, will kill it"
please help me fix it, thank you.
public static Bitmap getThumbnailByPath(ContentResolver cr, String path)
throws Exception {
String[] projection = { MediaStore.Images.Media._ID };
Cursor cursor = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection, MediaStore.Images.Media.DATA + "=?",
new String[] { path }, null);
if (cursor != null && cursor.moveToFirst()) {
long id = cursor.getLong(0);
return getThumbnailById(cr, id);
} else
cursor.close();
return null;
}
public static Bitmap getThumbnailById(ContentResolver cr, long idPhoto)
throws Exception {
return MediaStore.Images.Thumbnails.getThumbnail(cr, idPhoto,
MediaStore.Images.Thumbnails.MINI_KIND, options);
}
You must always close your cursors.
Use something like this:
Cursor cursor = ...;
try {
if (cursor.moveToFirst())
return getThumbnailById(cr, cursor.getLong(0));
else
return null;
} finally {
cursor.close();
}

How to get all videos on Android device

How can I get a list of all videos and their path that can be found on an Android device where is my app installed?
EDIT:
I am trying to make a simple video player, so the idea would be to display all the videos that can be found on the device and to play it on list item click.
Only problem is that i don't know how to get that info about videos, so I would be very thankful if someone can help me.
If someone is still looking for answer please Try this method. This method will return list of path of all media.
public ArrayList<String> getAllMedia() {
HashSet<String> videoItemHashSet = new HashSet<>();
String[] projection = { MediaStore.Video.VideoColumns.DATA ,MediaStore.Video.Media.DISPLAY_NAME};
Cursor cursor = getContext().getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection, null, null, null);
try {
cursor.moveToFirst();
do{
videoItemHashSet.add((cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA))));
}while(cursor.moveToNext());
cursor.close();
} catch (Exception e) {
e.printStackTrace();
}
ArrayList<String> downloadedList = new ArrayList<>(videoItemHashSet);
return downloadedList;
}
String[] projection = { MediaStore.Video.Media._ID};
Cursor cursor = new CursorLoader(contexts, MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection,
null, // Return all rows
null, null).loadInBackground();
after you have the cursor you can iterate it and get all videos using the video id.
Try following code.
private void getVideoList() {
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.Video.VideoColumns.DATA};
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
ArrayList<String> pathArrList = new ArrayList<>();
if (cursor != null) {
while (cursor.moveToNext()) {
pathArrList.add(cursor.getString(0));
}
cursor.close();
}
Log.e("all path",pathArrList.toString());
}

Does ContentResolver.query escape the arguments, or does it just replace the questionmarks?

Does ContentResolver.query escape the selection arguments?
For instance, should I manually escape the arguments in selArgs before doing something like
Cursor c = contentResolver.query(uri, null, "mimetype=?", selArgs, null);
or is it done by the query method?
No. You should do it manually in your content provider.
Source code of the query function:
public final Cursor query(Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
IContentProvider provider = acquireProvider(uri);
if (provider == null) {
return null;
}
try {
long startTime = SystemClock.uptimeMillis();
Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
if (qCursor == null) {
releaseProvider(provider);
return null;
}
// force query execution
qCursor.getCount();
long durationMillis = SystemClock.uptimeMillis() - startTime;
maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder);
// Wrap the cursor object into CursorWrapperInner object
return new CursorWrapperInner(qCursor, provider);
} catch (RemoteException e) {
releaseProvider(provider);
// Arbitrary and not worth documenting, as Activity
// Manager will kill this process shortly anyway.
return null;
} catch (RuntimeException e) {
releaseProvider(provider);
throw e;
}
}

Categories

Resources