Как Niyyah блокирует приложения на Android без AccessibilityService
Niyyah — Android-приложение, которое помогает ограничивать время в выбранных играх и сервисах. Перед запуском заблокированного приложения пользователь видит экран с коротким заданием: например, счётчик тасбиха на 33 или 99 нажатий, аят для набора или одно из 99 имён Аллаха. После выполнения задания доступ к приложению открывается.
Блокировку можно включить на весь день, задать расписание или активировать после исчерпания дневного лимита. Интерфейс Niyyah создан на React Native, а ключевые функции реализованы в нативных модулях на Kotlin: foreground-служба, отслеживание активного приложения, показ собственного экрана поверх других окон и обработка загрузки устройства.
Отслеживание активного приложения
Android не предоставляет обычным приложениям универсального события, которое сообщало бы о запуске конкретного приложения. Один из вариантов — AccessibilityService: он быстро получает события об изменениях окон, но его применение для блокировщиков ограничено правилами Google Play и требует отдельного обоснования.
В Niyyah используется другой механизм — UsageStatsManager и системное разрешение «Доступ к истории использования». Служба периодически запрашивает события за небольшой промежуток времени и определяет, какой пакет последним перешёл на передний план. Если он входит в список заблокированных, приложение показывает собственный экран через разрешение «Показ поверх других приложений».
Экономия энергии и состояние экрана
Первая версия проверяла активное приложение каждую секунду независимо от состояния телефона. Это приводило к лишнему расходу заряда, а при начале расписания ночью могло неожиданно включить экран устройства. Позже цикл ограничили периодом, когда дисплей включён и телефон разблокирован.
Когда экран гаснет, служба прекращает постоянный опрос и ждёт системного события включения дисплея. Приёмник для этого регистрируется непосредственно в службе, поскольку событие включения экрана относится к защищённым системным сигналам. В результате блокировочный экран появляется только после того, как пользователь снова начинает пользоваться телефоном.
Проблема оболочек производителей
Даже foreground-служба с уведомлением, которая по документации Android должна работать до явной остановки, может быть завершена агрессивными механизмами энергосбережения. На некоторых устройствах с MIUI, EMUI, ColorOS и другими оболочками это приводит к незаметному отключению блокировки.
Niyyah пытается компенсировать проблему двумя способами: запускает службу после перезагрузки и обновления приложения, а также проверяет её состояние и наличие необходимых разрешений. Если что-то не работает, пользователь получает предупреждение и кнопку, ведущую в системные настройки для исправления. Полностью устранить ограничения конкретного производителя невозможно, поэтому важнее вовремя сообщить, что блокировка сейчас неактивна.
Нормализация арабского текста
Одно из заданий требует набрать аят на арабском языке. Посимвольное сравнение здесь ненадёжно: пользователь может вводить текст с огласовками или без них, клавиатуры используют разные варианты алифа, а в мусхафе встречаются знаки остановки и номера аятов.
Перед проверкой приложение удаляет огласовки, знаки остановки, номера аятов, кашиду и прочие небуквенные символы, нормализует пробелы и приводит похожие формы букв к единому виду. Разные варианты алифа также заменяются на базовую форму. При этом оригинальный текст сохраняется для отображения и цветовой подсветки таджвида, а сравнение выполняется по отдельной нормализованной версии.
Локальная работа и планы для iOS
В приложении нет рекламы и регистрации: разработчик считает, что монетизация за счёт экранного времени противоречила бы назначению блокировщика. Данные хранятся на устройстве, а время намаза рассчитывается локально более чем для 10 тысяч городов. Геолокация нужна только для выбора города и не является обязательной.
Версии для iPhone пока нет. На iOS сторонние приложения не могут аналогичным образом отслеживать другие программы и выводить поверх них собственный экран. Для подобных сценариев используется Screen Time API с FamilyControls, у которого другая модель работы и собственные ограничения.
Niyyah опубликован в Google Play в октябре и на момент описания получил более 100 установок и первые оценки. Проект разрабатывается одним человеком и остаётся практическим примером того, как собрать блокировщик на Android без AccessibilityService, опираясь на UsageStatsManager, foreground-службу и системные разрешения.


