Unable to resume Activity when retrieving images from SD card
Asked Answered
N

3

12

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?

Neuritis answered 14/3, 2012 at 6:16 Comment(0)
G
41

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.

Graecize answered 14/3, 2012 at 6:46 Comment(5)
Your answer are right. But another activity of mine has the same error. The code like this https://mcmap.net/q/169517/-why-the-cursor-null . If did not call cursor.close(), the cousor will get null while run several loop. How to avoid it?Neuritis
@Neuritis Maybe the problems from your other question are because of the size of the operations you do. You do a full query of the MediaStore.Images.Media` for two columns, and then make several hundreds(or even over 1000) managedQuery to get the thumbnails(also if you want the thumbnail shouldn't you query the MediaStore.Images.Thumbnails contentprovider?). Also you say that the cursor is sometimes null, but wouldn't calling close on the cursor throw a NullPointerException?Graecize
For example, I have 2000 photo. The for loop from 1 to 1000 works but more then 1000 will get null. If use NullPointerException may cause several photo did not be open.Neuritis
@Neuritis I don't know why that happens. Maybe you could try a new approach and avoid the issue.Graecize
OK, reduce the cursor call seems the only method. Thanks anyway.Neuritis
P
1

remove cursor.close(); in your code it work fine definitely

Premises answered 9/2, 2017 at 11:20 Comment(0)
D
1

Function, managedQuery() is deprecated.

Please use getContentResolver().query().

The parameters is the same.

Decadence answered 31/3, 2017 at 6:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.