6.0 KiB
Автобус №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
(аналог 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) и сохраняется вSharedPreferencesbus127_push.- Приложение подписывается на топик
bus127при старте. Отдельного создания топика в консоли не требуется — публикация в него проходит и для несуществующего. - Если в запросе есть секция
notification— уведомление показывает сам SDK; если переданы толькоdata(title/body, необязательныйurl) — приложение показывает его само и открывает ссылку по клику.
Рассылка
Всем подписчикам топика (все устройства, открывшие приложение):
POST https://vkpns-topics.rustore.ru/v1/projects/{project_id}/topics/{topic}/publish
Authorization: Bearer {service-token}
{"message":{"notification":{"title":"...","body":"..."}}}
Одному устройству — по его push-токену:
POST https://vkpns.rustore.ru/v1/projects/{project_id}/messages:send
Authorization: Bearer {service-token}
{"message":{"token":"...","notification":{"title":"...","body":"..."}}}
Если устройства не подписались сами, их токены можно подписать разом:
POST .../topics/{topic}/batch_subscribe с {"push_tokens":[...]}.
Ответ 400 с текстом про registration token означает, что адресат не указан
или токен устройства неверен; 401/403 — неверный сервисный токен или его пара с project_id.
Структура
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 # веб-версия (та же страница, для браузера)
Сборка
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 — в релизах и в репозитории android_apk.
Лицензия
MIT.