My goal is to read complete contact information on an Android application. This is very slow and my understanding is that since the contacts are stored locally in a phone database, it shouldn't take long to fetch complete contact details.public void readContacts() {    Log.d(TAG,  -> Into readContacts);    // Get the ContentResolver    ContentResolver cr = getContentResolver();    // Get the Cursor of all the contacts    Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);    // Move the cursor to first. Also check whether the cursor is empty or not.    if (cursor.moveToFirst()) {        // Iterate through the cursor        do {            // Get the contacts name            Contact contactToSave = new Contact();            contactToSave.setIsUploaded(false);            String id = cursor.getString(cursor.getColumnIndex(                    ContactsContract.Contacts._ID));            Log.d(TAG,  ID  + id);            String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));            contactToSave.setFirstName(name);            Log.d(TAG,  Complete Name  + name);            String orgWhere = ContactsContract.Data.CONTACT_ID +  = ? AND  + ContactsContract.Data.MIMETYPE +  = ?;            String[] orgWhereParams = new String[]{id,                    ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE};            Cursor orgCur = cr.query(ContactsContract.Data.CONTENT_URI, null, orgWhere, orgWhereParams, null);            if (orgCur.moveToFirst()) {                String orgName = orgCur.getString(orgCur.getColumnIndex(ContactsContract.CommonDataKinds.Organization.DATA));                String title = orgCur.getString(orgCur.getColumnIndex(ContactsContract.CommonDataKinds.Organization.TITLE));                contactToSave.setCompany(orgName);            }            orgCur.close();            Cursor emailCur = cr.query(                    ContactsContract.CommonDataKinds.Email.CONTENT_URI,                    null,                    ContactsContract.CommonDataKinds.Email.CONTACT_ID +  = ?,                    new String[]{id}, null);            while (emailCur.moveToNext()) {                // This would allow you get several email addresses                // if the email addresses were stored in an array                String email = emailCur.getString(                        emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));                contactToSave.setEmail(email);            }            emailCur.close();            if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(                    ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {                Cursor pCur = cr.query(                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,                        null,                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID +  = ?,                        new String[]{id}, null);                while (pCur.moveToNext()) {                    String phoneNumber = pCur.getString(pCur.getColumnIndex(                            ContactsContract.CommonDataKinds.Phone.NUMBER));                    contactToSave.setPhone(phoneNumber);                }                pCur.close();            }            mAdapter.add(contactToSave);        } while (cursor.moveToNext());        mAdapter.sort(new Comparator<Contact>() {            @Override            public int compare(Contact o1, Contact o2) {                return o1.getFirstName().compareTo(o2.getFirstName());            }        });    }    // Close the cursor    cursor.close();}I think creating multiple cursors for different data may be a performance overhead. Is there any way those can be combined? Is there any other way to fetch the cursor than running multiple queries using multiple cursors? If the answer for the above two questions are negative, then is this the best way possible for such a simple requirement?
Reading complete contact information in Android
java;android;cursor;google contacts api
Use AsyncQueryHandler, a helper class to help make handling asynchronous ContentResolver queries easier.It basically wraps the ContentResolver object and handles background execution of its operations (CRUD) as well as passing messages (result) from the between threads (background and main/UI).Just use to call the queryHandler.startQuery method and you will get callback in onQueryComplete method.Exampleclass QueryHandler extends AsyncQueryHandler {        public QueryHandler(ContentResolver cr) {            super(cr);        }        @Override        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {            switch (token) {                case CONTACT_QUERY://Do your stuff here                    if (cursor.moveToFirst()) {                        // Iterate through the cursor                        do {                            String id = cursor.getString(cursor.getColumnIndex(                                    ContactsContract.Contacts._ID));                            Log.e(TAG,  ID  + id);                        } while (cursor.moveToNext());                    }                    break;}}Use below method to fetch contact and add projection, selection according to your requirment.public void fetchContact(){        queryHandler.startQuery(CONTACT_QUERY, null, ContactsContract.Contacts.CONTENT_URI, null, null, null, null);    }