android - 使用 Async Task 读取电话联系人并将它们设置为 AutoCompleteTextView 的适配器

标签 android android-asynctask android-contacts android-cursor android-contentresolver

我已经从设备中读取了所有电话联系人并将它们设置为 AutoCompleteTextView 的适配器。执行此操作的函数是:

private void storeContactsToArrayList() {
    Log.d("In ", "storeContactsToArrayList() called");

    List<Contact> contactList = new ArrayList<>();

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

    if ((cur != null ? cur.getCount() : 0) > 0) {
        while (cur != null && cur.moveToNext()) {
            String id = cur.getString(
                    cur.getColumnIndex(ContactsContract.Contacts._ID));
            String name = cur.getString(cur.getColumnIndex(
                    ContactsContract.Contacts.DISPLAY_NAME));

            if (cur.getInt(cur.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 phoneNo = pCur.getString(pCur.getColumnIndex(
                            ContactsContract.CommonDataKinds.Phone.NUMBER));
//                        Log.i("GOT", "Name: " + name);
//                        Log.i("GOT", "Phone Number: " + phoneNo); //working
                    //To our POJO
                    Contact contact = new Contact();
                    contact.setName(name);
                    contact.setPhoneNumber(phoneNo);

                    contactList.add(contact);

                }
                pCur.close();
            }
            ArrayAdapter<Contact> contactsArrayAdapter =
                    new ArrayAdapter<Contact>(this, android.R.layout.simple_list_item_1, contactList);

            //setting this adapter to our autocompleteTextView userInput
            userInput.setAdapter(contactsArrayAdapter);
        }
    }
    if(cur!=null){
        cur.close();
    }
}

然而,当我运行代码时,我意识到该函数需要相当长的时间来执行,这看起来很糟糕。 据我所知,我应该使用像 AdapterTask extends Async Task 这样的内部类来执行相同的操作,但异步操作不会阻塞我的主 UI 线程。我试过这样做,但我做不到。 请建议我是否有任何其他方法可以在不使用 AsyncTask 的情况下做同样的事情,或者如果 AsyncTask 是可行的方法,我怎样才能使用 AsyncTask 实现上述功能正在做的事情。 谢谢。

最佳答案

为后台任务创建一个单独的类并与监听器(和接口(interface))通信。以下是示例根据需要修改

 public class FetchContacts extends AsyncTask<Void, Void, List> {
    private Context activity;
    private OnContactFetchListener listener;
    public FetchContacts(Context context, OnContactFetchListener listener) {
        activity = context;
        this.listener = listener;
    }
    @Override
    protected List doInBackground(Void... params) {
        List<Contact> contactList = new ArrayList<>();
        // get Contacts here
        return contactList;
    }

    @Override
    protected void onPostExecute(List list) {
        super.onPostExecute(list);
        if(listener!=null){
            listener.onContactFetch(list);
        }
    }

    public interface OnContactFetchListener {
        void onContactFetch(List  list);
    }
}

可以调用为.

  new FetchContacts(activity, new FetchContacts.OnContactFetchListener() {
                @Override
                public void onContactFetch(List contacts) {
                    // Here you will get the contacts
                }
            }).execute();

关于android - 使用 Async Task 读取电话联系人并将它们设置为 AutoCompleteTextView 的适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47975674/

相关文章:

android - SharedPreferences 中的 commit() 和 apply() 有什么区别

android - 如何在特定时间从 Activity 运行 AsyncTask?

Android AsyncTask 登录同一文件

android - 逻辑上正确但 'if statement' 的方法使我的应用程序崩溃

android - 显示号码、联系人姓名和可能的联系人图像的联系人选择器?

android - 在单个查询中获取联系人的详细信息

android - 如何检查设备是否刚刚连接到互联网

android - 如何在菜单项上做点击事件?

android - 在Android中,如何获取当前标签页的内容?

android - 编辑联系人 URI 在 android 4.0 及更高版本中不起作用