143 lines
8.3 KiB
Markdown
143 lines
8.3 KiB
Markdown
# Автобус №127 — Расписание (Android)
|
||
|
||
Приложение с расписанием автобуса **№127** по маршруту
|
||
**Кандалакша — Полярные Зори — Зашеек** (Мурманская область).
|
||
|
||
## Возможности
|
||
|
||
- **Выбор остановки** — Кандалакша / Полярные Зори / Зашеек. При выборе
|
||
показываются доступные направления (куда можно уехать).
|
||
- **Ближайшие рейсы** — по 3 на каждое направление, с подсчётом
|
||
«через N ч M мин» (время по **МСК**, обновляется каждые 30 сек).
|
||
- **Автоопределение дня недели** — будни/выходные.
|
||
- **Полное расписание** — по кнопке раскрывается вся таблица
|
||
(4 остановки: Кандалакша · ПЗ→Зашеек · Зашеек · ПЗ→Кандалакша).
|
||
- **Карта с автобусами** — пункт меню «Карта» открывает VK Карты: видно
|
||
пройденный участок маршрута и автобусы прямо сейчас (без подписей остановок —
|
||
они были бы только шумом). Положение считается **по расписанию** (приложение
|
||
не берёт координаты с GPS), поэтому это оценка с точностью до нескольких
|
||
минут; внизу перечислены автобусы с направлением и временем прибытия.
|
||
Обновление каждые 20 сек.
|
||
- **Пуш-уведомления** — через 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` при старте. Отдельного создания топика
|
||
в консоли не требуется — публикация в него проходит и для несуществующего.
|
||
- Если в запросе есть секция `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 + запрос разрешения
|
||
│ │ ├── AboutActivity.java # окно «О приложении»
|
||
│ │ ├── MapActivity.java # экран карты (свой WebView на тот же index.html#map)
|
||
│ │ ├── Webs.java # общий WebView для всех экранов
|
||
│ │ ├── BusBridge.java # мост страницы и приложения (меню, назад, версия)
|
||
│ │ ├── Bus127App.java # инициализация RuStore Push SDK
|
||
│ │ ├── PushMessagingService.java # приём уведомлений
|
||
│ │ ├── PushIntents.java # переход по клику
|
||
│ │ └── push/PushStore.java # хранение push-токена
|
||
│ ├── assets/index.html # интерфейс (HTML/JS)
|
||
│ ├── assets/route.js # геометрия маршрута OSRM + координаты остановок ([lat,lon])
|
||
│ ├── assets/mmr-gl.js # VK Maps SDK (UMD, глобаль mmrgl), BSD-3-Clause
|
||
│ ├── assets/mmr-gl.css # стили SDK
|
||
│ └── 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. В `app/src/main/assets/` лежит сторонний код со своей лицензией:
|
||
|
||
- `mmr-gl.js`, `mmr-gl.css` — VK Maps SDK, BSD-3-Clause,
|
||
текст в `mmr-gl.LICENSE.txt`;
|
||
- `route.js` — геометрия дороги и координаты остановок из OpenStreetMap
|
||
(ODbL), атрибуция также выводится самими VK Картами.
|