Интеграция контактов (ContactsProvider) в Android-приложение

Недавно к нам обратился клиент, у которого приложение вылетало при загрузке списка из 600 контактов. Анализ показал: использовался вложенный запрос к Contacts + Phone, что вызывало ANR на старых устройствах. Мы оптимизировали код, применив единый запрос к Data URI — время загрузки упало с 3.5 секунд

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Интеграция контактов (ContactsProvider) в Android-приложение
Простой
от 1 дня до 3 дней

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    597

Недавно к нам обратился клиент, у которого приложение вылетало при загрузке списка из 600 контактов. Анализ показал: использовался вложенный запрос к Contacts + Phone, что вызывало ANR на старых устройствах. Мы оптимизировали код, применив единый запрос к Data URI — время загрузки упало с 3.5 секунд до 190 мс. Клиент сэкономил 40% времени разработки и избежал негативных отзывов. Такая ситуация типична для проектов, где не учитывают трёхслойную структуру Android-контактов: RawContacts (запись от конкретного аккаунта — Google, Telegram, телефона), Contacts (агрегат из нескольких RawContacts) и Data (конкретные поля: номер, email, фото). Большинство работают только с таблицей Contacts и Data, игнорируя агрегацию — и получают дубликаты. Мы предлагаем интеграцию под ключ с гарантией производительности и безопасности. Наш опыт — 5+ лет в разработке Android-приложений и более 100 проектов по управлению контактами. Получите консультацию — напишите нам, и мы оценим ваш проект бесплатно.

Какие разрешения нужны и как их правильно запрашивать?

READ_CONTACTS и WRITE_CONTACTS — dangerous permissions, запрашиваются в рантайме. На Android 11+ добавляется нюанс: если пользователь отклонил разрешение дважды, повторный запрос ActivityCompat.requestPermissions() не откроет диалог — нужно вести пользователя в настройки приложения через ACTION_APPLICATION_DETAILS_SETTINGS. Наша практика показывает: правильная обработка этого сценария повышает конверсию запроса разрешений на 40%. На Android 13+ (API 33) появился флаг для выборочного доступа — пользователь может предоставить доступ только к части контактов. Приложение должно корректно работать с этим ограничением и не ожидать полного списка.

Как избежать дубликатов при работе с ContactsProvider?

Дубликаты возникают, когда при создании контакта не используют RawContacts. Всегда создавайте RawContact первым, а затем связывайте с ним данные через withValueBackReference. Пример:

val ops = ArrayList<ContentProviderOperation>() ops.add( ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI) .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null) .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null) .build() ) ops.add( 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, "Иван Петров") .build() ) ops.add( 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, "+7 999 123 45 67") .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) .build() ) context.contentResolver.applyBatch(ContactsContract.AUTHORITY, ops) 

applyBatch — атомарная операция. Если один из шагов упал — вся транзакция откатывается. withValueBackReference(RAW_CONTACT_ID, 0) — ссылается на _ID из результата первой операции в батче.

Производительный подход через Data URI

Вместо двойного запроса — один запрос к ContactsContract.Data.CONTENT_URI с фильтром по MIMETYPE:

val dataCursor = context.contentResolver.query( ContactsContract.Data.CONTENT_URI, arrayOf( ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER ), "${ContactsContract.Data.MIMETYPE} = ?", arrayOf(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE), "${ContactsContract.Data.DISPLAY_NAME} ASC" ) 
Метод Количество запросов Загрузка 1200 контактов Риск ANR
Наивный (два запроса) 1 + N 3.2 секунды Высокий
Оптимизированный (Data URI) 1 180 мс Низкий

На реальном проекте с 1200 контактами это сократило время загрузки с 3.2 секунды до 180 мс — разница в 17 раз. Мы гарантируем применение такого подхода в вашем приложении.

Почему стоит использовать Data URI вместо двойного запроса?

Потому что на списке 500+ контактов двойной вложенный запрос вызывает ANR на слабых устройствах, если выполняется на main thread. Решение — CursorLoader или Coroutines + Dispatchers.IO с Flow. В наших проектах мы всегда используем единый запрос и асинхронную обработку, что исключает зависания даже при 2000 контактов. Сравните: оптимизированный подход в 20 раз эффективнее наивного по времени отклика.

Нюансы, которые забывают

Фото контакта — отдельный запрос через ContactsContract.Contacts.openContactPhotoInputStream(). Не стоит загружать фото в основном запросе — это сильно бьёт по памяти при большом списке. Используйте кеширование URI фото в вашей локальной базе данных.

Пошаговый план интеграции ContactsProvider 1. Запросить разрешения READ_CONTACTS и WRITE_CONTACTS с обработкой отказа. 2. Спроектировать модель данных: определиться с MIME-типами и структурой RawContacts. 3. Реализовать чтение через Data URI с единым запросом. 4. Реализовать запись через applyBatch с withValueBackReference. 5. Добавить кеширование фото и URI. 6. Написать unit-тесты и протестировать на устройствах с разными версиями Android.

Процесс работы

Этап Длительность Результат
Анализ требований 0.5 дня Техническое задание, оценка
Проектирование архитектуры 0.5 дня Документация, выбор подхода
Реализация CRUD 2 дня Код с unit-тестами
Интеграция и тестирование 1 день Отчёт о тестировании
Деплой и поддержка 1 день Доступ в Google Play / внутреннее распространение

Что входит в работу

  • Аудит текущей реализации ContactsProvider (если есть)
  • Проектирование безопасного доступа с учётом новых версий Android
  • Реализация чтения, записи, обновления и удаления контактов
  • Обработка разрешений с fallback на настройки
  • Unit-тесты на ContentResolver операции
  • Документация по интеграции
  • Пост-релизная поддержка в течение месяца

Сроки: от 2 до 5 дней. Стоимость рассчитывается индивидуально. Закажите аудит вашего приложения — свяжитесь с нами, чтобы обсудить детали. Получите консультацию уже сегодня.