# Автобус №127 — Расписание (Android) Приложение с расписанием автобуса **№127** по маршруту **Кандалакша — Полярные Зори — Зашеек** (Мурманская область). ## Возможности - **Выбор остановки** — Кандалакша / Полярные Зори / Зашеек. При выборе показываются доступные направления (куда можно уехать). - **Ближайшие рейсы** — по 3 на каждое направление, с подсчётом «через N ч M мин» (время по **МСК**, обновляется каждые 30 сек). - **Автоопределение дня недели** — будни/выходные. - **Полное расписание** — по кнопке раскрывается вся таблица (4 остановки: Кандалакша · ПЗ→Зашеек · Зашеек · ПЗ→Кандалакша). - **Пуш-уведомления** — через RuStore Push, см. раздел ниже. - Тёмная тема, живые часы МСК, подсветка ближайших рейсов (< 15 мин). ## Технические данные | Параметр | Значение | |-----------------|------------------------------| | Тип | WebView-обёртка (HTML/JS) | | Минимальный SDK | 26 (Android 8.0) | | Целевой SDK | 34 (Android 14) | | Сборка | Gradle 8.6 + AGP 8.2.2 | | Подпись | keystore `~/bus127.keystore` (alias `bus127`) | ## Пуш-уведомления (RuStore) Приложение интегрировано с [RuStore Push SDK](https://www.rustore.ru/help/sdk/push-notifications) (аналог Firebase Cloud Messaging). Проект в консоли RuStore привязан к пакету `ru.ua1zbe.bus127` и подписи release-keystore; пока подпись не меняется, перерегистрация не нужна. Для доставки на устройстве должен быть установлен и авторизован **RuStore**. Рассылка выполняется с сервера через API RuStore: ``` POST https://vkpns.rustore.ru/v1/projects/{project_id}/messages:send Authorization: Bearer {service-token} Content-Type: application/json { "message": { "token": "{push-token устройства}", "notification": { "title": "Автобус 127", "body": "Ближайший рейс через 5 мин" } } } ``` - `project_id` и `service-token` берутся в консоли RuStore: **Push-уведомления > Проекты**. В приложение попадает только `project_id`; сервисный токен в APK не хранится. - `push-token` устройства приходит в `onNewToken` (лог `RuStorePush`) и сохраняется в `SharedPreferences` `bus127_push`. - Приложение подписывается на топик `bus127` — топик должен существовать в консоли. Сообщения без поля `topic` приходят всем устройствам проекта. - Если в запросе есть секция `notification` — уведомление показывает сам SDK; если переданы только `data` (`title`/`body`, необязательный `url`) — приложение показывает его само и открывает ссылку по клику. ## Структура ``` apk-webview/ # исходники APK (WebView) ├── app/ │ ├── build.gradle │ └── src/main/ │ ├── AndroidManifest.xml │ ├── java/ru/ua1zbe/bus127/ │ │ ├── MainActivity.java # WebView + запрос разрешения на уведомления │ │ ├── Bus127App.java # инициализация RuStore Push SDK │ │ ├── PushMessagingService.java # приём уведомлений │ │ ├── PushIntents.java # переход по клику │ │ └── push/PushStore.java # хранение push-токена │ ├── assets/index.html # интерфейс (HTML/JS) │ └── res/values/strings.xml └── settings.gradle, build.gradle, gradle.properties web/index.html # веб-версия (та же страница, для браузера) ``` ## Сборка ```bash export JAVA_HOME=$HOME/jdk-17.0.20.1+1 export ANDROID_HOME=$HOME/Android/Sdk cd apk-webview ~/gradle-8.6/bin/gradle assembleRelease --no-daemon ``` Готовый APK — в [релизах](../../releases) и в репозитории `android_apk`. ## Лицензия MIT.