Введение
В первой части статьи мы рассмотрели архитектуру и ключевые компоненты приложения Open Tracker. Во второй части сосредоточимся на реализации пользовательского интерфейса и особенностях его взаимодействия с системными компонентами.
Дизайн и структура интерфейса
UI приложения разработан с учетом минималистичного подхода, так как основная функциональность работает в фоновом режиме. Приложение использует темную тему и состоит из трех основных экранов:
OverView — главный информационный экран
Log — журнал событий
Settings — настройки приложения
Навигация между экранами реализована с помощью Bottom Navigation Bar, что обеспечивает интуитивно понятное взаимодействие.

Экран OverView
На главном экране отображается:
Статус трекера (Запущен/Ожидает/Остановлен)
Время последнего получения координат GPS
Время последнего определения сотовых вышек (в текущей версии не используется)
Статус пакетов данных (готовы к отправке или отправлены)
Особенность: кнопка для немедленной отправки накопленных пакетов, что полезно для тестирования и отладки (в текущей версии не используется).
Экран Log
Журнал событий отображает последние 60 записей с визуальными метками:
GPS — получение координат
GSM — данные сотовых вышек
LOG — системные события
Экран Settings
Настройки включают:
Поля для ввода логина, пароля и адреса сервера
Переключатель постоянного трекинга (только для тестовых целей)
Работа с системными разрешениями
Для корректной работы приложения требуются следующие разр��шения:
POST_NOTIFICATIONS(уведомления)ACCESS_FINE_LOCATION(точное местоположение)ACCESS_BACKGROUND_LOCATION(геолокация в фоне)REQUEST_IGNORE_BATTERY_OPTIMIZATIONS(отключение оптимизации батареи)
При первом запуске пользователь последовательно проходит через два экрана:
PermissionScreen — запрос необходимых разрешений
BatteryOptScreen — настройки оптимизации батареи

Только после предоставления всех необходимых разрешений становится доступен главный экран приложения. Ниже показан код реализации такого поведения.
@Composable fun TrackerApp() { TrackerTheme { val context = LocalContext.current var showPermissionScreen by remember { mutableStateOf(!context.hasAllPermissions()) } var showBatteryOptScreen by remember { mutableStateOf(context.isBatteryOptimizationEnabled()) } when { showPermissionScreen -> { PermissionScreen( onDismiss = { showPermissionScreen = false }, onOpenSettings = { context.openAppSettings() } ) } showBatteryOptScreen -> { BatteryOptScreen ( onDismiss = { showBatteryOptScreen = false }, onOpenBatteryOptSettings = { context.openBatteryOptimizationSettings() } ) } else -> { MainScreen() } } } }
Взаимодействие между Service и UI
Для передачи данных между фоновым сервисом и пользовательским интерфейсом используются:
В Service: два StateFlow (
trackerState,trackerHistory)В ViewModel: соответствующие StateFlow (
uiOverView,uiHistory)
Механизм обмена данными:
В ViewModel происходит подключение к Service
Запускаются корутины для сбора данных из StateFlow Service
Данные трансформируются и передаются в StateFlow ViewModel
UI-компоненты подписываются на StateFlow ViewModel для отображения информации
private val connection = object : ServiceConnection { override fun onServiceConnected(className: ComponentName, service: IBinder) { val binder = service as TrackerService.LocalBinder boundService = binder.getService() isBound = true // Подписываемся на изменения состояния сервиса viewModelScope.launch { boundService?.trackerState?.collect { trackerState -> _uiOverView.value = trackerState } } viewModelScope.launch { boundService?.trackerHistory?.collect{ history-> _uiHistory.value = history } } } override fun onServiceDisconnected(arg0: ComponentName) { isBound = false boundService = null } }
Заключение
Во второй части статьи мы рассмотрели:
Минималистичный дизайн интерфейса, оптимизированный для фоновой работы
Три основных экрана приложения и их функциональность
Систему запроса и обработки необходимых разрешений
Механизм взаимодействия между фоновым сервисом и пользовательским интерфейсом
Ключевые преимущества реализованного решения:
Простота использования: минимальное взаимодействие с пользователем
Наглядность: четкая визуализация статусов и событий
Гибкость: возможность расширения функциональности
Перспективы развития:
Реализация полноценной системы аутентификации
Добавление аналитики маршрутов
Исходный код проекта доступен на GitHub
Приложение Open Tracker демонстрирует, как современные Android-технологии (Compose, StateFlow, корутины) позволяют создавать эффективные решения для бизнес-задач. Разработанная архитектура может служить основой для создания подобных систем трекинга.
