Как управлять местами хранения контактов

Приложения могут позволять пользователям создавать и хранить контакты. Обычно контакты можно сохранить в двух местах:

  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 содержит:

  • State – указывает, задан ли аккаунт по умолчанию, и если да, то его категорию (облачный, локальный или SIM).
  • "Аккаунт" – сведения об аккаунте (название и тип), если статус – DEFAULT_ACCOUNT_STATE_CLOUD or DEFAULT_ACCOUNT_STATE_SIM. Для других штатов, включая DEFAULT_ACCOUNT_STATE_LOCAL, значение будет нулевым.

Вот пример того, как можно проанализировать объект 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;
}

Создавать контакты без указания аккаунта.

Если аккаунт по умолчанию задан, приложению обычно не нужно явно указывать аккаунт при создании контактов. Система автоматически сохраняет новый контакт в аккаунте по умолчанию. Вот как создать контакт, не указывая аккаунт.

Создайте новый объект ArrayList, состоящий из объектов ContentProviderOperation. Этот список содержит операции по вставке необработанного контакта и связанных с ним данных.

Kotlin

val ops = ArrayList<ContentProviderOperation>()

Java

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

Создайте новый объект ContentProviderOperation, чтобы вставить необработанный контакт. Поскольку вы не указываете аккаунт, вам не нужно включать ACCOUNT_TYPE и ACCOUNT_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 в список ops, чтобы включить поля контакта (например, имя, номер телефона, адрес электронной почты). Затем выполните пакетную операцию, чтобы создать контакт.

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 и укажите облачный аккаунт. Вот как это сделать:

Создайте новый объект ArrayList, состоящий из объектов ContentProviderOperation.

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 в список ops, чтобы включить поля контакта, и выполните пакетную операцию для создания контакта.

Создать контакты в локальном аккаунте

Чтобы создать контакт в локальном аккаунте, вставьте новую строку необработанного контакта в таблицу ContactsContract.RawContacts и укажите информацию о локальном аккаунте:

Создайте новый объект ArrayList, состоящий из объектов ContentProviderOperation.

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 в список ops, чтобы включить поля контакта, и выполните пакетные операции для создания контакта.