1.联系人的查找
返回一个ArrayList<HashMap<String, String>>类型
//通过管理联系人的URI获取游标对象 Cursor cursor= getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null); ArrayList<HashMap<String, String>> contactData = new ArrayList<HashMap<String, String>>(); while (cursor.moveToNext()) { String contactId=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); String contactName=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)).trim(); String contactPhone=null; //通过管理联系人电话的URI获取游标对象 Cursor cursorForPhone=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+contactId, null, null); if(cursorForPhone.moveToFirst()){ contactPhone=cursorForPhone.getString(cursorForPhone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replaceAll(" ", ""); } cursorForPhone.close(); //删除无效联系人 if(contactPhone==null){ int id=getContentResolver().delete(ContactsContract.RawContacts.CONTENT_URI, ContactsContract.Contacts._ID+"="+contactId, null); Toast.makeText(contactList.this,"无效联系人"+contactName+"已清空"+id, Toast.LENGTH_SHORT).show(); continue; } HashMap<String, String> contact=new HashMap<String, String>(); contact.put("uid", contactId); contact.put("name", contactName); contact.put("phone", contactPhone); contactData.add(contact); } cursor.close(); return contactData;
以上demo也包含了联系人的删除
2.联系人的添加
String contactName=name.getText().toString().trim(); String contactPhone=phone.getText().toString().trim(); ArrayList<ContentProviderOperation> operation=new ArrayList<ContentProviderOperation>(); //在raw_contacts主表中添加一条数据 ContentProviderOperation op1= ContentProviderOperation.newInsert(RawContacts.CONTENT_URI) .withValue("account_id", null) .build(); operation.add(op1); //在data表中添加一条联系人姓名类型的数据 ContentProviderOperation op2= ContentProviderOperation.newInsert(Data.CONTENT_URI) .withValueBackReference(Data.RAW_CONTACT_ID, 0) .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE) .withValue(StructuredName.GIVEN_NAME, contactName) .build(); operation.add(op2); //在data表中添加一条电话类型的数据 ContentProviderOperation op3= ContentProviderOperation.newInsert(Data.CONTENT_URI) .withValueBackReference(Data.RAW_CONTACT_ID, 0) .withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE) .withValue(Phone.NUMBER, contactPhone) .withValue(Phone.TYPE, Phone.TYPE_MOBILE) .build(); operation.add(op3); try{ //执行上面的操作,该方法会开启事务 getContentResolver().applyBatch("com.android.contacts", operation); Toast.makeText(AddContact.this, "添加成功!", Toast.LENGTH_SHORT).show(); } catch (RemoteException | OperationApplicationException e) { e.printStackTrace(); }
对于联系人的操作,其实是对于data/data/com.android.providers.contacts/databases/contacts2.db的操作
主要需要了解的几张表:contacts,raw_contacts,data,mimetype,对于通话记录的操作,则需要该文件下的calls等表操作。
涉及到的URI:
Contacts.CONTENT_URI
对应contacts表,主要是联系人的主要信息
以上的图只截取了部分内容
Data.CONTENT_URI
对应data表中的数据
上图中可以看出有些phone数据类型错误,成了name类型,这也是之前电话号码不显示的原因
CommonDataKinds.Phone.CONTENT_URI
对应的是data表中,类型为电话号码的数据
CommonDataKinds.Email.CONTENT_URI
对应的是data表中,类型为电话号码的数据
RawContacts.CONTENT_URI
对应raw_contacts表中的数据
这个只是android中ContentProvider的一个应用,还有许多应用也通过ContentProvider共享了它们的数据