通讯录

增删查改操作

通过getContentResolver()得到ContentResolver
后,我们就可以通过该对象的delete,insert,updata,query等方法间接操作联系人数据库,那么,如果我们删除某些联系人,以ContactsContract.RawContacts.CONTENT_URI为例,怎么做,先来看下源码:


首先,ContentResolver调用delete();删除操作从红色部分开始

@Override
     public int delete(Uri uri, String selection, String[] selectionArgs) {
         waitForAccess();
         return super.delete(uri, selection, selectionArgs);
     }

上面的super.delete(uri, selection, selectionArgs)调用父亲方法

@Override
     public int delete(Uri uri, String selection, String[] selectionArgs) {
         int count = 0;
         boolean applyingBatch = applyingBatch();
         if (!applyingBatch) {
             mDb = mOpenHelper.getWritableDatabase();
             mDb.beginTransactionWithListener(this);
             try {
                 count = deleteInTransaction(uri, selection, selectionArgs);
                 if (count > 0) {
                     mNotifyChange = true;
                 }
                 mDb.setTransactionSuccessful();
             } finally {
                 mDb.endTransaction();
             }

            onEndTransaction();
         } else {
             count = deleteInTransaction(uri, selection, selectionArgs);
             if (count > 0) {
                 mNotifyChange = true;
             }
         }
         return count;
     }

父类回调deleteInTransaction(uri, selection, selectionArgs);删除联系人操作在这里进行。



//该方法对uri进行匹配来执行相应的删除操作,并且是在事务中完成的,,比如

//content://com.android.contacts/contacts

//content://com.android.contacts/contacts/#

// .......................................................省略

@Override
     protected int deleteInTransaction(Uri uri, String selection, String[] selectionArgs) {
            .......................................................
            .......................................................

         //我们可以在uri中的authority部分可带可选的参数ContactsContract.CALLER_IS_SYNCADAPTER

        //比如uri字符串可以写成content://com.android.contacts?ContactsContract.CALLER_IS_SYNCADAPTER=true

        // ContactsContract.CALLER_IS_SYNCADAPTER默认是false的,他告诉同步适配器如何执行删除操作。

       //如果设置为true,则delete的时候直接删除联系人,否则,默认delete时是不会立即删除RawContacts中的数据的,

       //只是把RawContacts.DELETED标志位设置为1,从它的aggregate contact中移除该raw contact,即显示联系人时不显示它的内容

        //同步联系人时,删除服务器上的raw contact,最终删除手机上已

       //标记为DELETED为1的raw contacts


         final boolean callerIsSyncAdapter = readBooleanQueryParameter(uri, ContactsContract.CALLER_IS_SYNCADAPTER, false);
         final int match = sUriMatcher.match(uri);
         switch (match) {

           .......................................................

           .......................................................

           .......................................................
             case CONTACTS: {//uri为content://com.android.contacts/contacts,目录(dir)类型

                // TODO
                 return 0;
             }

            case CONTACTS_ID: {//删除某一个联系人,uri指定了ContactsContract.Contacts中的字段contact_id,Item类型
                 long contactId = ContentUris.parseId(uri);//得到该给定联系人数据集的id
                 return deleteContact(contactId);
             }

           .......................................................

           .......................................................

           .......................................................

            case RAW_CONTACTS: {
                 int numDeletes = 0;
                 Cursor c = mDb.query(Tables.RAW_CONTACTS, new String[]{RawContacts._ID},
                         appendAccountToSelection(uri, selection), selectionArgs, null, null, null);
                 try {
                     while (c.moveToNext()) {
                         final long rawContactId = c.getLong(0);
                         numDeletes += deleteRawContact(rawContactId, callerIsSyncAdapter);
                     }
                 } finally {
                     c.close();
                 }
                 return numDeletes;
             }

            case RAW_CONTACTS_ID: {
                 final long rawContactId = ContentUris.parseId(uri);
                 return deleteRawContact(rawContactId, callerIsSyncAdapter);
             }

            case DATA: {
                 mSyncToNetwork |= !callerIsSyncAdapter;
                 return deleteData(appendAccountToSelection(uri, selection), selectionArgs,
                         callerIsSyncAdapter);
             }

            case DATA_ID:
             case PHONES_ID:
             case EMAILS_ID:
             case POSTALS_ID: {
                 long dataId = ContentUris.parseId(uri);
                 mSyncToNetwork |= !callerIsSyncAdapter;
                 return deleteData(Data._ID + "=" + dataId, null, callerIsSyncAdapter);
             }

           .......................................................

           .......................................................

           .......................................................
         }
     }


public int deleteRawContact(long rawContactId, boolean callerIsSyncAdapter) {
         if (callerIsSyncAdapter) {
             mDb.delete(Tables.PRESENCE, PresenceColumns.RAW_CONTACT_ID + "=" + rawContactId, null);

            //直接删除数据
             return mDb.delete(Tables.RAW_CONTACTS, RawContacts._ID + "=" + rawContactId, null);
         } else {

            //从他关联的aggregate contact移除该数据
             mDbHelper.removeContactIfSingleton(rawContactId);

            //标记为已删除,但不是立即删除数据
             return markRawContactAsDeleted(rawContactId);
         }
     }


综上,我们要删除联系人可以这样做:

1)删除单个联系人:

CR.delete(ContactsContract.RawContacts.CONTENT_URI,ContactsContract.RawContacts_id + "=" + delRawId);

2)删除全部联系人:

getContentResolver().delete(Uri.parse(ContactsContract.RawContacts.CONTENT_URI.toString() +"?" + ContactsContract.CALLER_IS_SYNCADAPTER+"=true"), ContactsContract.RawContacts._ID + ">0", null));

数据索引从1开始,所以只要id>0就可以全部删除raw contact记录,上面的删除操作是立即进行的,因为我们设置了true.

你可能感兴趣的:(通讯录)