Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fetching contacts in android is very slow

I had written a code to fetch contact name, phone number and image from Contacts and to display it on a listview in android. It's working fine but taking more time to load. I had tried to use multi-threading in some parts of the code. But the loading time is not decreased.

Here is the onCreate() method:

protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 lvDetail = (ListView) findViewById(R.id.listView1);

 fetchcontacts();

 lvDetail.setAdapter(new MyBaseAdapter(context, myList));
 }

Here is the code for fetch contacts:

  private void fetchcontacts() {

        // TODO Auto-generated method stub
        Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,
                null, null, ContactsContract.Contacts.DISPLAY_NAME + " ASC");
                int count = cursor.getCount();
                if (count > 0) {
                     Toast.makeText(context, "count >0", Toast.LENGTH_SHORT).show();
                    while (cursor.moveToNext()) {
                        String columnId = ContactsContract.Contacts._ID;
                        int cursorIndex = cursor.getColumnIndex(columnId);
                        String id = cursor.getString(cursorIndex);

                      name = cursor.getString(cursor
                .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));


                      Toast.makeText(context, "Toast 1", Toast.LENGTH_SHORT).show();




                        int numCount = Integer.parseInt(cursor.getString(cursor
                            .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
                        if (numCount > 0) {
                             Toast.makeText(context, "Toast 2", Toast.LENGTH_SHORT).show();
                            Cursor phoneCursor = getContentResolver().query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,
                                CommonDataKinds.Phone.CONTACT_ID+" = ?", new String[] { id
                }, ContactsContract.Contacts.DISPLAY_NAME + " ASC");

                                while (phoneCursor.moveToNext()) {
                                     Toast.makeText(context, "Toast 3", Toast.LENGTH_SHORT).show();
                              phoneNo = phoneCursor.getString(phoneCursor
                .getColumnIndex(ContactsContract.CommonDataKinds.
                Phone.NUMBER));


                                String image_uri = phoneCursor
                                         .getString(phoneCursor
                                         .getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));

                             if (image_uri != null) {
                                 Toast.makeText(context, "Toast 4", Toast.LENGTH_SHORT).show();
                                 System.out.println(Uri.parse(image_uri));
                                 try {
                              bitmap = MediaStore.Images.Media
                                 .getBitmap(this.getContentResolver(),
                                 Uri.parse(image_uri));
                                // sb.append("\n Image in Bitmap:" + bitmap);
                                // System.out.println(bitmap);

                                 } catch (FileNotFoundException e) {
                                 // TODO Auto-generated catch block
                                 e.printStackTrace();
                                 } catch (IOException e) {
                                 // TODO Auto-generated catch block
                                 e.printStackTrace();
                                 }

                                 }
                             Toast.makeText(context, name, Toast.LENGTH_SHORT).show();

                                    getDataInList(name,phoneNo,bitmap);
                                 name=null;
                                 phoneNo=null;
                                 Drawable myDrawable = getResources().getDrawable(R.drawable.star1);
                                 bitmap = ((BitmapDrawable) myDrawable).getBitmap();



                                    }
                                    phoneCursor.close();
                                }

                            }


                        }

Here the setAdapter() function of the listview is working after fetching all the contacts to an ArrayList. do anyone have idea about how to display the contacts during fetching contacts? any sample code?

like image 766
irfan Avatar asked Jan 04 '14 06:01

irfan


2 Answers

1.Read the Columns from the Cursor which you required only ,According to your requirement you just need _ID,HAS_PHONE_NUMBER,DISPLAY_NAME ,so change the Cursor reading

Cursor cursor = getContentResolver().query(
            ContactsContract.Contacts.CONTENT_URI,
            new String[] { ContactsContract.Contacts._ID,
                    ContactsContract.Contacts.HAS_PHONE_NUMBER,
                    ContactsContract.Contacts.DISPLAY_NAME }, null, null,
            ContactsContract.Contacts.DISPLAY_NAME + " ASC");

2.Dont do the time taking process in the UI thread..Use AsyncTask instead

Note : This two steps will resolve to some extent..but not completely

like image 194
Jagadesh Seeram Avatar answered Nov 03 '22 08:11

Jagadesh Seeram


I made it by reduce repeated query wich is expensive. Best of my solution is that method found all mobile phones and email for each contact and insert to list for every contact values. It is fast as storm now :)

//contact entity
public class MobileContact {
    public String name;
    public String contact;
    public Type type;

    public MobileContact(String contact, Type type) {
        name = "";
        this.contact = contact;
        this.type = type;
    }

    public MobileContact(String name, String contact, Type type) {
        this.name = name;
        this.contact = contact;
        this.type = type;
    }

    public enum Type {
        EMAIL, PHONE
    }

    @Override
    public String toString() {
        return "MobileContact{" +
                "name='" + name + '\'' +
                ", contact='" + contact + '\'' +
                ", type=" + type +
                '}';
    }
}

// method for collect contacts
public List<MobileContact> getAllContacts() {
        log.debug("get all contacts");
        List<MobileContact> mobileContacts = new ArrayList<>();
        ContentResolver contentResolver = context.getContentResolver();

        // add all mobiles contact
        Cursor phonesCursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.CONTACT_ID}, null, null, null);
        while (phonesCursor != null && phonesCursor.moveToNext()) {
            String contactId = phonesCursor.getString(phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
            String phoneNumber = phonesCursor.getString(phonesCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replace(" ", "");
            mobileContacts.add(new MobileContact(contactId, phoneNumber, MobileContact.Type.PHONE));
        }
        if (phonesCursor != null) {
            phonesCursor.close();
        }

        // add all email contact
        Cursor emailCursor = contentResolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Email.DATA, ContactsContract.CommonDataKinds.Email.CONTACT_ID}, null, null, null);
        while (emailCursor != null && emailCursor.moveToNext()) {
            String contactId = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.CONTACT_ID));
            String email = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
            mobileContacts.add(new MobileContact(contactId, email, MobileContact.Type.EMAIL));
        }
        if (emailCursor != null) {
            emailCursor.close();
        }

        // get contact name map
        Map<String, String> contactMap = new HashMap<>();
        Cursor contactsCursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI, new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.HAS_PHONE_NUMBER}, null, null, ContactsContract.Contacts.DISPLAY_NAME);
        while (contactsCursor != null && contactsCursor.moveToNext()) {
            String contactId = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts._ID));
            String contactName = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            contactMap.put(contactId, contactName);
        }
        if (phonesCursor != null) {
            phonesCursor.close();
        }


        // replace contactId to display name
        for (MobileContact mobileContact : mobileContacts) {
            String displayName = contactMap.get(mobileContact.name);
            mobileContact.name = displayName != null ? displayName : "";
        }

        // sort list by name
        Collections.sort(mobileContacts, new Comparator<MobileContact>() {
            @Override
            public int compare(MobileContact c1, MobileContact c2) {
                return c1.name.compareTo(c2.name);
            }
        });

        return mobileContacts;
    }
like image 2
Andrew Sneck Avatar answered Nov 03 '22 08:11

Andrew Sneck