Данная статья содержит описание внутреннего устройства умного обработчика служебных смс.
Приложение парсит входящие смс-ки и показывает только важную информацию из них.
Показывает красиво, быстро и удобно. 1. Как это работает В манифесте прописываем разрешение на получение и чтение SMS Там же регистрируем receiver
Разрешение action_sms_received_test нужно для тестирования.
Чтобы не тратить деньги на настоящие смс во время тестирования, я отправляю Intent с этим action из приложения и ловлю его. Теперь ресивер будет получать все входящие сообщения Теперь в методе handleIncomingSms(context, intent); требуется разобраться, что за СМС нам пришла, и принять решение о том, что делать.
Если она является служебной — мы её разбираем, достаем полезную информацию, и отображаем её в красивом виде.
Каким образом мы понимаем, служебная она или нет — опишу позже. Грубо, это выглядит так Метод checkTemplates(); Метод showPopupDialog После этого пользователь видит такой экран
Смысл в том, чтобы быстро увидеть полезную информацию  2. Алгоритм распознавания СМС и выдачи важной информации 2.1. Кратко 2.2. Подробно о модели Шаблон выглядит так Служебные слова делятся на extra и обычные.
Extra означает, что их нет в шаблоне.
Примеры: ~SUM~ — обычное служебное слово. Означает выражение с цифрами, разделенное точкой или запятой.
Используется для определения суммы денег. Для его поиска используется regex ~CURRENCY~ — обычное слово, которое может принимать несколько значений. Для его поиска используется перебор его значений. ~EXTRA_CODE_WORD~ — служебное слово типа extra. Используется для вывода текста "Кодовое слово" в результате. также нам нужны картинки, чтобы показать, кто именно отправил сообщение.
Эта информация хранится в объектах sender. Пример:
Это Альфа банк и его иконка. В итоге не сервере хранится Полный json можно посмотреть здесь 2.3. Подробно об алгоритме Мы скачиваем модель, сохраняем её.
Дальше следует сама процедура разбора смс и создание результирующего сообщения. Для парсинга текста сообщения я использую класс SmsParser со статичными методами.
Главный метод — getMessageLines(SmsTemplate smsTemplate, String realSmsText)
Он возвращает строки сообщения, если все ок, или null, если мы не нашли подходящий шаблон.
Этот метод вызывается из этого места метода checkTemplates, приведенного выше. Мы проходим по всем шаблонам из базы и пытаемся для каждого взять message lines.
Если получилось — показываем экран с информацией.. Логика getMessageLines кратко
Бежим по маске и сравниваем её посимвольно с текстом смс, записывая в массив значения встретившихся служебных слов, или выкидывая nullесли встретили несоответствия Логика getMessageLines подробнее: Логика с примерами кода Как параметры, в метод нам приходят шаблон и текст смс В начале метода инициализируем лист служебных слов. В базу они попали из регулярного обновления с апи.
Нам нужна глобальная переменная, т.к. метод большой и разбит на части. Затем создаем список служебных слов из заданного шаблона. т.е. если у нас есть шаблон  то мы хотим получить список  далее идет основная логика Она делает ровно то, что описано выше, как "Логика getMessageLines подробнее:" Далее мы пересортировываем список, т.к. в тексте он встречается в другом порядке, чем наших message lines Далее мы добавляем служебные слова типа extra, т.к. мы их не находили при прохождении по тексту смс. Это нужно вот почему.
На вход нам подали smsTemplate. У него есть набор messageLines. Например, их было 4. Но в процессе проверки текста на совпадение с шаблоном мы нашли только SUM_0 и SUM_1
Т.к. это данные, которые реально есть в тексте СМС.
Таким образом, после первого куска логики мы имеем массив из двух элементов (в данном случае 212,30 и 20537,96).
Но на выход нам нужно подать 4 строки (к этим двум нужно еще добавить EXTRA_PURCHASE и EXTRA_TOTAL), причем в нужном порядке.
Поэтому в конце метода мы их добавляем. В итоге, на выходе мы получаем массив из четырех строк. Например, если у нас был шаблон то на выходе мы получим На этом главная логика заканчивается.
Далее мы просто показываем это в нашей попап активити таким методом Текст messageLines просто отображается в текст вьюшках.
iconUrl подгружается в image view с помощью Glide — тут все предельно просто. Заключение Очевидно, что алгоритм примитивен и может быть улучшен.
Из идей Но поставленную задачу приложние решает.  Прилагаю главный класс для парсинга сообщений.
Он немного отличается от кода, приведенного выше,
т.к. приведенный код был улучшен визуально. Teamlead