Android聯繫人讀取操作筆記

Android中的聯繫人都保存在一個SQLite數據庫中,有興趣的可以使用adb直接push出來看一下里面的表和視圖的結構,

它的路徑爲:/data/data/com.android.providers.contacts/databases/contacts2.db


在聯繫人數據庫中,保存的都是一些小的數據表,即與把所有數據保存成一個表不同,它會對聯繫人的資料模塊化,然後分成多個表保存。

表與表之間使用id相關聯起來,這樣做的目的是儘量減小數據表的規模,提高數據檢索的速度,因爲我們檢索的時候不是每次都需要讀取所有的聯繫人資料的,這樣可以更靈活的選擇我們所關心的內容,提高檢索速度,

雖然分開的保存數據,可以提高檢索的速度,但是也給我們帶來了一些不便,就是需要把這些分開的表再重新聯合起來,組成我們所需要的完整的數據。好在這些,android已經替我們準備好了,它在數據庫裏面建了一些視圖,呵呵,視圖就是虛擬表。並且,android也提供了很多接口,通過ContentResolver().query方法,傳入不同的URI即可訪問相應的數據集。

在聯繫人數據庫裏面聯繫人和電話號碼是分別存在兩個表裏面的,因爲存在一個聯繫人擁有幾個號碼的情況,所以android爲聯繫人和手機號碼分別單獨創建了相應的視圖。

聯繫人信息的視圖裏面只保存與聯繫人相關的資料,例如姓名,是否有手機號碼等。

而手機號碼資料則是每一個電話號碼爲一條記錄,如果有一個聯繫人有3個號碼,則裏面會出現3個該聯繫人的記錄,號碼分別爲他的三個號碼。


如果是需要讀取聯繫人信息,傳入的URI爲:ContactsContract.Contacts.CONTENT_URI

如果是需要讀取手機號碼信息傳入的URI爲:ContactsContract.CommonDataKinds.Phone.CONTENT_URI


下面再看看query函數的原型,只讀取關心的字段,應該可以提高一點速度

query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

projection:是需要讀取的字段

selection:是數據檢索的條件

selectionArgs:是數據檢索條件的參數

sortOrder:是排序的字段

在android聯繫人表裏面一個兩個比較有意思的字體sort_key和sort_key_alt,它裏面保存的是聯繫人名字的拼音字母,

例如聯繫人名字是“李明”,則sort_key保存的是“LI李MING明”,這樣如果是按sort_key或sort_key_alt排序的話,就可以實現按漢字的拼音字母排序了,,,


下面給讀取系統所有聯繫人的代碼片段,讀取所有的聯繫人,然後每讀一個聯繫人,再把該聯繫人的所有號碼讀出來

(這個因爲需要不斷的去檢索數據庫,所以會很慢,大家有什麼方法提高SQLite數據庫的檢索的方法沒??):

	// the selected cols for contact users
	String[] selectCol = new String[]{
			ContactsContract.Contacts.DISPLAY_NAME,
			ContactsContract.Contacts.HAS_PHONE_NUMBER,
			ContactsContract.Contacts._ID
		};
	public static final int COL_NAME = 0;
	public static final int COL_HAS_PHONE = 1;
	public static final int COL_ID = 2;
	
	// the selected cols for phones of a user
	String[] selPhoneCols = new String[] {
			ContactsContract.CommonDataKinds.Phone.NUMBER,
			ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
			ContactsContract.CommonDataKinds.Phone.TYPE
	};
	public static final int COL_PHONE_NUMBER = 0;
	public static final int COL_PHONE_NAME = 1;
	public static final int COL_PHONE_TYPE = 2;
	
	
	public void getContactList() {
		String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
        + Contacts.HAS_PHONE_NUMBER + "=1) AND ("
        + Contacts.DISPLAY_NAME + " != '' ))";
		
		list = new ArrayList<ContactItemData>();
		Cursor cursor = this.getContentResolver().query(
				ContactsContract.Contacts.CONTENT_URI, selectCol, select, null, 
				ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
		if (cursor ==null) {
			Toast.makeText(this, "cursor is null!", Toast.LENGTH_LONG).show();
			return;
		}
		if (cursor.getCount() == 0) {
			Toast.makeText(this, "cursor count is zero!", Toast.LENGTH_LONG).show();
			return;
		}
		
		
		cursor.moveToFirst();
		while(!cursor.isAfterLast()) {
			int contactId;
			contactId = cursor.getInt(cursor.getColumnIndex(
				ContactsContract.Contacts._ID));
			if (cursor.getInt(COL_HAS_PHONE)>0) {
				// the contact has numbers
				// 獲得聯繫人的電話號碼列表
				String displayName;
				displayName = cursor.getString(COL_NAME);
                Cursor phoneCursor = getContentResolver().query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        selPhoneCols,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                + "=" + contactId, null, null);
                if(phoneCursor.moveToFirst()) {
                    do 
                    {
                        //遍歷所有的聯繫人下面所有的電話號碼
                        String phoneNumber = phoneCursor.getString(COL_PHONE_NUMBER);

                        ContactItemData data = new ContactItemData();
                        String phoneFiled = new String();
                        data.name = displayName;
                        data.number = phoneFiled + ":" + phoneNumber;
                        data.check = false;
                        list.add(data);
                    }while(phoneCursor.moveToNext());
                }
			}
			cursor.moveToNext();
		}
	}

讀取所有號碼的片段:

	/**
	 * Yao.GUET
	 * Blog: http://blog.csdn.net/Yao_GUET
	 */
	// the selected cols for phones numbers
	String[] selPhoneCols = new String[] {
			ContactsContract.CommonDataKinds.Phone.NUMBER,
			ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
			ContactsContract.CommonDataKinds.Phone.TYPE,
			ContactsContract.CommonDataKinds.Phone.LABEL,
			ContactsContract.CommonDataKinds.Phone._ID
	};
	public static final int COL_PHONE_NUMBER = 0;
	public static final int COL_PHONE_NAME = 1;
	public static final int COL_PHONE_TYPE = 2;
	public static final int COL_PHONE_LABEL = 3;
	
	public ContactsCursorAdapter getContactCursorList() {
			String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
	        + Contacts.DISPLAY_NAME + " != '' ) AND ("
	        + ContactsContract.CommonDataKinds.Phone.NUMBER + " NOTNULL) AND ("
	        + ContactsContract.CommonDataKinds.Phone.NUMBER + " != ''))";
			
			Cursor cursor = this.getContentResolver().query(
	                ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
	                selPhoneCols, select, null,
	                "sort_key_alt"
	                );
			ContactsCursorAdapter adapter = new ContactsCursorAdapter(this, 
					R.layout.contact_item, cursor);
			return adapter;
	}


發佈了79 篇原創文章 · 獲贊 6 · 訪問量 91萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章