Android Contacts Contacts与AutocompleteTextview合作太慢

时间:2015-06-24 09:15:10

标签: android autocompletetextview contactscontract

尝试使用ContactsProvider使用AutoCompleteTextview使用获取数据(名称和电话号码)的方法并将其存储在列表中。正如预期的那样,在我的onCreateView类的Fragment方法中调用方法时,此方法总是需要一段时间才能完成。

这是方法:

...
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);
    }


}

我确定有更好的方法可以实现这一目标,但是当我输入AutocompleteTextview时,此方法会有效,并会显示建议。我只是担心需要的时间。如何在不填充ArrayList的情况下完成此操作? 我已经查看了这个问题:Getting name and email from contact list is very slow并在我的代码的答案中应用了这些建议,但现在我输入时没有任何建议。如何提高当前代码的性能?

2 个答案:

答案 0 :(得分:0)

这就是我实施AutoCompleteTextView的方式,它对我来说很好..

  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);

答案 1 :(得分:0)

通过将方法放在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

然后在我的onCreateView()中调用它:

public View onCreateView(LayoutInflater inflater, ViewGroup container, 

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

现在,我的视图膨胀和获取数据的任务分为两个不同的线程。

CursorLoader提到的Eugen Pechanec选项是最好的选择,所以我会尽可能用该选项更新此答案。