Введение
В первой части статьи мы рассмотрели архитектуру и ключевые компоненты приложения 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, корутины) позволяют создавать эффективные решения для бизнес-задач. Разработанная архитектура может служить основой для создания подобных систем трекинга.