2025年4月15日 星期二 乙巳(蛇)年 正月十六 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > 安卓(android)开发

Android中联系人和通话记录详解(联系人的增删改查)(3)

时间:03-05来源:作者:点击数:9

在上一章Android中联系人和通话记录详解(2)中分析了联系人相关的表和字段,在这一章中将分析联系人相关的基本数据操作(Insert,Query,Update,Delete)。

1.添加(Insert)

从contacts,data,mimetypes,raw_contacts表的关系可以看出,表raw_contacts为表data的父表,所以插入数据时,应该先在raw_contacts表中插入数据,再在data表中插入数据。

  • 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)

  • 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)

  • 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)

  • 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.根据联系人电话号码查询名字,头像等等。

  • //根据联系人电话号码查询名字
  • 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;
  • }
  • //根据联系人电话查询头像
  • 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,监听联系人的变化

  • /**
  • * <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四大基本数据操作已经完成。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