1. 程式人生 > >Android中聯絡人和通話記錄詳解(聯絡人的增刪改查)(3)

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, "
[email protected]
") .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欄位
						"[email protected]").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四大基本資料操作已經完成。

相關推薦

Android聯絡人和通話記錄(聯絡人刪改)3

    在上一章 Android中聯絡人和通話記錄詳解(2)中分析了聯絡人相關的表和欄位,在這一章中將分析聯絡人相關的基本資料操作(Insert,Query,Update,Delete)。    1.新增(Insert)      從contacts,data,mimety

Android聯絡人和通話記錄2

  在文章Android中聯絡人和通話記錄詳解(1)中對通話記錄進行了分析,本章將對聯絡人的資料庫表、欄位以及Insert,Query,Delelte,Update四大基本資料操作進行分析。   與聯

在java對數據庫進行刪改

ima ive upd line 增加 key get cat imp 1.java連接MySql數據庫 代碼區域: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

資料庫簡單的刪改CRUD

一切都是基於資料,而對資料的管理都離不開資料庫。最近學到資料庫的簡單操作,所以寫下這篇文章,總結一下學習到的知識。淺陋之處,多多見諒。 補充一下:一直弄不清SQL Server,Mysql ,以及Oracle的關係。SQL Server是微軟的,因為微軟系統的市場佔有額

Android匯入的java包

 Android Java包在實際應程式開發中的作用是非常重要的。對於初學者來說必須要將這些包中的內容做一個詳細的瞭解,以方便我們將來的應用。 熟悉Android作業系統的朋友都知道,開發Android應用程式基本上使用的都是Java語言。那麼要想靈活的應用這一系統,就

Android圖片的三級快取

圖片的三級快取機制一般是指應用載入圖片的時候,分別去訪問內容,檔案,網路獲取圖片的一種行為。 一、三級快取流程圖 三級快取流程圖 二、程式碼框架搭建 這裡我仿造 Picasso 的載入圖片程式碼,也做出了with,load,into等方法。 2.1 with(c

Android 使用MediaRecorder進行錄影視訊錄製

在這裡給出自己的一個測試DEMO,裡面註釋很詳細。簡單的視訊錄製功能. package com.demo; import java.io.IOException; import android.app.Activity; import android

Android記憶體洩漏超級精煉

一、前期基礎知識儲備 (1)什麼是記憶體? JAVA是在JVM所虛擬出的記憶體環境中執行的,JVM的記憶體可分為三個區:堆(heap)、棧(stack)和方法區(method)。 棧(stack):是簡單的資料結構,但在計算機中使用廣泛。棧最顯著的特徵是:LIF

Android的介面回撥,回撥機制:以Activity和Adapter傳遞資料為例。

首先解決啥是回撥: 我覺得這個例子比較好:某天,我打電話向你請教問題,當然是個難題,你一時想不出解決方法,我又不能拿著電話在那裡傻等,於是我們約定:等你想出辦法後打手機通知我,這樣,我就掛掉電話辦其它事情去了。過了XX分鐘,我的手機響了,你興高采烈的說問題已經搞定,應該

Androidmeasure過程、WRAP_CONTENT以及xml佈局檔案解析流程淺析(上)

  繪製流程的三個步驟,即:                      1、  measure過程 --- 測量過程                      2、 layout 過程     --- 佈局過程                      3、 draw 過程

Android的Style、Theme已經發展史

Style介紹 style就像單詞意思一樣,風格,這裡面是屬性的集合,如果頁面中有許多控制元件的屬性值相同那麼就可以把這些屬性抽出來放到style裡面,定義也很簡單,在values檔案下的styles裡面建立就可以了。 例如: Styl

Android沉浸式狀態列

前言 地上斷了翅的蝶,霧散之後的滿月,原來愛跟心碎,都可以很細節。 簡介 這兩天時間比較充裕,所以實現了專案裡的沉浸式狀態列效果,這樣可以使得我們的app主題顯得更加統一。所以今天就帶領大家實現下不同情況下的狀態列效果顯示。 一 狀態列顏色改變

Android 動畫】動畫之補間動畫

前言 :之前很早就想寫寫Android 的動畫,最近剛好有時間,大概聊一聊安卓動畫。 我個人習慣將動畫分為:補間動畫(透明度、旋轉、位移、縮放)、幀動畫、和屬性動畫,這一篇,我們先說說補間動畫。 補間動畫這個詞出於flash,在兩個關鍵幀(可以理解成動畫開始和結束)中間需要做“補

Android 動畫】動畫之插值器

大家好,在上一篇中,我們介紹了Android 的補間動畫,這一篇我們來說說動畫的另外一個公共屬性插值器Interpolator 【Android 動畫】動畫詳解之補間動畫(一) 在上一節中,實現的旋轉、位移動畫等動畫,我們會發現它一直是勻速的,但如果我們需要做一個加

Android塗鴉畫板原理——從初級到高階

前言 前面寫了《Android塗鴉畫板原理詳解——從初級到高階(一)》,講了塗鴉原理初級和中級的應用,現在講解高階應用。如果沒有看過前面一篇文章的同學,建議先去看看哈。 準備 高階塗鴉涉及到圖片操作,包括對圖片進行縮放移動、塗鴉等,這裡涉及到矩陣的變換。關於矩陣

OSI七層之四 傳輸層Transport

http 計算機 地址 包括 分組 tcp aik 全部 滿足 一、簡介   第四層的數據單元也稱作數據包(packets)。但是,當你談論TCP等具體的協議時又有特殊的叫法,TCP的數據單元稱為段(segments)而UDP協議的數據單元稱為“數據報(datagrams)

串口驅動程序設計---串口初始化

flag more ini board 幾分鐘 cor configure 設計 rom 串口驅動程序設計詳解---串口初始化(上) 原創 2016年05月19日 23:51:13 標簽: 串口驅動初始化流程 / 內核源碼分析 / linux / ARM / 架構

C#特性和反射

typeinfo ref 都是 system.in 全局 color com 依然 程序   類型信息(Type Information)用來表示類型聲明的信息,通過抽象基類System.Type的實例存儲這些信息,當使用反射時,CLR獲取指定類型的Type對象,通過這個對

通過,認識遞迴recursion

首先先對遞迴進行入門。 遞迴是以自相似的方式重複專案的過程。在程式語言中,如果程式允許您在同一函式內呼叫函式,則稱其為函式的遞迴呼叫。 簡而言之,遞迴就是函式的自身呼叫。可以看看下面的遞迴使用: void Recursive() { Recursive();//call itself

gh0st遠控原始碼圖文Gh0st通訊協議解析1

與大家分享下gh0st通訊的全過程解析。瞭解gh0st的通訊上線發包全過程,網上有很多相關資料,自己在總結了下。希望對初學者有幫助少走彎路,gh0st的核心是個不錯的經典值得學習。轉載請註明: 速維網路 Gh0st通訊協議解析(1)  gh0st遠控原始碼釋出至今已有不少