管理联系人存储位置

应用可以允许用户创建和存储联系人。这些联系人通常可保存在以下两个位置:

  1. 云端账号:将联系人保存到与云服务(例如 Google Cloud)关联的账号,以便同步和备份联系人。
  2. 本地账号:联系人可以存储在设备本地。

用户可以在设备设置中设置首选存储位置。此首选位置称为默认账号,会在创建联系人时使用。应用应遵循此偏好设置。本文档介绍了如何使用不同的联系人存储位置(包括云账号和本地账号),以及实现管理用户偏好的最佳实践。本地账号是指直接在设备上存储联系人。

检索默认账号

如需确定新联系人的默认账号,请使用 ContactsContract.RawContacts.DefaultAccount

调用 getDefaultAccountForNewContacts() 以获取 ContactsContrast.RawContacts.DefaultAccount.DefaultAccountAndState 对象。此对象包含有关默认账号设置的信息。

Kotlin

import ContactsContrast.RawContacts
import ContactsContrast.RawContacts.DefaultAccount
import ContactsContrast.RawContacts.DefaultAccount.DefaultAccountAndState

val defaultAccountAndState: DefaultAccountAndState =
  DefaultAccount.getDefaultAccountForNewContacts(
      getContentResolver()
  )

Java

import ContactsContrast.RawContacts;
import ContactsContrast.RawContacts.DefaultAccount;
import ContactsContrast.RawContacts.DefaultAccount.DefaultAccountAndState;

DefaultAccountAndState defaultAccountAndState =
  DefaultAccount.getDefaultAccountForNewContacts(
    getContentResolver()
  );

DefaultAccountAndState 对象包含:

  • 状态:指明是否设置了默认账号,如果设置了,则指明该账号的类别(云端、本地或 SIM 卡)。
  • 账号:如果状态为 DEFAULT_ACCOUNT_STATE_CLOUD or DEFAULT_ACCOUNT_STATE_SIM,则提供具体账号详细信息(名称和类型)。对于其他状态(包括 DEFAULT_ACCOUNT_STATE_LOCAL),此值为 null。

以下示例展示了如何解析 DefaultAccountAndState 对象:

Kotlin

// Retrieves the state of default account.
val defaultAccountState = defaultAccountAndState.state
var defaultAccountName: String? = null
var defaultAccountType: String? = null

when (defaultAccountState) {
    // Default account is set to a cloud or a SIM account.
    DefaultAccountState.DEFAULT_ACCOUNT_STATE_CLOUD,
    DefaultAccountState.DEFAULT_ACCOUNT_STATE_SIM -> {
        defaultAccountName = defaultAccountAndState.account?.name
        defaultAccountType = defaultAccountAndState.account?.type
    }
    // Default account is set to the local account on the device.
    DefaultAccountState.DEFAULT_ACCOUNT_STATE_LOCAL -> {
        defaultAccountName = RawContacts.getLocalAccountType()
        defaultAccountType = RawContacts.getLocalAccountName()
    }
    // Default account is not set.
    DefaultAccountState.DEFAULT_ACCOUNT_STATE_NOT_SET -> {
    }
}

Java

// Retrieves the state of default account.
var defaultAccountState = defaultAccountAndState.getState();
String defaultAccountName = null;
String defaultAccountType = null;

switch (defaultAccountState) {
  // Default account is set to a cloud or a SIM account.
  case DefaultAccountState.DEFAULT_ACCOUNT_STATE_CLOUD:
  case DefaultAccountState.DEFAULT_ACCOUNT_STATE_SIM:
    defaultAccountName = defaultAccountAndState.getAccount().name;
    defaultAccountType = defaultAccountAndState.getAccount().type;
    break;
  // Default account is set to the local account on the device.
  case  DefaultAccountState.DEFAULT_ACCOUNT_STATE_LOCAL:
    defaultAccountName = RawContacts.getLocalAccountType();
    defaultAccountType = RawContacts.getLocalAccountName();
    break;

  // Default account is not set.
  case DefaultAccountState.DEFAULT_ACCOUNT_STATE_NOT_SET:
    break;
}

创建联系人时不指定账号

如果已设置默认账号,您的应用在创建联系人时通常无需明确指定账号。系统会自动将新联系人保存到默认账号。如需在不指定账号的情况下创建联系人,请按以下步骤操作。

创建一个包含 ContentProviderOperation 对象的新 ArrayList。此列表包含用于插入原始联系人及其关联数据的操作。

