0

Am trying to use the ContactsProvider with my AutoCompleteTextview using a method that fetches the data (name and phone number) and stores them in a list. As expected, this method will always take time to complete as am calling the method in the onCreateView method of my Fragment class.

This is the method:

...
ArrayList<String> phoneValues;
ArrayList<String> nameValues;
...

private void readContactData() {

    try {

        /*********** Reading Contacts Name And Number **********/

        String phoneNumber = "";
        ContentResolver contentResolver = getActivity()
                .getContentResolver();

        //Query to get contact name

        Cursor cursor = contentResolver
                .query(ContactsContract.Contacts.CONTENT_URI,
                        null,
                        null,
                        null,
                        null);

        // If data data found in contacts
        if (cursor.getCount() > 0) {

            int k=0;
            String name = "";

            while (cursor.moveToNext())
            {

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

                //Check contact have phone number
                if (Integer
                        .parseInt(cursor
                                .getString(cursor
                                        .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0)
                {

                    //Create query to get phone number by contact id
                    Cursor pCur = contentResolver
                            .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                    null,
                                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                            + " = ?",
                                    new String[] { id },
                                    null);
                    int j=0;

                    while (pCur
                            .moveToNext())
                    {
                        // Sometimes get multiple data
                        if(j==0)
                        {
                            // Get Phone number
                            phoneNumber =""+pCur.getString(pCur
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                            // Add contacts names to adapter
                            autocompleteAdapter.add(name);

                            // Add ArrayList names to adapter
                            phoneValues.add(phoneNumber.toString());
                            nameValues.add(name.toString());

                            j++;
                            k++;
                        }
                    }  // End while loop
                    pCur.close();
                } // End if

            }  // End while loop

        } // End Cursor value check
        cursor.close();


    } catch (Exception e) {
        Log.i("AutocompleteContacts","Exception : "+ e);
    }


}

Am sure there is a better way to accomplish this, but this method works and the suggestions are presented when I type into the AutocompleteTextview. Am just worried about the time it takes. How can I accomplish this without populating an ArrayList? I have looked at this question: Getting name and email from contact list is very slow and applied the suggestions in the answer to my code, but now nothing is suggested when I type.How can I improve the performance of my current code?

Community
  • 1
  • 1
Ojonugwa Jude Ochalifu
  • 26,627
  • 26
  • 120
  • 132

2 Answers2

0

This is how i have implemented AutoCompleteTextView and it works fine for me ..

  final AutoCompleteTextView act=(AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);
         ArrayList<String> alContacts = new ArrayList<String>();
         ArrayList<String> alNames= new ArrayList<String>();

ContentResolver cr = this.getContentResolver(); //Activity/Application android.content.Context
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if(cursor.moveToFirst())
{

    do
    {
        String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));

        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 contactNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                String contactName=pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                alNames.add(contactName);
                alContacts.add(contactNumber);
                break;
            }
            pCur.close();
        }

    } while (cursor.moveToNext()) ;
}


String[] array=new String[alNames.size()];
array=(String[]) alNames.toArray(array);
ArrayAdapter<String> myArr= new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line,array);
act.setAdapter(myArr);
act.setThreshold(1);
Anusha Harish
  • 382
  • 3
  • 14
0

I got rid of the slow response by placing the method inside an AsynTask.

 public class AutocompleteAsyncTask extends AsyncTask<Void, Void, Void> {


    public Void doInBackground(Void...params) {

        try {

            /*********** Reading Contacts Name And Number **********/

            String phoneNumber = "";
            ContentResolver contentResolver = getActivity()
                    .getContentResolver();

            //Query to get contact name

            Cursor cursor = contentResolver
                    .query(ContactsContract.Contacts.CONTENT_URI,
                            null,
                            null,
                            null,
                            null);

            // If data data found in contacts
            if (cursor.getCount() > 0) {

                int k=0;
                String name = "";

                while (cursor.moveToNext())
                {
            //...Rest of the same code as above

and then calling this in my onCreateView():

public View onCreateView(LayoutInflater inflater, ViewGroup container, 

  Bundle savedInstanceState) {
...
  new AutocompleteAsyncTask().execute();
   return rootView;
}

Now the task of inflating my view and fetching the data are separated into two different threads.

The CursorLoader option mentioned by Eugen Pechanec is kinda the best option, so I'll update this answer with that option when I can.

Ojonugwa Jude Ochalifu
  • 26,627
  • 26
  • 120
  • 132
  • as i said, use SimpleCursorAdapter here http://pastebin.com/fdg3QmAq you have magic 17 lines of complete working code – pskink Jun 24 '15 at 10:13
  • Tried it.Am getting an error : `The specified child already has a parent. You must call removeView() on the child's parent first.` but when I comment out the second line of the code, it works but a strange text is returned: `android.content.contentresolver$CursorWrapperInner@41b78fd8` – Ojonugwa Jude Ochalifu Jun 24 '15 at 10:28
  • dont comment the second line, just use one setContentView in your onCreate method – pskink Jun 24 '15 at 10:31
  • That was why I commented the second line.To use just one.If I leave the second line and comment out the default setContentView method, I also get an error – Ojonugwa Jude Ochalifu Jun 24 '15 at 10:35
  • just add my code to an **empty** onCreate method (keep super.onCreate only) – pskink Jun 24 '15 at 10:37
  • Activity#onCreate() ? you dont call it, its called by the system – pskink Jun 24 '15 at 10:43
  • create an Activity with empty onCreate method, add super.onCreate and then my code – pskink Jun 24 '15 at 10:45
  • Sorry,am away from my computer right now.Will give you a feedback ASAP – Ojonugwa Jude Ochalifu Jun 24 '15 at 12:09