В современных мобильных приложениях часто возникает задача не просто получить полный номер телефона абонента, а выделить из него определённую часть – например, код оператора, префикс или последние цифры. В разговорной речи такой фрагмент иногда называют «номер части телефона в шали» (от слова шали – условное обозначение «обёртки» или «шаблона», в которую помещают номер). Ниже подробно рассмотрим, как решить эту задачу на платформе Android и с помощью SQL‑запросов.
Почему нужно извлекать часть номера?
- Идентификация оператора. Первые три‑четыре цифры номера часто указывают на мобильного оператора.
- Фильтрация по региону. Коды регионов позволяют определить географическую принадлежность абонента.
- Маскирование данных. Для отображения в интерфейсе иногда показывают только последние 4‑6 цифр, скрывая остальные из соображений конфиденциальности.
- Сравнение и поиск. При поиске дубликатов или синхронизации контактов удобно сравнивать только определённый сегмент номера.
Извлечение части номера на Android
Android предоставляет доступ к контактам через ContentResolver и URI‑ы из пакета ContactsContract. Для поиска по номеру удобно использовать CONTENT_FILTER_URI, к которому добавляется искомый фрагмент.
Основные шаги
- Получить объект
ContentResolverизContext. - Сформировать URI:
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(searchPart)); - Выполнить запрос, указав нужные столбцы (например,
ContactsContract.PhoneLookup.DISPLAY_NAMEиContactsContract.PhoneLookup.NUMBER). - Обработать полученный
Cursorи извлечь нужную часть номера.
Пример кода (Java)
Примечание: Для простоты пример показан без обработки runtime‑разрешений; в реальном приложении необходимо запросить READ_CONTACTS.
ContentResolver cr = getContentResolver;
String searchPart = «916»; // например, ищем код оператора
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(searchPart));
String[] projection = new String[] {
ContactsContract.PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup.NUMBER
};
Cursor c = cr.query(uri, projection, null, null, null);
if (c != null) {
while (c.moveToNext) {
String name = c.getString(c.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
String number = c.getString(c.getColumnIndex(ContactsContract.PhoneLookup.NUMBER));
// Здесь можно извлечь нужную часть номера, например, первые 3 цифры:
String part = number.length >= 3 ? number.substring(0, 3) : «»;
// Используем полученные данные…
}
c.close;
}
Если требуется получить не только совпадения по префиксу, а произвольный фрагмент (например, средние цифры), то после получения полного номера применяем обычные строковые операции Java: substring, indexOf, регулярные выражения и т.д.
Извлечение части номера через SQL
Когда контакты хранятся в собственной базе данных (например, на сервере или в локальной SQLite), удобно написать эффективный запрос, который сразу вернёт нужный фрагмент номера.
Пример структуры таблицы
CREATE TABLE contacts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
phone TEXT NOT NULL
);
Запрос для получения первых трёх цифр (кода оператора)
SELECT id, name, SUBSTR(phone, 1, 3) AS operator_code
FROM contacts
WHERE phone LIKE ‘916%’; — пример фильтра по префиксу
Функция SUBSTR (или SUBSTRING в некоторых диалектах) позволяет вырезать часть строки, начиная с указанной позиции и заданной длины.
Запрос для получения последних четырёх цифр
SELECT id, name, SUBSTR(phone, -4) AS last_four
FROM contacts;
Отрицательный старт в SUBSTR считается от конца строки, что удобно для получения суффикса.
Оптимизация
- Индексируйте столбец
phone, если часто выполняете поиск по префиксу (LIKE 'prefix%'). - Избегайте функций в условии
WHERE, которые препятствуют использованию индекса (например,WHERE SUBSTR(phone,1,3) = '916'лучше заменить наWHERE phone LIKE '916%'). - Если нужно часто извлекать разные части номера, рассмотрите возможность добавления вычисляемых столбцов (например,
operator_code) и их индексирования.
Практические рекомендации
- Всегда проверяйте длину номера перед применением
substring, чтобы избежатьIndexOutOfBoundsException. - Учитывайте международный формат номера (+7, 007 и т.д.). При необходимости сначала нормализуйте номер, удаляя все нецифровые символы.
- Для мобильных приложений Android рекомендуеться использовать ContentProvider и
CursorLoader(или современныеLiveData+Room) для асинхронной загрузки данных. - Если работаете с серверной частью, переносите логику извлечения части номера в уровень базы данных – это уменьшит объём передаваемых данных и упростит клиентский код.
Извлечение части номера телефона – распространённая задача, которая решается как на клиенте (Android) с помощью ContentResolver и CONTENT_FILTER_URI, так и на сервере с помощью обычных SQL‑запросов, использующих функции SUBSTR, LEFT, RIGHT и т.д. Правильный выбор подхода зависит от архитектуры приложения, частоты выполнения операции и требований к производительности. Следуя приведённым рекомендациям, вы сможете эффективно и безопасно получать нужные фрагменты номеров телефонов из контактов или собственной базы данных.