1

i want to display my contacts in a recyclerview with cardelements. The problem is, that it is only displayed one contact for several times. So the same name is shown in every card. It seems like the cursor doesn't get to the next contact. But I don't know why. And I have to admit that I'm quite new to android. Here is the code:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.contacts);
    RecyclerView recList = (RecyclerView) findViewById(R.id.cardList);
    recList.setHasFixedSize(true);
    LinearLayoutManager llm = new LinearLayoutManager(this);
    llm.setOrientation(LinearLayoutManager.VERTICAL);
    recList.setLayoutManager(llm);


    contactRecAdapter ca = new contactRecAdapter(data);
    recList.setAdapter(ca);
    data = displayContact();
}

and my displayContact():

private ArrayList<contactInfo> displayContact(){

    ContentResolver cr = getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,null,null,null,null);
    String name ;
    String number;
    String id;

    contactInfo cI = new contactInfo();

    if(cur.getCount()>1){
        while (cur.moveToNext()){
           id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
           name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

            if(Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)))>0){

                cI.name = name;
                Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",new String[]{id},null);

               while (pCur.moveToNext()){
                     number = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                     cI.number =number;
                }
                data.add(cI);
                pCur.close();
           }

        }
    }

    cur.close();
    return data;
}

Thank you!

ben
  • 11
  • 2
  • Hey,You need to collect data first and then set it in the adapter. Try to change your onCreate() data = displayContact(); contactRecAdapter ca = new contactRecAdapter(data); recList.setAdapter(ca); – Divya Jain Jun 30 '15 at 13:08

1 Answers1

0

What you need to understand is that currently, you have 1 contactInfo object and you are adding this contactInfo object into the data (arraylist).

Let's take it down one step at a time. This is what the code is currently doing:

  1. Create a contactInfo object (Let's name it C1).
  2. Set the name as "abc" and number as "123".
  3. Add this C1 into data arraylist. --> Essentially the arraylist is holding a reference to where this C1 resides in the memory (i.e. it is only pointing to C1)
  4. Cursor founds another contact and set the name of C1 to "def" and number to "456"
  5. Add this C1 into data arraylist. (At this point of time, what the arraylist contains is actually 2 references, both pointing to C1)
  6. Assuming the cursor finds nothing next and finally returns the data arraylist.

You will then get an arraylist that contains 2 records and both consists of contact name "def" and number "456".

Instead, what I would recommend based on your code is to simply add 1 more line to create a new contactInfo object each time you find a new contact, before setting the name.

private ArrayList<contactInfo> displayContact(){

    ContentResolver cr = getContentResolver();
    Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI,null,null,null,null);
    String name ;
    String number;
    String id;
    contactInfo cI; //Remove the creation of cI object at the start

    if(cur.getCount()>1){
        while (cur.moveToNext()){
           id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
           name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

            if(Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)))>0){

                cI = new contactInfo(); //Add in this to create a new cI object when there's a new contact

                cI.name = name;
                Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",new String[]{id},null);

               while (pCur.moveToNext()){
                     number = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                     cI.number =number;
                }
                data.add(cI);
                pCur.close();
           }

        }
    }

    cur.close();
    return data;
}

And you might want to optimize this code a little by having it fetch the phone numbers together with the names as the current way will take a fair bit of time if the data is huge. You can have a look at this post: https://stackoverflow.com/a/28690030/3717990

Community
  • 1
  • 1
skyplor
  • 251
  • 3
  • 8