You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中如何使用AsyncTask读取手机通讯录联系人

Android AsyncTask 通讯录读取优化实现方案

注:AsyncTask 自 Android 11(API 30)开始被官方标记为废弃,若适配高版本系统优先考虑协程、WorkManager 等方案,以下实现适用于低版本兼容场景

1. 前置权限配置

首先在 AndroidManifest.xml 中声明通讯录读取权限:

<uses-permission android:name="android.permission.READ_CONTACTS" />

Android 6.0 及以上版本需要在启动读取任务前,动态申请 READ_CONTACTS 权限,权限校验通过后再执行后续操作。

2. 自定义通讯录读取 AsyncTask 类

首先定义通讯录实体类存储读取结果,再继承 AsyncTask 实现耗时逻辑:

// 通讯录实体类,自行补充构造、getter、setter 方法
public class ContactInfo {
    private String name;
    private String phone;
}

// 异步读取任务类
public class ReadContactsTask extends AsyncTask<Void, Void, List<ContactInfo>> {
    private Context appContext;
    private OnContactsReadListener readListener;

    // 构造方法传入上下文和结果回调,用ApplicationContext避免内存泄漏
    public ReadContactsTask(Context context, OnContactsReadListener listener) {
        this.appContext = context.getApplicationContext();
        this.readListener = listener;
    }

    // 后台线程执行耗时的通讯录查询逻辑
    @Override
    protected List<ContactInfo> doInBackground(Void... voids) {
        List<ContactInfo> resultList = new ArrayList<>();
        ContentResolver resolver = appContext.getContentResolver();
        // 查询通讯录数据
        Cursor cursor = resolver.query(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null,
            null,
            null,
            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"
        );
        if (cursor != null) {
            while (cursor.moveToNext()) {
                String name = cursor.getString(cursor.getColumnIndexOrThrow(
                    ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                String phone = cursor.getString(cursor.getColumnIndexOrThrow(
                    ContactsContract.CommonDataKinds.Phone.NUMBER));
                resultList.add(new ContactInfo(name, phone));
            }
            cursor.close();
        }
        return resultList;
    }

    // 任务完成后回调,运行在主线程可直接更新UI
    @Override
    protected void onPostExecute(List<ContactInfo> contactInfos) {
        super.onPostExecute(contactInfos);
        if (readListener != null) {
            readListener.onReadSuccess(contactInfos);
        }
    }

    // 结果回调接口
    public interface OnContactsReadListener {
        void onReadSuccess(List<ContactInfo> contactList);
    }
}

3. 页面调用异步任务

权限申请通过后,直接启动任务即可:

// 确认已获取READ_CONTACTS权限后执行
new ReadContactsTask(this, new ReadContactsTask.OnContactsReadListener() {
    @Override
    public void onReadSuccess(List<ContactInfo> contactList) {
        // 此处可直接使用读取结果更新列表、渲染UI
    }
}).execute();

注意事项

  • 若页面销毁时不需要接收读取结果,可在 onDestroy() 生命周期中调用 task.cancel(true) 终止任务,避免内存泄漏
  • 通讯录查询逻辑和你原有同步读取逻辑保持一致即可,仅需要把耗时逻辑移动到 doInBackground 方法中执行

内容的提问来源于stack exchange,提问作者Abdul Rasheed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 15:54:09