На Oppo/OnePlus/Realme стандартного исключения из оптимизации батареи мало —
система схлопывает приложение в фоне. Один раз показываем пояснение и открываем
настройки приложения, чтобы юзер включил «Разрешить работу в фоновом режиме».
На OnePlus/ColorOS радио глохло в фоне даже с wake mode. Причины: POST_NOTIFICATIONS
не выдан (медиа-уведомление не показывалось → foreground-сервис хрупкий) и
приложение не в вайтлисте Doze. MainActivity на старте запрашивает POST_NOTIFICATIONS
(13+), затем системный диалог REQUEST_IGNORE_BATTERY_OPTIMIZATIONS (один раз).
v1.4 / versionCode 5 (clean-сборка).
Причина петли: при bump 2→3 инкрементальная сборка НЕ пересобрала BuildConfig.dex —
в v3 APK manifest versionCode=3, но BuildConfig.VERSION_CODE остался 2. Приложение
сравнивало manifest(3) > BuildConfig(2) → всегда предлагало обновиться, ставило
тот же v3, снова предлагало. Фикс: ./gradlew clean перед сборкой релиза —
BuildConfig теперь совпадает с versionCode. Проверено на телефоне: v4, диалога нет.
UpdateManager: на старте дёргает /app-version, при version_code > BuildConfig.
VERSION_CODE показывает UpdateDialog. Скачивает APK во внутр. Download, сверяет
SHA-256 (защита от подмены по HTTP/битой загрузки), ставит через системный
установщик (FileProvider). force_update делает диалог необкрываемым. versionCode
1→2, versionName 1.0→1.1. Добавлено право REQUEST_INSTALL_PACKAGES, путь в file_paths.
- RecordingPlaybackController: ExoPlayer создаётся лениво (на первый play) и
освобождается в stop() — раньше второй плеер висел в памяти всю сессию у каждого.
Поллер позиции 500мс крутится только во время игры (был вечный 2 Гц main-loop).
- StationRepositoryImpl.refreshStations: merge каталога O(n) через apiById/apiByName
индексы вместо .find на каждую станцию (было O(n²) ~700×700 на холодном старте).
Убраны verbose Log.d-трейсы (оставлен Log.e/.w на ошибки).
- Track/Station/StreamQuality помечены @Immutable — read-only модели, иначе
списки tags/qualities делали класс нестабильным → лишние рекомпозиции списков.
- HttpLoggingInterceptor только при BuildConfig.DEBUG (включён buildConfig feature):
в релизе нет оверхеда на каждый запрос и утечки URL в logcat.