Android聯絡人資料庫讀取
android讀取聯絡人是通過contentprovider的介面形式來進行的,而且聯絡人操作屬於高危級別的行為,因此需要做許可權申請:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
如果是Android6.0以上系統,還需要在實際操作前申請執行時許可權,關於執行時許可權的問題這裡暫且不討論。
那麼我們首先獲取獲取一個ContentResolver物件,一般都是Context.getContentResolver()
方法,然後執行ContentResolver的query()
方法即可獲取一個Cursor物件,這個物件裡面儲存了我們從對應資料庫表查出來的所有資料。
我們首先分析一下query方法中的幾個引數,
第一個引數Uri,這個引數是指定查詢的資料位置,一般都是指定到某個表,
第二個引數String[],這個引數表示我們需要介面訪問表中的哪些欄位的資料,
第三個引數String,這個是查詢條件,相當於where語句,
第四個引數String[],這個是查詢值。比如你的第三個引數寫的是”=?”,那麼第四個引數就是表示符合條件的情況的集合,
第五個引數String,表示排序條件。
如果我們需要獲取一張表的所有資料,那麼我們可以將query方法中除Uri以外的所有引數都設為null。那麼接下來,我們就首先來獲取contacts表中的資料,這個表相當於聯絡人資料庫中的user表,在android的資料庫中,聯絡人的一些詳細資訊並不存在於contacts表中,而且存在其它表裡面,contacts就是儲存其他表中的一些id來關聯這些資料。查詢的方法如下:
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
以上這個cursor物件裡面就儲存了contacts表中的所有資訊,接下來就是根據contacts儲存的關聯資訊來獲取聯絡人的一些實際資訊了。
我們首先來獲取聯絡人的姓名相關的資訊,姓名相關的資訊主要是儲存在raw_contacts表中,該表的URI是ContactsContract.RawContacts.CONTENT_URI
。
然後是關鍵的電話號碼資訊,電話號碼的資訊儲存在data表中,這個表其實不只儲存了電話號碼,還包括姓名、郵箱、社交帳號、家庭住址等等資訊。而且這裡面的資料不是一個聯絡人對應的一條資料,而是多個聯絡人對應有多條資料。我們可以根據該表中的mimetype_id
data1
到data15
這15個欄位中。 以上分析就到此為止,下面是具體的程式碼:
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(ContactsContract.RawContacts.CONTENT_URI, null, null, null, null);
if (cursor != null && cursor.getCount() > 0 ) {
cursor.moveToFirst();
while (cursor.moveToNext()) {
int userId = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Cursor dataCursor = resolver.query(ContactsContract.Data.CONTENT_URI, null, ContactsContract.Data.RAW_CONTACT_ID + "=" + userId, null, null);
if (dataCursor != null && dataCursor.getCount() > 0) {
dataCursor.moveToFirst();
while (dataCursor.moveToNext()) {
String mimeType = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.MIMETYPE));
//電話號碼
if ("vnd.android.cursor.item/phone_v2".equals(mimeType)) {
//這裡DATA1和DATA4都儲存的是電話號碼 但是DATA1的資料裡面有短橫線或者空格
//注意 這裡phone可能存在多個 後面的內容也有可能為空
String phone = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DATA4));
//姓名
} else if ("vnd.android.cursor.item/name".equals(mimeType)) {
//DATA1表示姓名全稱
String displayName = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DATA1));
//DATA2表示名
String firstName = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DATA2));
//DATA3表示姓
String lastName = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DATA3));
//電子郵箱
} else if ("vnd.android.cursor.item/email_v2".equals(mimeType)) {
String email = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DATA1));
}
//這裡mimeType有很多種型別 這裡就暫時例舉了三種 如果想了解更多型別
// 可以進入系統/data/data/com.android.providers.contacts/databases/目錄下面
//提取一個名為contacts2.db的資料庫檔案 檢視mimetypes表和data表
}
}
if (dataCursor!=null){
dataCursor.close();
}
}
}
if (cursor!=null){
cursor.close();
}
以上是一種查詢方式,但是這種查詢方式會有點麻煩,下面推薦一種更加簡單的查詢方式:
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID);
if (cursor != null) {
cursor.moveToFirst();
while (cursor.moveToNext()) {
//注意 如果某個聯絡人有多個電話 這裡會出現多條 rawId相同 但是phone不同的資料
int rawId = cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID));
String phone = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER));
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
}
cursor.close();
}