Kotlin

val ops = ArrayList<ContentProviderOperation>()

Java

ArrayList<ContentProviderOperation> ops =
        new ArrayList<ContentProviderOperation>();

创建一个新的 ContentProviderOperation 以插入原始联系人。由于您未指定账号,因此无需添加 ACCOUNT_TYPEACCOUNT_NAME

Kotlin

val op = ContentProviderOperation.newInsert(
    ContactsContract.RawContacts.CONTENT_URI
)
ops.add(op.build())

Java

ContentProviderOperation.Builder op =
    ContentProviderOperation.newInsert(
        ContactsContract.RawContacts.CONTENT_URI
    );
ops.add(op.build());

将其他 ContentProviderOperation 对象添加到操作列表中,以添加联系人字段(例如姓名、电话号码、电子邮件地址)。然后,执行批量操作以创建联系人。

Kotlin

try {
    getContentResolver().applyBatch(
        ContactsContract.AUTHORITY, ops
    )
} catch (e: Exception) {
    // Handle exceptions
}

Java

try {
    getContentResolver().applyBatch(
        ContactsContract.AUTHORITY, ops
    );
} catch (Exception e) {
    // Handle exceptions
}

在云端账号中创建联系人

如需在云账号中创建联系人,请将原始联系人行插入 ContactsContract.RawContacts 表并指定云账号。具体方法如下:

创建一个包含 ContentProviderOperation 对象的新 ArrayList

Kotlin

val ops = ArrayList<ContentProviderOperation>()

Java

ArrayList<ContentProviderOperation> ops =
    new ArrayList<ContentProviderOperation>();

创建一个新的 ContentProviderOperation 以插入原始联系人。使用 withValue() 方法指定所选云账号的账号类型和账号名称。

Kotlin

val op = ContentProviderOperation.newInsert(
    ContactsContract.RawContacts.CONTENT_URI
)
    .withValue(
        ContactsContract.RawContacts.ACCOUNT_TYPE,
        selectedAccount.type
    )
    .withValue(
        ContactsContract.RawContacts.ACCOUNT_NAME,
        selectedAccount.name
    )
ops.add(op.build())

Java

ContentProviderOperation.Builder op =
    ContentProviderOperation.newInsert(
        ContactsContract.RawContacts.CONTENT_URI
    )
        .withValue(
            ContactsContract.RawContacts.ACCOUNT_TYPE,
            selectedAccount.getType()
        )
        .withValue(
            ContactsContract.RawContacts.ACCOUNT_NAME,
            selectedAccount.getName()
        );
ops.add(op.build());

将其他 ContentProviderOperation 对象添加到操作列表中以添加联系人字段,然后执行批量操作以创建联系人。

在本地账号中创建联系人

如需在本地账号中创建联系人,请将新的原始联系人行插入 ContactsContract.RawContacts 表中,并指定本地账号的账号信息:

创建一个包含 ContentProviderOperation 对象的新 ArrayList

Kotlin

val ops = ArrayList<ContentProviderOperation>()

Java

ArrayList<ContentProviderOperation> ops =
    new ArrayList<ContentProviderOperation>();

创建一个新的 ContentProviderOperation 以插入原始联系人。使用 ContactsContract.RawContacts.getLocalAccountName()ContactsContract.RawContacts.getLocalAccountType() 指定本地账号的账号信息。

Kotlin

val op = ContentProviderOperation.newInsert(
    ContactsContract.RawContacts.CONTENT_URI
)
    .withValue(
        ContactsContract.RawContacts.ACCOUNT_TYPE,
        ContactsContract.RawContacts.getLocalAccountType()
    )
    .withValue(
        ContactsContract.RawContacts.ACCOUNT_NAME,
        ContactsContract.RawContacts.getLocalAccountName()
    )
ops.add(op.build())

Java

ContentProviderOperation.Builder op =
    ContentProviderOperation.newInsert(
        ContactsContract.RawContacts.CONTENT_URI
    )
        .withValue(
            ContactsContract.RawContacts.ACCOUNT_TYPE,
            ContactsContract.RawContacts.getLocalAccountType()
        )
        .withValue(
            ContactsContract.RawContacts.ACCOUNT_NAME,
            ContactsContract.RawContacts.getLocalAccountName()
        );
ops.add(op.build());

将其他 ContentProviderOperation 对象添加到操作列表中以添加联系人字段,然后执行批量操作以创建联系人。