Search code examples
androidcursorandroid-contactsandroid-cursoradapter

Create autocompletetextview to display contacts


I want to create a auto complete textview in application that will read and show the users phone contacts. First i tried the link given here but the problem was everything was happening in the UI thread, hence my UI thread would freeze for like 10 seconds.

I saw many examples but all happen in the UI thread.

Then after googling a lot i came to the concept of cursoradapter and found a very good project given here but the problem is this example uses Contacts.CONTENT_URI and i cant get the Phone number associated with each contact. I tried changing the uri to ContactsContract.CommonDataKinds.Phone but it didn't work.

Then i modified the getitem method as follows:

@Override
public Object getItem(int position) {
    Cursor cursor = (Cursor) super.getItem(position);
    Contact contact = new Contact();

    String imageUri = cursor
            .getString(ContactsQuery.PHOTO_THUMBNAIL_DATA_COLUMN);
    Bitmap bitmap = loadContactPhotoThumbnail(imageUri,
            mDropdownItemHeight);
    if (bitmap == null) {
        bitmap = mLoadingImage;
    }

    contact.id = cursor.getLong(ContactsQuery.ID_COLUMN);

    Cursor phones = mContext.getContentResolver().query(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null,
            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = "
                    + contact.id, null, null);
    while (phones.moveToNext()) {
        String phoneNumber = phones
                .getString(phones
                        .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        Log.d(TAG, "Number: " + phoneNumber);
    }

    contact.lookupKey = cursor
            .getString(ContactsQuery.LOOKUP_KEY_COLUMN);
    contact.displayName = cursor
            .getString(ContactsQuery.DISPLAY_NAME_COLUMN);
    contact.image = bitmap;

    return contact;
} 

This gives me the contact number, but the query still happens in the UI thread i guess. I want it to happen in background thread. How do i achieve this.

Please also tell if there is an alternate approach.


Solution

  • You can write AsyncTask and retrieve the records in the doInBackgroud and then set the adapter to the autocomplete textview in the onPostExecute method. Something like this can be done :

    private void loadContacts(){
        AsyncTask<Void, Void, Void> contactsTask = new AsyncTask<Void, Void, Void>(){
    
            ProgressDialog progressDialog = null;
    
            @Override
            protected void onPreExecute() {
                final String msg = "Loading Contacts...";
                progressDialog = ProgressDialog.show(mContext, "Contacts", msg);
            }
    
            @Override
            protected Void doInBackground(Void... params) {
    
                final String projection[] = { Contacts.DISPLAY_NAME, Phone.NUMBER, "_id" };
                final String selection = null;
                final String[] selectionArgs = null;
    
                Cursor contactsCursor = mContext.getContentResolver().query(Phone.CONTENT_URI,
                        projection, selection, selectionArgs, null);
    
                final int[] toResources = {R.id.textView1, R.id.textView2};
    
                mContactsAdapter = new SimpleCursorAdapter(mContext,
                        R.layout.contacts_row, contactsCursor,
                        projection, toResources,0);
    
                return null;
            }
    
            @Override
            protected void onPostExecute(Void result) {
                progressDialog.dismiss();
                autoCompleteTextView.setAdapter(mContactsAdapter);
            }
        };
    
        contactsTask.execute(null,null);
    }