Contacts源码分析(一、概述)

概述

Contacts是Android系统中的一个重要组件,它提供了一个用于管理用户联系人的界面和API。用户可以使用Contacts来添加、编辑、删除和查找联系人。开发者可以使用Contacts API来读取、写入和监听联系人数据的变化。Contacts组件包括以下几个部分:

1. ContactsProvider:ContactsProvider是Contacts组件的核心,它是一个ContentProvider,负责管理联系人数据的存储、提供访问联系人数据的接口和处理来自其他应用的请求。

2. Contacts应用:Contacts应用是Android系统中内置的一个应用程序,它提供了一个用户友好的界面来管理联系人。

3. Contacts API:Contacts API是一个Java API,开发者可以使用它来读取、写入和监听联系人数据的变化。

使用方法

1. 访问联系人

访问联系人数据的最基本方式是使用Contacts API中的ContentResolver.query()方法,该方法返回一个Cursor对象,通过它可以遍历所有联系人以及它们的详细信息。例如,以下代码段演示如何获取联系人ID、姓名和电子邮件信息:

```java

ContentResolver resolver = getContentResolver();

Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI,

null, null, null, null);

while (cursor.moveToNext()) {

long id = cursor.getLong(cursor.getColumnIndex(ContactsContract.Contacts._ID));

String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

String email = null;

Cursor emailCursor = resolver.query(

ContactsContract.CommonDataKinds.Email.CONTENT_URI,

null,

ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?",

new String[] { Long.toString(id) },

null);

if (emailCursor.moveToNext()) {

email = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));

}

emailCursor.close();

Log.d(TAG, "id: " + id + ", name: " + name + ", email: " + email);

}

cursor.close();

```

2. 添加联系人

可以使用Contacts API中的ContentProviderOperation类来创建一个添加联系人的操作,然后使用ContentResolver.applyBatch()方法提交该操作。以下代码显示如何添加一个联系人以及联系人的电话号码和电子邮件地址:

```java

ArrayList operations = new ArrayList();

ContentProviderOperation operation = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)

.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)

.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)

.build();

operations.add(operation);

operation = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)

.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)

.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)

.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, "John Doe")

.build();

operations.add(operation);

operation = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)

.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)

.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)

.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, "4155551234")

.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)

.build();

operations.add(operation);

operation = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)

.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)

.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)

.withValue(ContactsContract.CommonDataKinds.Email.DATA, "johndoe@example.com")

.withValue(ContactsContract.CommonDataKinds.Email.TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK)

.build();

operations.add(operation);

try {

getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);

} catch (RemoteException e) {

e.printStackTrace();

} catch (OperationApplicationException e) {

e.printStackTrace();

}

```

3. 编辑联系人

要编辑联系人,需要首先查询该联系人的详细信息,然后修改需要更改的属性。通过使用ContentProviderOperation类,可以创建一个更新联系人数据的操作,然后使用ContentResolver.applyBatch()方法提交该操作,完成联系人的更新。以下代码显示如何通过ID查询联系人,并更新其姓名:

```java

ContentResolver resolver = getContentResolver();

String[] projection = {ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME};

String selection = ContactsContract.Contacts._ID + " = ?";

String[] selectionArgs = {Long.toString(contactId)};

Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI,

projection, selection, selectionArgs, null);

if (cursor.moveToNext()) {

long id = cursor.getLong(cursor.getColumnIndex(ContactsContract.Contacts._ID));

String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

ArrayList operations = new ArrayList();

ContentProviderOperation operation = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)

.withSelection(

ContactsContract.Data.CONTACT_ID

+ "=? AND "

+ ContactsContract.Data.MIMETYPE

+ "='"

+ ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE

+ "'",

new String[] { Long.toString(id) })

.withValue(

ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,

"New Name").build();

operations.add(operation);

try {

getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);

} catch (RemoteException e) {

e.printStackTrace();

} catch (OperationApplicationException e) {

e.printStackTrace();

}

}

cursor.close();

```

案例说明

在一个联系人管理应用中,我们可以使用Contacts提供的API来获取、添加、编辑和删除联系人。例如,我们可以创建一个联系人列表界面,该界面显示所有联系人的姓名和头像:

```java

public class ContactListActivity extends AppCompatActivity

implements LoaderManager.LoaderCallbacks {

private static final int LOADER_ID_CONTACTS = 1;

private ListView mContactListView;

private ContactListAdapter mAdapter;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_contact_list);

mContactListView = findViewById(R.id.contact_list_view);

mAdapter = new ContactListAdapter(this);

mContactListView.setAdapter(mAdapter);

getSupportLoaderManager().initLoader(LOADER_ID_CONTACTS, null, this);

}

@Override

public Loader onCreateLoader(int id, Bundle args) {

return new CursorLoader(this,

ContactsContract.Contacts.CONTENT_URI,

new String[]{

ContactsContract.Contacts._ID,

ContactsContract.Contacts.DISPLAY_NAME,

ContactsContract.Contacts.PHOTO_URI

},

null,

null,

ContactsContract.Contacts.DISPLAY_NAME + " COLLATE NOCASE ASC"

);

}

@Override

public void onLoadFinished(Loader loader, Cursor data) {

mAdapter.swapCursor(data);

}

@Override

public void onLoaderReset(Loader loader) {

mAdapter.swapCursor(null);

}

private static class ContactListAdapter extends CursorAdapter {

private static final int CONTACT_PHOTO_SIZE = 96;

private LayoutInflater mInflater;

public ContactListAdapter(Context context) {

super(context, null, false);

mInflater = LayoutInflater.from(context);

}

@Override

public View newView(Context context, Cursor cursor, ViewGroup parent) {

View itemView = mInflater.inflate(R.layout.list_item_contact, parent, false);

ViewHolder holder = new ViewHolder();

holder.nameView = itemView.findViewById(R.id.contact_name);

holder.photoView = itemView.findViewById(R.id.contact_photo);

itemView.setTag(holder);

return itemView;

}

@Override

public void bindView(View view, Context context, Cursor cursor) {

ViewHolder holder = (ViewHolder) view.getTag();

String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

holder.nameView.setText(name);

String photoUri = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_URI));

if (photoUri != null) {

Uri uri = Uri.parse(photoUri);

Picasso.get()

.load(uri)

.resize(CONTACT_PHOTO_SIZE, CONTACT_PHOTO_SIZE)

.centerCrop()

.placeholder(R.drawable.ic_person_gray_24dp)

.error(R.drawable.ic_person_gray_24dp)

.into(holder.photoView);

} else {

holder.photoView.setImageResource(R.drawable.ic_person_gray_24dp);

}

}

private static class ViewHolder {

TextView nameView;

ImageView photoView;

}

}

}

```

在上面的例子中,我们使用CursorLoader来异步获取联系人列表,然后使用CursorAdapter来显示联系人的姓名和头像。我们还使用Picasso库来异步加载头像图片并将其缩放到合适的尺寸。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.37seo.cn/

点赞(70) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部