Основы Contacts API в Android
Интерфейс работы с контактами изменился начиная с 5-ой версии API Android SDK : провайдер Contacts и все его составляющие получили статус @Deprecated. Теперь за работу с контактами отвечает провайдер ContactsContract, который внёс изменения в структуру хранения контактов, более адаптированную для Android устройств, позволяющую хранить контакты из разных источников и предоставлять их пользователю как единую сущность. В настоящее время объект описания контакта на мобильном устройстве включает не только имя и номер телефона, но и Email, Twitter, Facebook и т.д. Новый ContactsContract API позволяет системе агрегировать похожие контакты и выдавать их пользователю в одной записи, а также связывать контакт с разного рода данными.
Пользовательские данные хранятся в центральном репозитории устройства, которым управляет поставщик контактов — эффективный и гибкий компонент Android. Поставщик контактов — это источник данных, которые отображаются в приложении «Контакты» на Вашем устройстве.
Структура поставщика контактов
Поставщик контактов содержит в себе три типа данных о пользователе, как это представлено на рисунке. Каждый тип данных хранится в отдельной таблице :
В качестве наименований таблиц обычно используются названия соответствующих классов-контрактов ContactsContract. Эти классы определяют константы для URI контента, названий столбцов и значений в столбцах этих таблиц :
ContactsContract.Contacts
Строки в таблице Contacts содержат данные о пользователях, полученные путем агрегации строк необработанных контактов.
ContactsContract.RawContacts
Строки в таблице RawContacts содержат сводные данные о пользователях, относящиеся к пользовательским учетным записям и их типам.
ContactsContract.Data
Строки в таблице Data содержат сведения о необработанных контактах, например email или номера телефонов.
Имеются и другие таблицы, представленные классами-контрактами ContactsContract и представляющие собой вспомогательные таблицы. Эти таблицы поставщик контактов использует для управления своими операциями и поддержки определенных функций, имеющихся в приложении устройства «Контакты» или приложениях для телефонной связи.
Разрешения на доступ к поставщику контактов
Приложения, которым требуется доступ к поставщику контактов для чтения или записи, должны определить разрешения в файле манифеста приложения :
Профиль пользователя
Разрешения на доступ к данным поставщика контактов не распространяются на работу с профилями пользователя.
Примечание : данные о контактах пользователя являются личными и конфиденциальными. Владельцы мобильных устройств заботятся о своей конфиденциальности и часто не проявляют желания предоставлять приложениям возможности сбора данных о них самих и/или их контактах. Если владельцам не до конца ясно, для чего требуется предоставить приложению разрешение на доступ к данным контактов, они могут присвоить Вашему приложению низкий рейтинг, или вообще откажутся его устанавливать.
Строка контактов профиля связана со строкой необработанных контактов в каждой из систем, в которой используется профиль. В каждой строке необработанного контакта профиля может содержаться несколько строк данных. Константы для доступа к профилю пользователя представлены в классе ContactsContract.Profile.
Для доступа к профилю пользователя требуются отдельные разрешения. Наряду с разрешениями READ_CONTACTS и WRITE_CONTACTS (чтение и запись контакта) для доступа к профилю пользователя необходимы разрешения android.Manifest.permission#READ_PROFILE и android.Manifest.permission#WRITE_PROFILE на чтение и запись соответственно.
Помните, что профиль пользователя представляет собой конфиденциальную информацию. При запросе доступа к личной информации на устройстве пользователя обязательно укажите, для чего вам требуется доступ к профилю пользователя.
Примечание : если при получении нескольких строк контактов необходимо определить, какая из них является профилем пользователя, анализируйте значение столбца IS_USER_PROFILE этой строки. Для профиля пользователя значение должно быть «1».
Пример чтения контактов
Рассмотрим простой пример чтения списка контактов и вывода их в журнал Log. Ниже представлен листинг метода onCreate главного модуля приложения MainActivity.
Перед выполнением запроса проверим, имеются ли у нас необходимые разрешения на доступ к контактам. Для этого используем метод ContextCompat.checkSelfPermission, которому в качестве параметров передадим контекст модуля и идентификатор разрешений списка контактов. Если приложение имеет разрешения (permission), то метод вернет значение PERMISSION_GRANTED, в противном случае PERMISSION_DENIED.
При наличии необходимых разрешений вызываем метод чтения контактов readContacts, представленный ниже. В противном случае запросим необходимые разрешения методом ActivityCompat.requestPermissions, которому в качестве параметров необходимо передать контекст модуля, список запрашиваемых разрешений и «определенную в модуле константу» (PERMISSIONS_REQUEST_READ_CONTACTS).
Примечание : при запросе приложением «разрешения» методом requestPermissions(), система открывает стандартное диалоговое окно подтверждения доступа. Приложение не может изменить интерфейс диалогового окна. Если имеется необходимость представить пользователю дополнительную информацию, то это желательно сделать перед открытием окна запроса подтверждения. После запроса первого подтверждения и получения положительного ответа система запоминает результат ответа и больше не открывает окно подтверждения доступа.
Результат выполнения запроса на получение разрешений система возвращает вызовом callback метода onRequestPermissionsResult, листинг которого представлен ниже.
Листинг callback метода запроса разрешений
Система вызывает callback метод onRequestPermissionsResult при запросе разрешений методом requestPermissions. В качестве параметров методу передается массив запрошенных permissions и массив разрешений grantResults.
В примере проверяем результат полученного от системы ответа. При наличии необходимых разрешений вызывается метод readContacts.
Листинг метода чтения контактов
Метод чтения контактов readContacts в качестве параметра получает контекст приложения, используемый для вызова метода getContentResolver().query и получения результата в виде курсора. Если курсор содержит список контактов, то метод в цикле перебирает этот список и выводит в Log параметры контактов (id, name, phone). Метод можно доработать, чтобы он возвращал список контактов в виде List .
Листинг класса Contact
Класс описания контакта, используемого в методе чтения контактов устройства.
Источник