转自:http://blog.csdn.net/wangjiang_qianmo/article/details/49002149
在上一章 Android中联系人和通话记录详解(2)中分析了联系人相关的表和字段,在这一章中将分析联系人相关的基本数据操作(Insert,Query,Update,Delete)。
1.添加(Insert)
从contacts,data,mimetypes,raw_contacts表的关系可以看出,表raw_contacts为表data的父表,所以插入数据时,应该先在raw_contacts表中插入数据,再在data表中插入数据。
[java] view plain copy ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(); ContentProviderOperation op1 = ContentProviderOperation .newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null) .build();// 得到了一个添加内容的对象 operations.add(op1); ContentProviderOperation op2 = ContentProviderOperation .newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue( ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) .withValue(ContactsContract.Data.DATA1, "小明").build();// 得到了一个添加内容的对象 operations.add(op2); ContentProviderOperation op3 = ContentProviderOperation .newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue( ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE) .withValue(ContactsContract.Data.DATA1, "1233232542") .withValue(ContactsContract.Data.DATA2, "2")// data2=2即type=2,表示移动电话 .build();// 得到了一个添加内容的对象 operations.add(op3); ContentProviderOperation op4 = ContentProviderOperation .newInsert(ContactsContract.Data.CONTENT_URI) .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) .withValue( ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE) .withValue(ContactsContract.Data.DATA1, "test@email.com") .withValue(ContactsContract.Data.DATA2, "2")// data2=2即type=2,表示工作邮箱 .build();// 得到了一个添加内容的对象 operations.add(op4); getContext().getContentResolver().applyBatch("com.android.contacts", operations);// 执行批量操作 ContentProviderOperation类是为了使批量更新、插入、删除数据更加方便而引入的,在官方文档中指出推荐使用ContentProviderOperation类的原因有:1.所有的操作都在一个事务中执行,这样可以保证数据完整性;2.由于批量操作在一个事务中执行,只需要打开和关闭一个事务,比多次打开关闭多个事务性能要好些;3.使用批量操作和多次单个操作相比,减少了应用和content provider之间的上下文切换,这样也会提升应用的性能,并且减少占用CPU的时间,当然也会减少电量的消耗。2.查询(Query)
[java] view plain copy public void queryContacts(Context context) { ContentResolver cr = context.getContentResolver(); Cursor contactCursor = cr.query(ContactsContract.Contacts.CONTENT_URI, new String[] { ContactsContract.Contacts._ID }, null, null, ContactsContract.Contacts.SORT_KEY_PRIMARY);//在raw_contacts表中得到contactId if (contactCursor != null && contactCursor.getCount() > 0) while (contactCursor.moveToNext()) { long contactId = contactCursor.getLong(contactCursor .getColumnIndex(ContactsContract.Contacts._ID)); Cursor dataCursor = cr.query(ContactsContract.Data.CONTENT_URI, new String[] { ContactsContract.Data.MIMETYPE, ContactsContract.Data.DATA1, ContactsContract.Data.DATA2, ContactsContract.Data.DATA15 }, ContactsContract.Data.RAW_CONTACT_ID + "=" + contactId, null, null); if (dataCursor != null && dataCursor.getCount() > 0) { while (dataCursor.moveToNext()) { String mimeType = dataCursor .getString(dataCursor .getColumnIndex(ContactsContract.Data.MIMETYPE)); if (ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE .equals(mimeType)) { //电话号码 dataCursor .getString(dataCursor .getColumnIndex(ContactsContract.Data.DATA1)); } else if (ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE .equals(mimeType)) { //邮件 dataCursor .getString(dataCursor .getColumnIndex(ContactsContract.Data.DATA1)); } else if (ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE .equals(mimeType)) { //即时消息 } else if (ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE .equals(mimeType)) { //名字 dataCursor .getString(dataCursor .getColumnIndex(ContactsContract.Data.DATA1)); } else if (ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE .equals(mimeType)) { //头像 byte[] data = dataCursor .getBlob(dataCursor .getColumnIndex(ContactsContract.Data.DATA15)); BitmapFactory.decodeByteArray(data, 0, data.length); } else if (ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE .equals(mimeType)) { //昵称 } } } if (dataCursor != null) { dataCursor.close(); dataCursor = null; } } if (contactCursor != null) { contactCursor.close(); contactCursor = null; } }3.更新(Update)
[java] view plain copy ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); ContentProviderOperation op1 = ContentProviderOperation .newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.Data.RAW_CONTACT_ID + "=? and " + ContactsContract.Data.MIMETYPE + "=?", new String[] { String.valueOf(contactId), ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE }) .withValue( ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,// 对应data表中的data1字段 "小明").build(); ops.add(op1); ContentProviderOperation op2 = ContentProviderOperation .newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.Data.RAW_CONTACT_ID + "=? and " + ContactsContract.Data.MIMETYPE + "=?", new String[] { String.valueOf(contactId), ContactsContract.CommonDataKinds.Phone.MIMETYPE }) .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER,// 对应data表中的data1字段 "12367712322").build(); ops.add(op2); ContentProviderOperation op3 = ContentProviderOperation .newUpdate(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.Data.RAW_CONTACT_ID + "=? and " + ContactsContract.Data.MIMETYPE + "=?", new String[] { String.valueOf(contactId), ContactsContract.CommonDataKinds.Phone.MIMETYPE }) .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS,// 对应data表中的data1字段 "test@email.com").build(); ops.add(op3); try { context.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops); } catch (Exception e) { e.printStackTrace(); } 4.删除(Delete)[java] view plain copy ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); // 先删除子表Contacts中的数据 ops.add(ContentProviderOperation .newDelete(ContactsContract.Contacts.CONTENT_URI) .withSelection( ContactsContract.Contacts._ID + "=?", new String[] { String.valueOf(mContactId) }) .build()); // 然后删除子表Data中的数据 ops.add(ContentProviderOperation .newDelete(ContactsContract.Data.CONTENT_URI) .withSelection( ContactsContract.Data.RAW_CONTACT_ID + "=?", new String[] { String.valueOf(mContactId) }) .build()); // 最后删除父表RawContacts中的数据 ops.add(ContentProviderOperation .newDelete(ContactsContract.RawContacts.CONTENT_URI) .withSelection( ContactsContract.RawContacts.CONTACT_ID + "=?", new String[] { String.valueOf(mContactId) }) .build()); try { getContentResolver().applyBatch( ContactsContract.AUTHORITY, ops); } catch (Exception e) { e.printStackTrace(); }
5.根据联系人电话号码查询名字,头像等等。
[java] view plain copy //根据联系人电话号码查询名字 public static String queryNameFromContactsByNumber(Context context, String number) { String name = null; if (context != null && number != null && !"".equals(number.trim())) { Uri uri = Uri.withAppendedPath( ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI, number); Cursor nameCursor = context.getContentResolver().query(uri, new String[] { "display_name" }, null, null, null); if (nameCursor != null) { if (nameCursor.getCount() > 0) { nameCursor.moveToFirst(); name = nameCursor.getString(0); } } } return name; } [java] view plain copy //根据联系人电话查询头像 public Bitmap queryPhotoFromContactsByNumber(Context context, String number) { Bitmap bitmap = null; if (context != null && number != null && !"".equals(number.trim())) { Uri numberUri = Uri.withAppendedPath( ContactsContract.CommonDataKinds.Phone.CONTENT_FILTER_URI, number); ContentResolver cr = context.getContentResolver(); Cursor numberCursor = cr.query(numberUri, new String[] { "contact_id" }, null, null, null); if (numberCursor != null) { if (numberCursor.getCount() > 0) { numberCursor.moveToFirst(); long mContactId = numberCursor.getLong(0); Uri contactUri = ContentUris.withAppendedId( ContactsContract.Contacts.CONTENT_URI, mContactId); InputStream is = ContactsContract.Contacts .openContactPhotoInputStream(cr, contactUri); if (is != null) { bitmap = BitmapFactory.decodeStream(is); numberCursor.close(); } } } } return bitmap;6.通过raw_contacts的字段version,监听联系人的变化
[java] view plain copy /** * <br> * <b> Description: </b> 在raw_contacts表中获得联系人的version,如果联系人有更改,则version会变化 * * @return int 联系人的version */ public static int getContactVersion(Context context, long contactId) { Cursor cursor = context.getContentResolver().query( ContactsContract.RawContacts.CONTENT_URI, new String[] { ContactsContract.RawContacts.CONTACT_ID, ContactsContract.RawContacts.VERSION }, ContactsContract.RawContacts.CONTACT_ID + "=?", new String[] { String.valueOf(contactId) }, null); int version = 0; if (cursor != null && cursor.getCount() > 0) { cursor.moveToFirst(); version = cursor.getInt(cursor .getColumnIndex(ContactsContract.RawContacts.VERSION)); } if (cursor != null) { cursor.close(); cursor = null; } return version; } 到这儿联系人的Insert,Query,Update,Delete四大基本数据操作已经完成。