日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

利用Contacts Provider读取手机联系人信息

發布時間:2023/12/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 利用Contacts Provider读取手机联系人信息 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考:https://developer.android.google.cn/guide/topics/providers/contacts-provider.html

Contacts Provider組織結構

Contacts Provider組織結構由三部分構成,如下圖所示:

  • (聯系人)Contact:代表聯系人,包含了多種聯系渠道。
  • (原始聯系人)RawContact:每個原始聯系人代表某個聯系人的一種具體的聯系渠道,比如E-mail、手機通訊錄、推特等等。
  • (數據)Data:儲存大多數實際的信息,比如手機號碼、郵箱地址等等。

舉例說明:假設手機用戶為A,它有一個聯系人B。A與B通過電子郵件、電話、推特三種渠道產生過聯系,那么聯系人B就對應三個原始聯系人B,每個原始聯系人B中會記錄一種聯系渠道(A使用的聯系賬戶、賬戶類型),而具體的信息(手機號碼、郵箱地址)會存放在數據表中。

Contact表、RawContact表、Data表之間的聯系

Contact、RawContact、Data分別對應三張數據庫表,三張表都有一個_ID字段作為主鍵。在此基礎上,RawContact表有一個CONTACT_ID列,代表這個原始聯系人對應的聯系人的_ID;Data表有一個Raw_CONTACT_ID列,代表這個數據行對應的原始聯系人的_ID。
因此,查詢某個聯系人的某項信息的一般步驟為:

  • 在Contact表中查到該聯系人對應的ID;
  • 在RawContact表中查到該聯系人ID對應的原始聯系人的ID;
  • 在Data表中查到原始聯系人ID對應的數據行,并通過投影取得需要的數據。
  • 實例:獲取手機通訊錄中所有聯系人對應的手機號碼

    下面是一個用于加載聯系人手機號碼信息的ContactManager類,具有以下功能:

    • 判斷應用是否具有讀取手機通訊錄的權限android.permission.READ_CONTACTS。
    • 可以在創建對象時即開始加載,也可以在需要時再加載。
    • 在子線程中執行查詢,不會阻塞UI線程。
    • 加載結束后通過一個UnmodifiableMap返回聯系人姓名到電話號碼的映射。
    • 支持設置加載完畢后執行的回調。

    使用方法:通過靜態方法getService()獲取ContactManager實例,并設置是否需要立即開始加載、監聽器等附加信息。

    import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; import android.database.Cursor; import android.provider.ContactsContract; import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.util.SparseArray;import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map;/*** Created by swt369 on 2017/10/1.* Provide a simple way for managing contacts*/public class ContactManager {private static final Map<Context,ContactManager> INSTANCES = new HashMap<>();private final Context context;private OnFinishLoadListener onFinishListener;private boolean loaded = false;private Map<String,List<String>> nameToCallNumbers = null;private ContactManager(Context context, boolean loadAtOnce, @Nullable OnFinishLoadListener onFinishListener){this.context = context;this.onFinishListener = onFinishListener;if(loadAtOnce){load();}}/**** @param context The context the Manager is running in* @param loadAtOnce True if needed to load at once* @param onFinishListener the callback that will be invoked when the loading is over * @return A instance of the ContactManager* @throws SecurityException When the application failed to get the android.permission.READ_CONTACTS*/public static ContactManager getService(Context context, boolean loadAtOnce, @Nullable OnFinishLoadListener onFinishListener)throws SecurityException{int granted = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS);if(granted != PackageManager.PERMISSION_GRANTED){throw new SecurityException("Need READ_CONTACTS permission");}ContactManager contactManager = INSTANCES.get(context);if(contactManager == null){contactManager = new ContactManager(context,loadAtOnce,onFinishListener);INSTANCES.put(context,contactManager);}return contactManager;}public void setOnFinishListener(OnFinishLoadListener onFinishListener){this.onFinishListener = onFinishListener;}public void load(){if(!loaded){new LoadThread().start();}else{onFinishListener.onFinishLoad(Collections.unmodifiableMap(nameToCallNumbers));}}public interface OnFinishLoadListener{void onFinishLoad(Map<String, List<String>> nameToCallNumbers);}private class LoadThread extends Thread{@Overridepublic void run() {List<Integer> listIDs = new LinkedList<>();SparseArray<String> idToName = new SparseArray<>();SparseArray<List<String>> idToCallNumber = new SparseArray<>();//Get all the _IDs and names in the table ContactCursor cursorForContactID = null;try {cursorForContactID = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME},null,null,null);if(cursorForContactID != null){int indexID = cursorForContactID.getColumnIndex(ContactsContract.Contacts._ID);int indexName = cursorForContactID.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);//build the INSTANCES from ID to name.while(cursorForContactID.moveToNext()){int id = cursorForContactID.getInt(indexID);listIDs.add(id);idToName.put(id, cursorForContactID.getString(indexName));}}}finally {if (cursorForContactID != null) {cursorForContactID.close();}}//Get all the _IDs in the table RawContact,which is equal to the raw_contact_IDs in the table Data.for(Integer ID : listIDs){LinkedList<Integer> listRawContacts = new LinkedList<>();Cursor cursorForRawContactID = null;try {cursorForRawContactID = context.getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI,new String[]{ContactsContract.RawContacts._ID},ContactsContract.RawContacts.CONTACT_ID + " = ?",new String[]{String.valueOf(ID)},null);if(cursorForRawContactID == null){continue;}//build the INSTANCES from ID to raw_contact_ID.while (cursorForRawContactID.moveToNext()){listRawContacts.add(cursorForRawContactID.getInt(cursorForRawContactID.getColumnIndex(ContactsContract.RawContacts._ID)));}}finally {if (cursorForRawContactID != null) {cursorForRawContactID.close();}}//Build the INSTANCES from ID to phone numbers via raw_contact_ID.LinkedList<String> numbers = new LinkedList<>();for(Integer rawID : listRawContacts){Cursor cursorForCallNumbers = null;try {cursorForCallNumbers = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER},ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID + " = ?",new String[]{String.valueOf(rawID)},null);if(cursorForCallNumbers != null){while(cursorForCallNumbers.moveToNext()){numbers.add(cursorForCallNumbers.getString(cursorForCallNumbers.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));}}}finally {if (cursorForCallNumbers != null) {cursorForCallNumbers.close();}}}idToCallNumber.put(ID,numbers);}//Build the INSTANCES from name to phone numbers via ID.nameToCallNumbers = new HashMap<>();for(Integer id : listIDs){nameToCallNumbers.put(idToName.get(id), idToCallNumber.get(id));}loaded = true;//invoke the callback if not null.if(onFinishListener != null){onFinishListener.onFinishLoad(Collections.unmodifiableMap(nameToCallNumbers));}}} }

    下面的例子中,信息加載完畢后會通過Log的方式打印出來:

    ContactManager.getService(this, true, new ContactManager.OnFinishLoadListener() {@Overridepublic void onFinishLoad(Map<String, List<String>> nameToCallNumbers) {for(Map.Entry<String, List<String>> entry : nameToCallNumbers.entrySet()){Log.i("聯系人", entry.getKey() + ": " + entry.getValue());}} });

    總結

    以上是生活随笔為你收集整理的利用Contacts Provider读取手机联系人信息的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。