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

    在上一章 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四大基本数据操作已经完成。
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值