使用Async Task读取手机通讯录并将其设置为AutoCompleteTextView的适配器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Async Task读取手机通讯录并将其设置为AutoCompleteTextView的适配器相关的知识,希望对你有一定的参考价值。

我已经从设备中读取了所有手机联系人,并将它们设置为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做的事情。谢谢。

答案

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

 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();
另一答案

喜欢@ADM建议。创建一个单独的类,而不是内部类。 FetchContacts.java

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... voids) {
    List<Contact> contactList = new ArrayList<>();
    // get Contacts here

    ContentResolver cr = activity.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();
            }
        }
    }
    if (cur != null) {
        cur.close();
    }
    return contactList;
}

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

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

并调用该类,将联系人列表设置为ArrayAdapter,将arrayadapter设置为自动完成textview,如下所示:

new FetchContacts(MainActivity.this, new FetchContacts.OnContactFetchListener() {
        @Override
        public void onContactFetch(List contacts) {
            // Here you will get the contacts
            ArrayAdapter<Contact> contactArrayAdapter = new ArrayAdapter<Contact>(MainActivity.this,
                    android.R.layout.simple_list_item_1, contacts);
            userInput.setAdapter(contactArrayAdapter); //userInput is our AutoCompleteTextView

        }
    }).execute();

以上是关于使用Async Task读取手机通讯录并将其设置为AutoCompleteTextView的适配器的主要内容,如果未能解决你的问题,请参考以下文章

vivo手机怎么设置通讯录读取权限

有没有办法从 text.file 读取文本并将其设置为 pom.xml maven 中的 maven 属性?

如何读取 save.txt 文件并将其设置为标签

异步杂记

安卓手机手机微信如何设置允许访问通讯录

如何从外部 api 读取属性并将其设置为 springboot 中的应用程序上下文以使其全局可用?