標籤:
一、目標。
通過內容解析器擷取手機連絡人資訊,並採用自訂的樣式顯示。
為了便於介紹和重複使用,重建立立一個”讀取連絡人“工程。
二、代碼實現。
1、建立工程,取名為”讀取連絡人“。在布局檔案(activity_main.xml)中,採用ListView組件(其ID為select_contact)。
布局檔案代碼:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 tools:context=".MainActivity" > 6 7 <ListView 8 android:id="@+id/select_contact" 9 android:layout_width="wrap_content"10 android:layout_height="wrap_content" />11 12 </RelativeLayout>
View Code
2、在主程式中執行個體化ListView組件(取名select_contact),並通過findViewById()方法找到布局檔案中的ListView對象。select_contact對象需要通過適配器的方法(setAdapter(ListAdapter adapter))將相關資料填充進去,其中ListAdapter adapter採用SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)。而SimpleAdapter中的第二個參數List就是需要顯示的資料,因此需要通過自訂的方法(取名getContactInfo())擷取手機中連絡人的資訊並形成一個List集合。
3、在主程式中建立擷取手機連絡人資訊的方法(取名getContactInfo()),傳回值類型為List<Map<String, String>>。在該方法中:
①.通過getContentResolver()得到一個內容解析器(ContentResolver)對象,取名(resolver)。由於需要讀取手機連絡人,因此需要擷取許可權(android.permission.READ_CONTACTS)。
②.利用內容解析器的query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)方法尋找手機裡連絡人資料內的相關資料,參數中Uri為需要查詢的資料庫的Uri地址,String[] projection為需要返回的列名,String selection為查詢條件,String[] selectionArgs為查詢條件參數,String sortOrder為是否排序。該方法的傳回值為Cursor對象,Cursor對象就類似於一張表格,列數等於查詢條件的個數,行數等於資料庫中符合查詢條件的資料的行數,該對象在使用完之後需要及時關閉。
③.本例中需要查詢連絡人資料中的raw_contacts表(其Uri為“content://com.android.contacts/raw_contacts”和data表(其Uri為“content://com.android.contacts/data”)。在raw_contacts表中查詢列名為“contact_id”的列,該列儲存了所有連絡人的id。然後通過while迴圈判斷查詢出的Cursor對象是否還有下一個,如有則通過getString(int columnIndex)方法擷取。由於查詢條件只有一個,所以該Cursor對象只有一列,因此getString方法中的參數只能為0,注意參數是指列的角標。
④根據查出的每一個id判斷其是否為空白,不為空白則再通過內容解析器的query方法查詢data表中,需要查詢的列名為“data1”和“mimetype”,查詢條件和參數為contact_id和其值。再通過while迴圈判斷查詢出的Cursor對象時候還有下一個,如有則通過getString(int columnIndex)方法擷取該Cursor對象裡面的資料,其中第一列是data1資料,第二列是mimetype資料。
⑤.根據mimetype資料的值通過equal方法判斷所擷取的資料是連絡人姓名還是電話號碼,如果其值為“vnd.android.cursor.item/name”,則獲得的資料data1為連絡人姓名,如果其值為“vnd.android.cursor.item/phone_v2”,則獲得資料data1為連絡人電話。
⑥.在建立方法getContactInfo()中建立一個List<Map<String, String>> 的List對象,用於儲存取出的所有連絡人資訊,在第四步中通過if語句判斷id不為空白後建立Map<String, String>對象,用於儲存一個連絡人的“name”和“phone”資訊(注意,由於List對象和Map對象均為介面類型,因此建立時採用其子類)。然後再第五步中判斷資料為連絡人姓名還是電話後將其放入Map對象中。
⑦.一個連絡人資訊放入一個Map對象後,通過add方法將該Map對象放入連絡人List對象中,最後返回List對象。
建立擷取手機連絡人資訊的方法(名為getContactInfo())代碼:
1 private List<Map<String, String>> getContactInfo() { 2 //擷取內容解析器 3 ContentResolver resolver = getContentResolver(); 4 List<Map<String, String>> listContacts = new ArrayList<Map<String,String>>(); 5 //擷取手機連絡人資料庫相關表的Uri 6 Uri uri = Uri.parse("content://com.android.contacts/raw_contacts"); 7 Uri uriData = Uri.parse("content://com.android.contacts/data"); 8 //查詢資料表中的相關資料 9 Cursor cursor = resolver.query(uri, new String[] { "contact_id" },10 null, null, null);11 while (cursor.moveToNext()) {12 String contact_id = cursor.getString(0);13 if (contact_id != null) {14 //具體的某一個連絡人15 Map<String,String> mapContact = new HashMap<String, String>();16 Cursor dataCursor = resolver.query(uriData, new String[] {17 "data1", "mimetype" }, "contact_id=?",18 new String[] { contact_id }, null);19 while(dataCursor.moveToNext()){20 String data1 = dataCursor.getString(0);21 String mimetype = dataCursor.getString(1);22 if("vnd.android.cursor.item/name".equals(mimetype)){23 //連絡人姓名 24 mapContact.put("name", data1);25 }else if("vnd.android.cursor.item/phone_v2".equals(mimetype)){26 //連絡人的電話號碼27 mapContact.put("phone", data1);28 }29 }30 //將每個連絡人放入List對象中31 listContacts.add(mapContact);32 //關閉Cursor對象33 dataCursor.close();34 }35 }36 //關閉Cursor對象37 cursor.close();38 return listContacts;39 }View Code
4、在主方法中通過setAdapter(ListAdapter adapter)方法為主布局檔案載入資料和單條資料顯示的樣式。
①.在layout檔案夾下建立一個XML檔案用於製作單條資料顯示的樣式。文本顯示格式、大小、相片順序等均可自訂。
單條資料顯示樣式的XML檔案代碼:
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" > 6 7 <TextView 8 android:id="@+id/contact_item_name" 9 android:layout_width="match_parent"10 android:layout_height="wrap_content"11 android:text="姓名" 12 android:textSize="22sp"/>13 14 <TextView15 android:id="@+id/contact_item_phone"16 android:layout_width="match_parent"17 android:layout_height="wrap_content"18 android:text="電話號碼" />19 20 </LinearLayout>
View Code
②.由於ListAdapter對象是介面,所以建立其子類SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)傳入,該方法中第一個參數為上下文(這是this),第二個參數為需要顯示的資料(即連絡人的List對象),第三個參數為單條資料想要顯示的樣式的id(即contact_item_view的id),第四個參數和第五個參數分別表示要顯示的資料中的某一個資料與樣式中要顯示位置的對應關係(均以數組的形式對應)。
Android執行個體-手機安全衛士(二十六)—擷取手機內連絡人資訊