Search code examples
androidandroid-4.0-ice-cream-sandwichandroid-cursor

Unable to resume Activity when retrieving images from SD card


My Activity contains this code to get all images on the SD card:

String[] projection = {MediaStore.Images.Media._ID,
                       MediaStore.Images.Media.DATA,
                       MediaStore.Images.ImageColumns.DATA};  
Cursor cursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                             projection, null, null,
                             MediaStore.Images.Media._ID); 
int count = cursor.getCount();
int image_path_index = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
int i;
for(i = 0; i < count; i++) {
    cursor.moveToPosition(i);
    String p = cursor.getString(image_path_index);
    fd.addToPhonePhoto(p);
}
cursor.close();

The occurred while the Activity was resuming:

03-14 14:06:48.380: E/AndroidRuntime(20793): java.lang.RuntimeException: Unable to resume activity {}: java.lang.RuntimeException: Unable to resume activity {}: android.database.StaleDataException: Attempted to access a cursor after it has been closed.

It only occurs on Android 4.0. If on Android 2.x or 3.x, it works normally. But if I change the system setting which selects the "don't keep Activities" option in "Developer options". The error does not show.

I want to modify my code to avoid this error without changing the system setting. How should I do it?


Solution

  • I think this is because of the managedQuery call + you closing the cursor. From the docs of the managedQuery() method:

    Warning: Do not call close() on a cursor obtained using this method, because the activity will do that for you at the appropriate time. However, if you call stopManagingCursor(Cursor) on a cursor from a managed query, the system will not automatically close the cursor and, in that case, you must call close().

    Leave the cursor for the Android system to manage and don't call cursor.close();.

    Note: The managedQuery method is deprecated and it should be avoided, implement CursorLoaders instead. More info about CursorLoaders can be found at developer.android.com.