user934820
user934820

Reputation: 1178

Application did not close the cursor or database object android

I am trying to lookup for contact name by number from contacts book in an AsyncTask. Sometimes I get the following error which, I think, causes application crash. Any help please.

Logcat

08-05 09:00:49.627 24988-27371/com.fake.fake E/CursorLeakDetecter: PossibleCursorLeak:content://com.android.contacts/phone_lookup/%2B923310433708,QueryCounter:5
android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
    at android.content.ContentResolver.query(ContentResolver.java:323)
    at com.fake.fake.GV.getContactName(GV.java:177)
    at com.fake.fake.MySQLiteHelper.GetNumbers(MySQLiteHelper.java:361)
    at com.fake.fake.MainActivity$taskLoadContacts.doInBackground(MainActivity.java:930)
    at com.fake.fake.MainActivity$taskLoadContacts.doInBackground(MainActivity.java:921)
    at android.os.AsyncTask$2.call(AsyncTask.java:264)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
    at java.lang.Thread.run(Thread.java:856)

Retrieving contact numbers from database.

 public ArrayList<MyMessageDetails> GetNumbers(String query) {
        ArrayList<MyMessageDetails> numbers = new ArrayList<MyMessageDetails>();
        Cursor cursor = db.rawQuery(query, null);
        if (cursor != null && cursor.moveToFirst()) {
            do {
                MyMessageDetails item = new MyMessageDetails();
                item.setNumber(cursor.getString(0));
                String name = GV.getContactName(item.getNumber());    
                if (name == null) {
                    name = item.getNumber();
                }
                item.setName(name);
                item.setTime(cursor.getString(3));
                numbers.add(item);
            } while (cursor.moveToNext());

        }
        return numbers;
    }

Retrieving contact name.

 public static String getContactName(String phoneNumber) {
        if (phoneNumber != null) {
            ContentResolver cr = ApplicationContextProvider.getContext().getContentResolver();
            Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
            Cursor cursor = cr.query(uri, new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);
            if (cursor == null) {
                return "";
            }
            String contactName = null;
            if (cursor.moveToFirst()) {
                contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
            }

            if (cursor != null && !cursor.isClosed()) {
                cursor.close();
            }
            return contactName;
        }

        return phoneNumber;
    }

Upvotes: 1

Views: 950

Answers (2)

Kapil G
Kapil G

Reputation: 4141

So couple of issues i see here.

First of all, always surround your queries in a try catch finally block and close all cursor and db operations in finally block. So that for both your methods.

And I think what you are doing wrong here is first calling GetNumbers() method and after that getContactName(). Now you don't close db in GetNumbers() in the code and hence after that whatever operations you try to do on the db will give this error and hence error comes in getContactName()

Upvotes: 0

Anton Potapov
Anton Potapov

Reputation: 1275

Use Cursor#close() after you finish reading the data from it. Example:

Cursor cursor = ...
try {
    // fetch whatever you need here
} finally {
    cursor.close();
}

Upvotes: 2

Related Questions