«Open Tracker: как разработать Android-приложение для автоматического трекинга коммерческих представителей. Часть 2»

от автора

Введение

В первой части статьи мы рассмотрели архитектуру и ключевые компоненты приложения Open Tracker. Во второй части сосредоточимся на реализации пользовательского интерфейса и особенностях его взаимодействия с системными компонентами.

Дизайн и структура интерфейса

UI приложения разработан с учетом минималистичного подхода, так как основная функциональность работает в фоновом режиме. Приложение использует темную тему и состоит из трех основных экранов:

  1. OverView — главный информационный экран

  2. Log — журнал событий

  3. Settings — настройки приложения

Навигация между экранами реализована с помощью Bottom Navigation Bar, что обеспечивает интуитивно понятное взаимодействие.

Главные экраны приложения

Главные экраны приложения

Экран OverView

На главном экране отображается:

  • Статус трекера (Запущен/Ожидает/Остановлен)

  • Время последнего получения координат GPS

  • Время последнего определения сотовых вышек (в текущей версии не используется)

  • Статус пакетов данных (готовы к отправке или отправлены)

Особенность: кнопка для немедленной отправки накопленных пакетов, что полезно для тестирования и отладки (в текущей версии не используется).

Экран Log

Журнал событий отображает последние 60 записей с визуальными метками:

  • GPS — получение координат

  • GSM — данные сотовых вышек

  • LOG — системные события

Экран Settings

Настройки включают:

  • Поля для ввода логина, пароля и адреса сервера

  • Переключатель постоянного трекинга (только для тестовых целей)

Работа с системными разрешениями

Для корректной работы приложения требуются следующие разрешения:

  • POST_NOTIFICATIONS (уведомления)

  • ACCESS_FINE_LOCATION (точное местоположение)

  • ACCESS_BACKGROUND_LOCATION (геолокация в фоне)

  • REQUEST_IGNORE_BATTERY_OPTIMIZATIONS (отключение оптимизации батареи)

При первом запуске пользователь последовательно проходит через два экрана:

  1. PermissionScreen — запрос необходимых разрешений

  2. 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 (trackerStatetrackerHistory)

  • В ViewModel: соответствующие StateFlow (uiOverViewuiHistory)

Механизм обмена данными:

  1. В ViewModel происходит подключение к Service

  2. Запускаются корутины для сбора данных из StateFlow Service

  3. Данные трансформируются и передаются в StateFlow ViewModel

  4. 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         }     }

Заключение

Во второй части статьи мы рассмотрели:

  1. Минималистичный дизайн интерфейса, оптимизированный для фоновой работы

  2. Три основных экрана приложения и их функциональность

  3. Систему запроса и обработки необходимых разрешений

  4. Механизм взаимодействия между фоновым сервисом и пользовательским интерфейсом

Ключевые преимущества реализованного решения:

  • Простота использования: минимальное взаимодействие с пользователем

  • Наглядность: четкая визуализация статусов и событий

  • Гибкость: возможность расширения функциональности

Перспективы развития:

  • Реализация полноценной системы аутентификации

  • Добавление аналитики маршрутов

Исходный код проекта доступен на GitHub

Приложение Open Tracker демонстрирует, как современные Android-технологии (Compose, StateFlow, корутины) позволяют создавать эффективные решения для бизнес-задач. Разработанная архитектура может служить основой для создания подобных систем трекинга.


ссылка на оригинал статьи https://habr.com/ru/articles/929484/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *