Android监听通讯录修改,然后上传修改部分
2017-12-12 21:04
1081 查看
需求
由于项目需要所以在app登录之后都有获取一份本地的通讯录然后上传到服务器。但是最近后台的小伙伴一直反馈说如果每次前端都把整个的通讯录上传过去,然后后台再做比较、去重、再插入数据库的话这样给服务器的压力会比较大。仔细一想其实也是,如果用户的通讯录没有改变那么上诉的所有操作都是白费的。于是我们前端要做到除了用户第一次全部上传外,以后只有在通讯录发生改变的时候才上传修改的部分通讯录。
为了实现以上的需求我们需要实现下面几个功能:
首次登录上传全部通讯录,然后保存通讯录到本地数据库中
监听联系人是否改变
如果联系人发生改变,获取到改变后的联系人和之前保存在本地的做比较得到改变后的,然后上传服务器
首次全部上传,并且保存到本地数据库中
第一次上传的时候获取全部联系人数据,上传完成后保存到greenDao中,这里主要记录连个字段,RawContacts._ID和RawContacts.VERSION。RawContacts._ID:用于判断这个联系人之前是否存在
RawContacts.VERSION:当新创建一个联系人的时候version的默认值为2,以后每修改一次就增加1,所以它是判断联系人是否修改的关键
ContentResolver _contentResolver = getContentResolver(); Cursor cursor = _contentResolver.query( ContactsContract.RawContacts.CONTENT_URI, null, null, null, null); //清空本地数据库 oldContactLists.clear(); DBHelper.getInstance().getContact2Dao().deleteAll(); while (cursor.moveToNext()) { Long contactID = cursor.getLong(cursor .getColumnIndex(ContactsContract.RawContacts._ID)); long contactVersion = cursor.getLong(cursor .getColumnIndex(ContactsContract.RawContacts.VERSION)); String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); Contact2 contact2 = new Contact2(); contact2.vesion = contactVersion; contact2.name = name; contact2.phone = getPhoneNumber(contactID); contact2.contactID = contactID; contact2.cid = MyApplication.userAllInfo.cid; oldContactLists.add(contact2); 4000 } cursor.close(); upLoad(oldContactLists);
下面是模拟上传代码成功后保存通讯录到greenDao中:
Log.e("+++","上传成功"); Contact2Dao contact2Dao = DBHelper.getInstance().getContact2Dao(); for (int i = 0; i < removeDuplicateContactLists1.size(); i++) { Log.e("+++","上传了:"+removeDuplicateContactLists1.get(i).name+" "+removeDuplicateContactLists1.get(i).phone); contact2Dao.insert(removeDuplicateContactLists1.get(i)); }
接下来开始就是要开启一个service去监听联系人的变化
在service启动的时候:
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contactObserver);
/** * 监听通讯录变化 */ private ContentObserver contactObserver = new ContentObserver(new Handler()) { @Override public boolean deliverSelfNotifications() { return super.deliverSelfNotifications(); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); boolean needUpdate = isContactChanged(); if (needUpdate) { upLoad(newContactLists); getContentResolver().unregisterContentObserver(contactObserver); needUpdate = false; } } };
当监听到通讯录有改变的时候就调用isContactChanged()方法去判断联系人是否有修改
/** * 判断是否有改变 * * @return */ public boolean isContactChanged() { boolean theReturn = false; ContentResolver _contentResolver = getContentResolver(); Cursor cursor = _contentResolver.query( ContactsContract.RawContacts.CONTENT_URI, null, null, null, null); String phoneNumber = null; newContactLists.clear(); //当前获取到的最新通讯录 List<Contact2> tempLists = new ArrayList<>(); while (cursor.moveToNext()) { Long contactID = cursor.getLong(cursor .getColumnIndex(ContactsContract.RawContacts._ID)); long contactVersion = cursor.getLong(cursor .getColumnIndex(ContactsContract.RawContacts.VERSION)); String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); Contact2 contact2 = new Contact2(); contact2.vesion = contactVersion; contact2.name = name; contact2.contactID = contactID; contact2.cid = MyApplication.userAllInfo.cid; tempLists.add(contact2); } cursor.close(); //最新的通讯录去重 for (int i = 0; i < tempLists.size(); i++) { for (int j = tempLists.size() - 1; j > i; j--) { if (tempLists.get(j).name.equals(tempLists.get(i).name)) { tempLists.remove(j); } } } //本地数据库老的通讯录id List<Long> ids = new ArrayList<>(); for (int i = 0; i < oldContactLists.size(); i++) { ids.add(oldContactLists.get(i).contactID); } for (int i = 0; i < tempLists.size(); i++) { //联系人之前存在 Long contactID = tempLists.get(i).contactID; int index = ids.indexOf(contactID); if (ids.contains(contactID)) { //老的version long version = oldContactLists.get(index).vesion; //version和之前保存的不一致,联系人被修改 if (version != tempLists.get(i).vesion) { phoneNumber = getPhoneNumber(contactID); Contact2 contact2 = new Contact2(); contact2.vesion = tempLists.get(i).vesion; contact2.name = tempLists.get(i).name; contact2.phone = phoneNumber; contact2.contactID = tempLists.get(i).contactID; contact2.cid = MyApplication.userAllInfo.cid; newContactLists.add(contact2); theReturn = true; } } else { //联系人不存在,新增 phoneNumber = getPhoneNumber(contactID); Contact2 contact2 = new Contact2(); contact2.vesion = tempLists.get(i).vesion; contact2.name = tempLists.get(i).name; contact2.phone = phoneNumber; contact2.contactID = tempLists.get(i).contactID; contact2.cid = MyApplication.userAllInfo.cid; newContactLists.add(contact2); theReturn = true; } } return theReturn; }
最终newContactLists中的数据就是修改后的联系人。但是有一点需要注意,之前都是使用的RawContacts中的数据,但是这个表里面只能回去到联系人的RawContacts.id,RawContacts.version等数据,并不能获取到用户的电话号码。所以我们必须要根据RawContacts.id去得到用户的电话号码。
/** * 根据contactID得到联系人号码 * * @param contactID * @return */ private String getPhoneNumber(Long contactID) { Uri rawContactUri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, contactID); Uri entityUri = Uri.withAppendedPath(rawContactUri, ContactsContract.RawContacts.Entity.CONTENT_DIRECTORY); Cursor c = getContentResolver().query(entityUri, new String[]{ContactsContract.RawContacts.SOURCE_ID, ContactsContract.Contacts.Entity.DATA_ID, ContactsContract.RawContacts.Entity.MIMETYPE, ContactsContract.Contacts.Entity.DATA1}, null, null, null); try { while (c.moveToNext()) { if (!c.isNull(1)) { String data = c.getString(3); return data; } } } finally { c.close(); } return ""; }
至此,已经能够实现监听联系人变化,然后获取到变化后的联系人的姓名和电话号码。
下面贴出完整的代码,只需要把其中的上传联系人部分替换掉就能够完整使用,当然这里面greenDao部分需要自己去实现。
public class ContactIntentService extends IntentService { //原始的 private List<Contact2> oldContactLists; //修改的 private List<Contact2> newContactLists; public ContactIntentService() { super("contactIntentService"); } @Override protected void onHandleIntent(Intent intent) { } @Override public void onCreate() { super.onCreate(); DBHelper.init(this); oldContactLists = new ArrayList<>(); newContactLists = new ArrayList<>(); initHashMap(); getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contactObserver); } /** * 监听通讯录变化 */ private ContentObserver contactObserver = new ContentObserver(new Handler()) { @Override public boolean deliverSelfNotifications() { return super.deliverSelfNotifications(); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); boolean needUpdate = isContactChanged(); if (needUpdate) { upLoad(newContactLists); getContentResolver().unregisterContentObserver(contactObserver); needUpdate = false; } } } ba50 ; /** * 记录下RawContacts._ID和对应的version */ public void initHashMap() { //如果本地数据库没有数据,上传全部通讯录 if (DBHelper.getInstance().getContact2Dao().queryBuilder().list() == null || DBHelper.getInstance().getContact2Dao().queryBuilder().list().size() <= 0) { ContentResolver _contentResolver = getContentResolver(); Cursor cursor = _contentResolver.query( ContactsContract.RawContacts.CONTENT_URI, null, null, null, null); //清空本地数据库 oldContactLists.clear(); DBHelper.getInstance().getContact2Dao().deleteAll(); while (cursor.moveToNext()) { Long contactID = cursor.getLong(cursor .getColumnIndex(ContactsContract.RawContacts._ID)); long contactVersion = cursor.getLong(cursor .getColumnIndex(ContactsContract.RawContacts.VERSION)); String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); Contact2 contact2 = new Contact2(); contact2.vesion = contactVersion; contact2.name = name; contact2.phone = getPhoneNumber(contactID); contact2.contactID = contactID; contact2.cid = MyApplication.userAllInfo.cid; oldContactLists.add(contact2); } cursor.close(); //去掉重复,因为上面在遍历的时候会循环添加3次 for (int i = 0; i < oldContactLists.size(); i++) { for (int j = oldContactLists.size() - 1; j > i; j--) { if (oldContactLists.get(j).name.equals(oldContactLists.get(i).name)) { oldContactLists.remove(j); } } } Log.e("+++", "原始通讯录人数:" + oldContactLists.size()); upLoad(oldContactLists); } else { //本地数据库有数据和本地数据库比较后上传修改和增加的联系人信息 oldContactLists.addAll(DBHelper.getInstance().getContact2Dao().queryBuilder().list()); } } private void upload( final List<Contact2> removeDuplicateContactLists1) { <---这里执行上传操作--> Log.e("+++","上传成功"); Contact2Dao contact2Dao = DBHelper.getInstance().getContact2Dao(); for (int i = 0; i < removeDuplicateContactLists1.size(); i++) { Log.e("+++","上传了:"+removeDuplicateContactLists1.get(i).name+" "+removeDuplicateContactLists1.get(i).phone); contact2Dao.insert(removeDuplicateContactLists1.get(i)); } getContentResolver().unregisterContentObserver(contactObserver); } } /** * 判断是否有改变 * * @return */ public boolean isContactChanged() { boolean theReturn = false; ContentResolver _contentResolver = getContentResolver(); Cursor cursor = _contentResolver.query( ContactsContract.RawContacts.CONTENT_URI, null, null, null, null); String phoneNumber = null; newContactLists.clear(); //当前获取到的最新通讯录 List<Contact2> tempLists = new ArrayList<>(); while (cursor.moveToNext()) { Long contactID = cursor.getLong(cursor .getColumnIndex(ContactsContract.RawContacts._ID)); long contactVersion = cursor.getLong(cursor .getColumnIndex(ContactsContract.RawContacts.VERSION)); String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); Contact2 contact2 = new Contact2(); contact2.vesion = contactVersion; contact2.name = name; contact2.contactID = contactID; contact2.cid = MyApplication.userAllInfo.cid; tempLists.add(contact2); } cursor.close(); //最新的通讯录去重 for (int i = 0; i < tempLists.size(); i++) { for (int j = tempLists.size() - 1; j > i; j--) { if (tempLists.get(j).name.equals(tempLists.get(i).name)) { tempLists.remove(j); } } } //本地数据库老的通讯录id List<Long> ids = new ArrayList<>(); for (int i = 0; i < oldContactLists.size(); i++) { ids.add(oldContactLists.get(i).contactID); } for (int i = 0; i < tempLists.size(); i++) { //联系人之前存在 Long contactID = tempLists.get(i).contactID; int index = ids.indexOf(contactID); if (ids.contains(contactID)) { //老的version long version = oldContactLists.get(index).vesion; //version和之前保存的不一致,联系人被修改 if (version != tempLists.get(i).vesion) { phoneNumber = getPhoneNumber(contactID); Contact2 contact2 = new Contact2(); contact2.vesion = tempLists.get(i).vesion; contact2.name = tempLists.get(i).name; contact2.phone = phoneNumber; contact2.contactID = tempLists.get(i).contactID; contact2.cid = MyApplication.userAllInfo.cid; newContactLists.add(contact2); theReturn = true; } } else { //联系人不存在,新增 phoneNumber = getPhoneNumber(contactID); Contact2 contact2 = new Contact2(); contact2.vesion = tempLists.get(i).vesion; contact2.name = tempLists.get(i).name; contact2.phone = phoneNumber; contact2.contactID = tempLists.get(i).contactID; contact2.cid = MyApplication.userAllInfo.cid; newContactLists.add(contact2); theReturn = true; } } return theReturn; } /** * 根据contactID得到联系人号码 * * @param contactID * @return */ private String getPhoneNumber(Long contactID) { Uri rawContactUri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, contactID); Uri entityUri = Uri.withAppendedPath(rawContactUri, ContactsContract.RawContacts.Entity.CONTENT_DIRECTORY); Cursor c = getContentResolver().query(entityUri, new String[]{ContactsContract.RawContacts.SOURCE_ID, ContactsContract.Contacts.Entity.DATA_ID, ContactsContract.RawContacts.Entity.MIMETYPE, ContactsContract.Contacts.Entity.DATA1}, null, null, null); try { while (c.moveToNext()) { if (!c.isNull(1)) { String data = c.getString(3); return data; } } } finally { c.close(); } return ""; } }
相关文章推荐
- Android网络开源库-Retrofit(二) 文件上传、下载及进度监听
- Android之修改用户头像并上传服务器(实现手机拍照和SD卡选择上传)
- [置顶] android——解决部分输入法监听回退键无效的问题
- android 部分手机修改led灯方法
- android 头像利用okhttp上传到服务器部分----萌新成长之路
- Android OkHttp文件上传与下载的进度监听扩展
- Android拍照,上传,预览综合【修改】
- Android跳转到系统通讯录新增和修改联系人
- Android OkHttp文件上传与下载的进度监听扩展
- android String文件中修改部分字体颜色
- Android 打包VersionCode自增、APK文件名修改、上传蒲公英
- android-修改TextView中部分文字的颜色
- Android 修改TextView中部分字体的颜色及大小
- 如何监听系统联系人修改-android
- 取文件修改内容,然后上传至另一个ftp
- android 部分驱动修改的编译指令
- Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能
- Android开发中调用系统相册上传图片到服务器OPPO等部分手机上出现短暂的显示桌面问题的解决方法
- android-修改TextView中部分文字的颜色
- android脚步---UI界面修改,关于activity中增加按钮和监听