- Подключён ru.rustore.sdk:pushclient:7.4.0 (репозиторий Rustore). - SvxApp: канал svx_push и инициализация RuStorePushClient с project_id; push-токен устройства сохраняется в настройках. - PushMessagingService (RuStoreMessagingService): onNewToken, onMessageReceived (data-only пуши показываем сами), onDeletedMessages, onError. - Манифест: сервис, значок/канал по умолчанию, android.useAndroidX=true (зависимость тянет androidx). - README: как рассылать пуши через vkpns.rustore.ru API.
127 lines
7.7 KiB
Markdown
127 lines
7.7 KiB
Markdown
# SVXHomyak
|
||
|
||
Android-клиент для подключения к рефлекторам **SVXLink** (svxreflector) — слушайте и участвуйте в групповых переговорах (TG) прямо со смартфона.
|
||
|
||
## Возможности
|
||
|
||
- Подключение к рефлектору SVXLink по протоколу v2 с авторизацией по AUTH_KEY
|
||
- Выбор группы вещания (TG) — по умолчанию 11
|
||
- Голосовая связь в формате **Opus** (8 кГц, моно) через UDP
|
||
- Кнопка PTT (Push-To-Talk) в стиле Zello — крупная, с градиентом и тенью; удерживайте, чтобы говорить
|
||
- Индикаторы уровня передачи (микрофон) и приёма (S-метры)
|
||
- **Статистика приёма** (потери, %, и джиттер, мс) — включается в скрытых настройках звука
|
||
- **Выбор битрейта передачи** — Авто (адаптация под качество канала) либо фиксированный 6–32 кбит/с (скрытые настройки звука)
|
||
- **Мониторинг групп** — кнопка наушников: прослушивание выбранных групп с автоматическим возвратом к базовой после паузы
|
||
- **Запись приёма в OGG** с пропуском тишины (подробности ниже)
|
||
- Строка текущего говорящего между блоками экрана:
|
||
- при приёме — `Говорит UA1ZBE-M TG12`
|
||
- без приёма — `UA1ZBE-M TG12` (последний говоривший)
|
||
- Автоматическое переподключение при обрыве связи
|
||
- Уведомления о входе/выходе участников (опционально)
|
||
- Позывной регистронезависимый: `ua1zbe-m` автоматически преобразуется в `UA1ZBE-M` для отправки на сервер
|
||
|
||
## Запись приёма
|
||
|
||
- Кнопка записи расположена между позывным и кнопкой мониторинга групп.
|
||
- **Короткое нажатие** — начать/остановить запись. Файл сохраняется в
|
||
`Android/data/ru.ua1zbe.svxremote/files/recordings/rec_ГГГГ-ММ-ДД_ЧЧ-ММ-СС.ogg`.
|
||
- Записывается только реальный приём: паузы в эфире (тишина) в файл не попадают,
|
||
реплики склеиваются без разрывов.
|
||
- **Удержание кнопки 3 секунды** — открывается список записей: воспроизведение
|
||
(повторный тап останавливает) и удаление с подтверждением. Если записей нет —
|
||
выводится подсказка.
|
||
|
||
## Скрытые настройки звука
|
||
|
||
Открываются тройным тапом по заголовку «SVXHomyak» на главном экране. Позволяют:
|
||
|
||
- включить/выключить отображение статистики приёма (потери/джиттер);
|
||
- выбрать битрейт передачи (Авто или 6–32 кбит/с).
|
||
|
||
## Требования
|
||
|
||
- Android 8.0 (API 26) и выше
|
||
- Доступ к сети и микрофону
|
||
- Рефлектор SVXLink с включённой поддержкой протокола v2 (AUTH_KEY)
|
||
- Для push-уведомлений: установить и авторизоваться в приложении **RuStore** на устройстве (оно является дистрибьютором пуша)
|
||
|
||
## Push-уведомления (RuStore)
|
||
|
||
Приложение интегрировано с [RuStore Push SDK](https://www.rustore.ru/help/sdk/push-notifications) (аналог Firebase Cloud Messaging). Для доставки на устройстве должен быть установлен и авторизован RuStore (или приложение-дистрибьютор экосистемы VK).
|
||
|
||
Рассылка выполняется с сервера через 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": "Говорит UA1ZBE1 TG12",
|
||
"body": "..."
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
- `project_id` и `service-token` берутся в консоли RuStore: **Push-уведомления > Проекты**.
|
||
- `push-token` устройства приходит в callback `onNewToken` (лог `RuStorePush`), сохраняется в настройках приложения.
|
||
- Если в запросе есть секция `notification` — уведомление отображает сам SDK; если переданы только `data` (`title`/`body`) — приложение показывает его самостоятельно.
|
||
|
||
## Установка
|
||
|
||
Скачайте последний APK со страницы [Releases](https://git2.ua1zbe.ru/ua1zbe/svxhomyak/releases) и установите его на устройство (разрешите установку из неизвестных источников).
|
||
|
||
## Использование
|
||
|
||
1. Откройте **Настройки** (иконка шестерёнки).
|
||
2. Укажите:
|
||
- **Сервер** — адрес рефлектора (хост или IP)
|
||
- **Порт** — по умолчанию `5300`
|
||
- **Позывной** — ваш позывной, например `UA1ZBE-M`
|
||
- **Пароль (AUTH_KEY)** — ключ доступа к рефлектору
|
||
- **Группа вещания (TG)** — номер группы
|
||
3. Нажмите **Сохранить**, затем **Подключиться**.
|
||
4. Для передачи удерживайте кнопку PTT.
|
||
|
||
## Сборка из исходников
|
||
|
||
```bash
|
||
./gradlew :app:assembleDebug
|
||
```
|
||
|
||
APK появится в `app/build/outputs/apk/debug/app-debug.apk`.
|
||
|
||
Для сборки релизного (подписанного) APK:
|
||
|
||
```bash
|
||
./gradlew :app:assembleRelease
|
||
# далее выровнять и подписать через build-tools (zipalign + apksigner)
|
||
```
|
||
|
||
Требования: JDK 17, Android SDK (compileSdk 34).
|
||
|
||
## Структура проекта
|
||
|
||
- `app/src/main/java/ru/ua1zbe/svxremote/MainActivity.kt` — основной экран и логика UI
|
||
- `app/src/main/java/ru/ua1zbe/svxremote/SettingsActivity.kt` — настройки подключения
|
||
- `app/src/main/java/ru/ua1zbe/svxremote/proto/ReflectorClient.kt` — клиент рефлектора (TCP + UDP)
|
||
- `app/src/main/java/ru/ua1zbe/svxremote/proto/ReflectorProtocol.kt` — бинарный протокол svxreflector v2
|
||
- `app/src/main/java/ru/ua1zbe/svxremote/audio/OpusEngine.kt` — кодирование/декодирование Opus через MediaCodec
|
||
- `app/src/main/java/ru/ua1zbe/svxremote/audio/RxRecorder.kt` — запись приёма в OGG (MediaCodec + MediaMuxer)
|
||
- `app/src/main/java/ru/ua1zbe/svxremote/ui/` — кнопка PTT (стиль Zello), S-метр, индикатор уровня
|
||
- `app/src/test/java/ru/ua1zbe/svxremote/` — юнит-тесты протокола и рукопожатия
|
||
|
||
## Тесты
|
||
|
||
```bash
|
||
./gradlew :app:testDebugUnitTest
|
||
```
|
||
|
||
## Лицензия
|
||
|
||
Проект распространяется без ограничений (для радиолюбительских целей).
|