Android通訊錄數據庫介紹與基本操作(增刪改查)
2014年2月21日
Android通訊錄管理總結
這幾天導師安排我一個任務就是研究一下Android通訊錄獲取聯系人、通話記錄、短信的方法,還有看看不同Android版本之間的異同是否能做到兼容之類的事情。Android通訊錄這一塊,我個人感覺是挺亂的,網上一堆關於查詢本地數據庫獲取聯系人的方法,但似乎都沒有仔細說明數據有哪些重要的表,它們之間有什麼聯系。下面是本人查詢資料總結的一下知識點,方便童鞋們以後用到。
Android聯系人數據庫文件(contact2.db)
有研究過手機通訊錄數據的童鞋肯定知道一個數據庫文件:目前是contact2.db(哥的手機是Android4.04的)
在此路徑下可以找到:/data/data/com.android.providers.contacts/databases/contact2.db
將其導入可視化數據庫管理器當中(我這裡用的是SQLiteDatabase Browser)
有以上那麼多張表,看到頭暈的有木有,我們主要關註一些比較重要的表就行瞭。
vcD4KPHA+0tTJz87S08O67L/yserWvrXEysexyL3P1tjSqrXEvLi49rHto7o8L3A+CjxwPjGhomNvbnRhY3Rzse08L3A+CjxwPiAgICAgICAgILjDse2xo7TmwcvL+dPQtcTK1rv6suLBqs+1yMujrMO/uPbBqs+1yMvVvNK70NCjrLjDse2xo7TmwcvBqs+1yMu1xENvbnRhY3RJRKGiwarPtbTOyv2hotfuuvPSu7TOwarPtbXEyrG85KGiyse38bqs09C6xcLroaLKx7fxsbvM7bzTtb3K1bLYvNC1yNDFz6KhozwvcD4KPHA+MqGicmF3X2NvbnRhY3Rzse08L3A+CjxwPiAgICAgICAgILjDse2xo7TmwcvL+dPQtLS9qLn9tcTK1rv6suLBqs+1yMujrMO/uPbBqs+1yMvVvNK70NCjrLHtwO/T0NK7wdCx6sq2uMPBqs+1yMvKx7fxsbvJvrP9o6y4w7HtsaO05sHLwb249klEo7ogUmF3Q29udGFjdElEus1Db250YWN0SUQstNO2+L2rY29udGFjdHOx7brNcmF3X2NvbnRhY3Rzse3Bqs+1xvDAtKGjuMOx7bGjtObBy8Gqz7XIy7XEUmF3Q29udGFjdElEoaJDb250YWN0SUShosGqz7W0zsr9oaLX7rrz0ru0zsGqz7W1xMqxvOShosrHt/Gxu8ztvNO1vcrVsti80KGiz9TKvrXEw/vX1qGi08PT2sXF0PK1xLq60+/GtNL0tcjQxc+ioaM8L3A+CjxwPjOhoiBtaW1ldHlwZXMgse08L3A+CjxwPrjDse22qNLlwcvL+dPQtcRNaW1lVHlwZUlEo6y8tMGqz7XIy7XEuPe49tfWts61xM6o0rux6ta+oaM8L3A+CjxpbWcgc3JjPQ==”/uploadfile/Collfiles/20140222/20140222090656109.png” alt=”\”>
4、data表
? 該表保存瞭所有創建過的手機測聯系人的所有信息,每個字段占一行 ,該表保存瞭兩個ID: MimeTypeID和RawContactID,從而將data表和raw_contacts表聯系起來。
? 聯系人的所有信息保存在列data1至data15中,各列中保存的內容根據MimeTypeID的不同而不同。如保存號碼(MimeTypeID=5)的那行數據中,data1列保存號碼,data2列保存號碼類型(手機號碼/傢庭號碼/工作號碼等)。
對聯系人的基本操作(增刪改查)
權限設置
讀取聯系人
分為以下步驟:
1、先讀取contacts表,獲取ContactsID;
2、再在raw_contacts表中根據ContactsID獲取RawContactsID;
3、然後就可以在data表中根據RawContactsID獲取該聯系人的各數據瞭。
private void queryContacts() { // 獲取用來操作數據的類的對象,對聯系人的基本操作都是使用這個對象 ContentResolver cr = getContentResolver(); // 查詢contacts表的所有記錄 Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); // 如果記錄不為空 if (cursor.getCount() > 0) { // 遊標初始指向查詢結果的第一條記錄的上方,執行moveToNext函數會判斷 // 下一條記錄是否存在,如果存在,指向下一條記錄。否則,返回false。 while (cursor.moveToNext()) { String rawContactId = ""; // 從Contacts表當中取得ContactId String id = cursor.getString(cursor .getColumnIndex(ContactsContract.Contacts._ID)); Log.v("contactID", id); // 獲取RawContacts表的遊標 Cursor rawContactCur = cr.query(RawContacts.CONTENT_URI, null, RawContacts._ID + "=?", new String[] { id }, null); // 該查詢結果一般隻返回一條記錄,所以我們直接讓遊標指向第一條記錄 if (rawContactCur.moveToFirst()) { // 讀取第一條記錄的RawContacts._ID列的值 rawContactId = rawContactCur.getString(rawContactCur .getColumnIndex(RawContacts._ID)); Log.v("rawContactID", rawContactId); } // 關閉遊標 rawContactCur.close(); // 讀取號碼 if (Integer .parseInt(cursor.getString(cursor .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) { // 根據查詢RAW_CONTACT_ID查詢該聯系人的號碼 Cursor phoneCur = cr .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID + "=?", new String[] { rawContactId }, null); // 上面的ContactsContract.CommonDataKinds.Phone.CONTENT_URI // 可以用下面的phoneUri代替 // Uri // phoneUri=Uri.parse("content://com.android.contacts/data/phones"); // 一個聯系人可能有多個號碼,需要遍歷 while (phoneCur.moveToNext()) { // 獲取號碼 String number = phoneCur .getString(phoneCur .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); Log.v("number", number); // 獲取號碼類型 String type = phoneCur .getString(phoneCur .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)); Log.v("type", type); } phoneCur.close(); } } cursor.close(); } }
新建聯系人
新建聯系人時, 根據contacts、raw_ contacts兩張表中ID的使用情況,自動生成ContactID和RawContactID。
Android源碼新建重復姓名的聯系人的ContactID是不重復的,所以會重復顯示。
用下面的代碼新建聯系人,如果多次新建的聯系人的姓名是一樣的,生成的ContactID也會重復, RawContactID不會重復,我們在讀取聯系人的時候可以獲取所有同姓名聯系人的號碼等信息,在顯示聯系人的時候,重復姓名的聯系人的所有字段信息都會合並起來顯示為一個聯系人。
public void addContact(String name, String phoneNum) { ContentValues values = new ContentValues(); Uri rawContactUri = getContentResolver().insert( RawContacts.CONTENT_URI, values); long rawContactId = ContentUris.parseId(rawContactUri); // 向data表插入數據 if (name != "") { values.clear(); values.put(Data.RAW_CONTACT_ID, rawContactId); values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE); values.put(StructuredName.GIVEN_NAME, name); getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values); } // 向data表插入電話號碼 if (phoneNum != "") { values.clear(); values.put(Data.RAW_CONTACT_ID, rawContactId); values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); values.put(Phone.NUMBER, phoneNum); values.put(Phone.TYPE, Phone.TYPE_MOBILE); getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values); } }
刪除聯系人
Android幫助文檔:When a raw contact is deleted, all of its Data rows as well asStatusUpdates, AggregationExceptions, PhoneLookup rows are deleted automatically.
所以,要刪除聯系人,我們隻需要將raw_contacts表中指定RawContactID的行刪除,其他表中與之關聯的數據都會自動刪除。
// 刪除聯系人 public void deleteContact(long rawContactId) { getContentResolver().delete( ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), null, null); }
更新聯系人
聯系人的所有信息都是保存在data表中,所以要更新聯系人,我們隻需要根據RawContactID和MIMETYPE修改data表中的內容。
// 更新聯系人 public void updataCotact(long rawContactId) { ContentValues values = new ContentValues(); values.put(Phone.NUMBER, "13800138000"); values.put(Phone.TYPE, Phone.TYPE_MOBILE); String where = ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?"; String[] selectionArgs = new String[] { String.valueOf(rawContactId), Phone.CONTENT_ITEM_TYPE }; getContentResolver().update(ContactsContract.Data.CONTENT_URI, values, where, selectionArgs); }
以上就是本篇博客的所有內容,不知道小巫說清楚瞭沒有?關於Android相關的知識點,還是需要多查資料和總結才能比較熟悉,查看官方文檔是最直接的方式,如果閱讀全英文有困難的話就看看別人總結的東西吧。下篇博客會做一個demo來提供一種方法查詢所有聯系人、通話記錄、短信。