Android插入联系人完美封装类
背景
公司项目智护伞维护 , 因为业务需求,需要插入联系人 , 同一名字下大量电话号码.因为此项目为很多人开发,到了我这里,只是日常维护,修改新需求.所以需求来了
技术免踩坑
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就可以咯 .
怎么样?是不是很简单? 做下记录而已啦!如果需要插入批量联系人,看了我的思路还不会修改的话,联系我帮你哦!