1. 程式人生 > >Android聯絡人資料庫讀取

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

欄位來區分這條資料究竟是姓名資訊還是電話資訊或者郵箱資訊。具體的資料則儲存在data1data15 這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();
        }