Android端通讯录拉取与插入工具类

  最近做了一个拉取用户通讯录的App,其中关键点在于用户通讯录的拉取和还原,所以根据业务需求抽象出来一个工具类,其中也遇到坑,但是还是算比较顺利的完成了。

   <!-- 读联系人权限 -->
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <!-- 写联系人权限 -->
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
package com.fenla.contacts.utils;

import android.app.Activity;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.os.RemoteException;
import android.provider.ContactsContract;

import com.fenla.contacts.model.bean.ContactBean;

import java.util.ArrayList;
import java.util.List;

/**
 *
 * 联系人的备份和还原工具类
 */

public class ContactUtils {

    public static String[] projection = new String[]{
            ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
            ContactsContract.CommonDataKinds.Phone.NUMBER,
            ContactsContract.Contacts.DISPLAY_NAME};

    /**
     * 获取联系人数据
     *
     * @param activity
     * @return
     */
    public static List<ContactBean> getContactsData(Activity activity) {
        Cursor cursor = null;
        String contactName;
        String contactNumber;
        ContentResolver resolver = activity.getContentResolver();
        List<ContactBean> list = new ArrayList<>();
        //搜索字段
        try {
            cursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, null, null, null);
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    //获取联系人的ID
                    int contactId = cursor.getInt(0);
                    //获取联系人的姓名
                    contactName = cursor.getString(2);
                    //获取联系人的号码
                    contactNumber = cursor.getString(1);
                    ContactBean bean = new ContactBean();
                    bean.setContactNo(contactNumber);
                    bean.setContactName(contactName);
                    list.add(bean);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return list;
    }



    /**
     * 还原通讯录
     *
     * @param activity
     * @param list
     */
    public static void restoreContactsData(Activity activity, List<ContactBean> list) {
//        需要批量插入的数据
        List<ContactBean> beanList = new ArrayList<>();
        for (ContactBean contactBean : list) {
           contactBean.setContactName(contactBean.getContactName().replace("-",""));
        }
        ContentResolver resolver = activity.getContentResolver();
        for (ContactBean contactBean : list) {
            boolean flag = hasExist(resolver, contactBean.getContactName(), contactBean.getContactNo());
            if (!flag) {
                beanList.add(contactBean);
            }
        }
        if (beanList.size() != 0) {
            copyAllPhone(beanList, activity);
        }

    }

    /**
     * 判断是否存在这个联系人
     *
     * @param resolver
     * @param name
     * @param phone
     * @return
     */
    public static boolean hasExist(ContentResolver resolver, String name, String phone) {
        Cursor cursor = null;
        String contactName;
        String contactNumber;
        //搜索字段
        try {
            cursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, null, null, null);
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    //获取联系人的ID
                    int contactId = cursor.getInt(0);
                    //获取联系人的姓名
                    contactName = cursor.getString(2);
                    //获取联系人的号码
                    contactNumber = cursor.getString(1);
                    if (contactName.equals(name) && contactNumber.equals(phone)) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return false;
    }



    /**
     * 批量插入联系人
     *
     * @param list
     * @param ctx
     */
    public static void copyAllPhone(List<ContactBean> list, Activity ctx) {
        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
        int rawContactInsertIndex;
        for (int i = 0; i < list.size(); i++) {
            rawContactInsertIndex = ops.size();//这句好很重要,有了它才能给真正的实现批量添加。
            ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
                    .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
                    .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
                    .withYieldAllowed(true)
                    .build());

            ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                    .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID,
                            rawContactInsertIndex)
                    .withValue(ContactsContract.Data.MIMETYPE,
                            ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                    .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, list.get(i).getContactName())
                    .withYieldAllowed(true)
                    .build());

            ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                    .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex)
                    .withValue(ContactsContract.Data.MIMETYPE,
                            ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                    .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, list.get(i).getContactNo())
                    .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
                    .withYieldAllowed(true)
                    .build());
        }

        try {
//              批量添加
            ctx.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (OperationApplicationException e) {
            e.printStackTrace();
        }
    }


}

        几个关键节点需要注意的:

1、因为我有做简单的号码比对,所以过程中出现的问题是一直都是单条插入,和动态获取插入后的联系人数据,使插入的效率太低,然后我通过批量插入的方式来操作,明显减少了插入时间。

2、在通讯录的插入和拉取的时候都要用RxJava2来开IO线程来操作,不然当数据量大的时候,主线程被卡住,会出现ANR。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值