源码来自我的一个拨号应用:https://github.com/NashLegend/QuicKid


1.读取带电话号码的所有联系人。

Android系统貌似没有直接取得带电话号码的联系人列表的功能。直接读取Contacts.CONTENT_URI只能读取联系人信息却得不到电话号码。如果先读取联系人列表,再通过联系人列表一个一个读取电话号码又非常慢,所以可以这样读:先从Phone.CONTENT_URI读取出电话列表,但是有可能一个人对应多个号码,这时只要合并一下就可以了,根据Contacts.SORT_KEY_PRIMARY排序,同一个人的不同号码是靠在一起的,这样合并就变得非常容易,坏处是对于没有电话号码的联系人这里是取不到的。(Contact是一个自定义类,这里没有写出来,这不是重点……)

publicstaticvoidloadContacts(Contextcontext){ArrayList<Contact>AllContacts=newArrayList<Contact>();ContentResolverresolver=context.getContentResolver();//要使用RawContacts.CONTACT_ID而不是Contacts.CONTACT_IDString[]PROJECTION={RawContacts.CONTACT_ID,Contacts.DISPLAY_NAME,Contacts.LOOKUP_KEY,Contacts.PHOTO_THUMBNAIL_URI,Phone.NUMBER,Phone.TYPE,Contacts.STARRED};Cursorcursor=resolver.query(Phone.CONTENT_URI,PROJECTION,null,null,Contacts.SORT_KEY_PRIMARY);StringpreLookupKey="";ContactpreContact=null;if(cursor.moveToFirst()){do{longcontractID=cursor.getInt(0);StringdisplayName=cursor.getString(1);StringlookupKey=cursor.getString(2);StringphotoUri=cursor.getString(3);booleanstarred=cursor.getInt(6)==1;if(lookupKey.equals(preLookupKey)&&preContact!=null){preContact.addPhone(cursor.getString(4),cursor.getInt(5));}else{Contactcontact=newContact();contact.setContactId(contractID);contact.setName(displayName);contact.setLookupKey(lookupKey);contact.setPhotoUri(photoUri);contact.addPhone(cursor.getString(4),cursor.getInt(5));contact.setStarred(starred);AllContacts.add(contact);preLookupKey=lookupKey;preContact=contact;}}while(cursor.moveToNext());}else{//NoPhoneNumberFound}cursor.close();}

2.读取最近联系人

Android可以通过查询Contacts.CONTENT_STREQUENT_URI得到最近联系人。注意这里得到的不是历史通话记录,而是系统根据通话频率自动获得的。

publicstaticvoidloadStrequent(){ArrayList<Contact>StrequentContacts=newArrayList<Contact>();String[]projection={Contacts._ID,Contacts.DISPLAY_NAME,Contacts.LOOKUP_KEY,Contacts.PHOTO_THUMBNAIL_URI,Contacts.TIMES_CONTACTED,Contacts.LAST_TIME_CONTACTED,Contacts.STARRED,Contacts.PHOTO_ID};ContentResolverresolver=AppApplication.globalApplication.getContentResolver();//显示最近联系人和收藏的联系人Cursorcursor=resolver.query(Contacts.CONTENT_STREQUENT_URI,projection,null,null,null);//加载最近联系人,不包括收藏的联系人//Cursorcursor=resolver.query(//Uri.withAppendedPath(Contacts.CONTENT_URI,"frequent"),//projection,null,null,null);while(cursor.moveToNext()){Contactcontact=newContact();longcontractID=cursor.getInt(0);StringdisplayName=cursor.getString(1);StringlookupKey=cursor.getString(2);StringphotoUri=cursor.getString(3);intTIMES_CONTACTED=cursor.getInt(4);longLAST_TIME_CONTACTED=cursor.getLong(5);booleanstarred=cursor.getInt(6)==1;contact.setContactId(contractID);contact.setName(displayName);contact.setLookupKey(lookupKey);contact.setPhotoUri(photoUri);contact.setStarred(starred);contact.Times_Contacted=TIMES_CONTACTED;contact.Last_Time_Contacted=LAST_TIME_CONTACTED;StrequentContacts.add(contact);}cursor.close();//notify}

3.读取合并后的通话记录。

查询Calls.CONTENT_URI,并不能读取出具体的联系人信息,如果要知道最近通话记录,要跟已经联系人列表对照使用。

publicstaticvoidloadCallLogsCombined(){if(AllContacts.size()==0){loadContacts();}ArrayList<Contact>recentContacts=newArrayList<Contact>();String[]projection={Calls._ID,Calls.TYPE,Calls.CACHED_NAME,Calls.CACHED_NUMBER_TYPE,Calls.DATE,Calls.DURATION,Calls.NUMBER};ContentResolverresolver=AppApplication.globalApplication.getContentResolver();Cursorcursor=resolver.query(Calls.CONTENT_URI,projection,null,null,Calls.DEFAULT_SORT_ORDER);while(cursor.moveToNext()){longcallID=cursor.getInt(0);intcallType=cursor.getInt(1);Stringname=cursor.getString(2);intnumberType=cursor.getInt(3);longdate=cursor.getLong(4);intduration=cursor.getInt(5);Stringnumber=cursor.getString(6);if(TextUtils.isEmpty(name)){booleanmatched=false;for(Iterator<Contact>iterator=recentContacts.iterator();iterator.hasNext();){Contactcon=iterator.next();if(con.Last_Contact_Number.equals(number)){matched=true;con.Times_Contacted++;break;}}if(!matched){ContacttmpContact=newContact();tmpContact.Times_Contacted=1;tmpContact.Last_Contact_Call_ID=callID;tmpContact.Last_Contact_Call_Type=callType;tmpContact.Last_Contact_Number=number;tmpContact.Last_Contact_Phone_Type=numberType;tmpContact.Last_Time_Contacted=date;tmpContact.Last_Contact_Duration=duration;recentContacts.add(tmpContact);}}else{booleanmatched=false;for(Iterator<Contact>iterator=recentContacts.iterator();iterator.hasNext();){Contactcon=iterator.next();if(con.Last_Contact_Number.equals(number)){matched=true;con.Times_Contacted++;break;}}if(!matched){match3:for(Iterator<Contact>iterator=AllContacts.iterator();iterator.hasNext();){Contactcon=iterator.next();ArrayList<PhoneStruct>phones=con.getPhones();for(Iterator<PhoneStruct>iterator2=phones.iterator();iterator2.hasNext();){PhoneStructphoneStruct=iterator2.next();if(phoneStruct.phoneNumber.equals(number)){matched=true;ContacttmpContact=con.clone();tmpContact.setPhones(newArrayList<Contact.PhoneStruct>());tmpContact.Times_Contacted=1;tmpContact.Last_Contact_Call_ID=callID;tmpContact.Last_Contact_Call_Type=callType;tmpContact.Last_Contact_Number=number;tmpContact.Last_Contact_Phone_Type=numberType;tmpContact.Last_Time_Contacted=date;tmpContact.Last_Contact_Duration=duration;recentContacts.add(tmpContact);breakmatch3;}}}}}}cursor.close();}