內容提供是實質上是個接口,后門,他給別人提供數據,系統聯系人是個比較復雜的內容通過者。
找到/data/data/com.android.providers.contacts/contacts2.db
這個目錄下還有個文件contacts2.db.-journal,這個文件和數據庫的事務相關
聯系人應用數據庫的主要結構
raw_contacts 聯系人表 contact_id 聯系人id
data數據表 raw_contact_id聯系人id,mimetype_id數據類id,data1數據
mimetypes類型表 1 email,5 phone,7 name
查詢所有的聯系人信息:
- 查詢raw_contacts表把聯系人id取出來
- 根據id查詢data表,把所有的數據取出來
- 根據數據的mimetype_id查詢mimetypes表獲取數據的業務類型
查詢系統源代碼,找到providers/Contacts相關的,先找清單文件,看到<Provider>節點,name屬性和authories屬性,主機名部分是分號隔開的contacts;com.android.contacts 低版本是前一個,高版本是后一個。
找到源碼定義規則的地方UriMatcher對象的地方,看實際規則,一般是表名,因此實際Uri路徑是 content://com.android.contacts/表名
獲取ContentResolver對象,調用對象的query(uri)方法,參數:Uri就是路徑
得到Cursor對象,循環Cursor對象
讀取content://com.android.contacts/raw_contacts沒問題
讀取content://com.android.contacts/data 時出現錯誤,mimetype_id字段不存在,實際走的視圖表,當你不確定字段的時候,調用Cursor對象的getColumnNames()方法,返回字段數組,打印一下
這里字段應該是data1和mimetype
調用Cursor對象的query()方法,注意寫上條件,”raw_contact_id=?” 和值new String[]{id}
世面上的很多應用都是取出了聯系人的信息,社交應用一般都有發送信息給對方,讀取系統聯系人
需要定義權限:<uses-permission android:name="android.permission.READ_CONTACTS"/>
注意:如果一個賬號被刪除了,他不是真正的刪除而是把raw_contacts表里面的contact_id寫為null了,查詢的時候應該加個判斷是否為空!=null
activity:
ContentResolver resolver=getContentResolver(); Uri uri=Uri.parse("content://com.android.contacts/raw_contacts"); Uri dataUri=Uri.parse("content://com.android.contacts/data"); //循環聯系人表 Cursor cursor=resolver.query(uri, null, null, null, null); while(cursor.moveToNext()){ String id=cursor.getString(cursor.getColumnIndex("contact_id")); //查找數據表 Cursor dataCursor=resolver.query(dataUri, null,"raw_contact_id=?", new String[]{id}, null); while(dataCursor.moveToNext()){ String data1=dataCursor.getString(dataCursor.getColumnIndex("data1")); String mimetype=dataCursor.getString(dataCursor.getColumnIndex("mimetype")); System.out.println("data1:"+data1+",mimetype:"+mimetype); } System.out.println("=========="); }