背景

公司项目智护伞维护 , 因为业务需求,需要插入联系人 , 同一名字下大量电话号码.因为此项目为很多人开发,到了我这里,只是日常维护,修改新需求.所以需求来了

技术免踩坑

android在合并的时候回去调用compare方法对EntityDeltas进行一个比较,这时候会根据2个 raw_contacts的accountType进行比较,但是此时有可能你这2条记录 不在任何账户下 就会导致联系人插入重复.那么问题来了,该怎么避免这种情况呢?

旧代码实现方式

进入应用统统删除自己公司的号码后再统统插入.

新需求

公司要求,不予许删除号码,只能插入.

思路

那么我们的思路可以是 :查询后存在则不理,不存在则插入.

遇到坑

网上的针对插入方式很多,查询方式也很多,然而没有一个通用的,总是出现,不是小米手机重复插入,就是VIVO手机重复插入.

正确姿势

经过多次实验,发现直接通过数据库表的方式插入是可行的.所以我们可以开始玩耍咯.

封装类

package com.yanguan.aima.Other.Public_Class;
	import android.content.ContentResolver;
	import android.content.ContentUris;
	import android.content.ContentValues;
	import android.content.Context;
	import android.database.Cursor;
	import android.net.Uri;
	import android.provider.ContactsContract;
	import android.util.Log;
	
	import java.util.ArrayList;
	
	import static com.vilyever.contextholder.ContextHolder.getContext;

	/**
	 *  批量报警电话插入联系人
	 *  @author Town
	 *  created at 2017/7/29 15:55
	 *  说明: 为适应本公司业务需求.将本公司告警提醒电话插入联系人
	 *  新启线程  避免影响UI线程
	 */

	public class ContentProviderHelper implements Runnable {

    Context context;
    //本司电话告警名称
    private   String phoneName = "";
    //本司电话告警号码
    private  ArrayList<String> phoneNum = null;

    //是否插入联系人
    private boolean isInserted = false;

    ContentValues values = null;

    Uri rawContactUri;

    long rawContactId = 0;

    public ContentProviderHelper(Context context ,ArrayList<String> phoneNum, String phoneName ){
        this.context = context;
        this.phoneNum = phoneNum;
        this.phoneName = phoneName;
    }


    @Override
    public void run() {
	//            查询
        isInserted = queryTheContactName(phoneNum,phoneName);
        if (isInserted){
	//            插入
            insertContent(phoneNum,phoneName);
        }

    }

    /**
     * 利用手机号查询联系人是否有与本司告警名字一样的
     * @param phoneNumber 本司手机电话号码集合
     * @param contactName 本司告警电话名字
     * @return 是否可以插入联系人   false 联系人存在不可以插入  true 联系人不存在需要插入
     */
    private boolean queryTheContactName(final ArrayList<String> phoneNumber ,String contactName) {
        Log.i(" 联系人操作 ","开始查询");
        for (String str:phoneNumber) {
            Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + str);
            ContentResolver resolver = getContext().getContentResolver();
            Cursor cursor = resolver.query(uri, new String[]{android.provider.ContactsContract.Data.DISPLAY_NAME}, null, null, null);
            if (cursor.moveToFirst()) {
                String name = cursor.getString(0);
                if (name.equals(contactName)) {
                    cursor.close();
                    Log.i(" 联系人操作 ","查询完成   不需要插入");
                    return  false;
                }
            }
            cursor.close();
        }

        Log.i(" 联系人操作 ","查询完成   需要插入");
        return true;
    }

    private void insertContent(ArrayList<String> phoneNumber ,String contactName){
        isInserted = false;
        values = new ContentValues();
        rawContactUri = context.getContentResolver().insert(
                ContactsContract.RawContacts.CONTENT_URI, values);
        rawContactId = ContentUris.parseId(rawContactUri);
        if (values!=null && rawContactId!=0){
            Log.i(" 联系人操作 ","开始插入");
            //插入或者更新联系人
            for (String str:phoneNumber) {
                // 向data表插入数据
                if (contactName != "") {
                    values.clear();
                    values.put(ContactsContract.Contacts.Data.RAW_CONTACT_ID, rawContactId);
                    values.put(ContactsContract.Contacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
                    values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contactName);
                    context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
                            values);
                }
                // 向data表插入电话号码
                if (str != "") {
                    values.clear();
                    values.put(ContactsContract.Contacts.Data.RAW_CONTACT_ID, rawContactId);
                    values.put(ContactsContract.Contacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
                    values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, str);
                    values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
                    context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI,
                            values);
                }
            }
            Log.i(" 联系人操作 ","插入完成");
        }
 }
}

调用方法

只需要传入电话号码列表 aPhoneList,和联系人名字phoneName.就可以咯


new Thread(new ContentProviderHelper(context,aPhoneList,phoneName){
            @Override
            public void run() {
                super.run();
            }
        }
).start();

扩展

需要插入批量联系人的 可以做简单修改就可以使用咯!

扩展思路

适用于插入批量联系人 , 请求后台数据 解析json后放入map里 建立两个map 一个放电话 一个放对应的姓名,对应电话和对应姓名对同样的k ,那么就好办咯 !修改传入phoneName与aPhoenList为map,

里面遍历的地方改为map就可以咯 .

怎么样?是不是很简单? 做下记录而已啦!如果需要插入批量联系人,看了我的思路还不会修改的话,联系我帮你哦!