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 usersString[] 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 userString[] 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 numbersString[] 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;}