BLE HR: connect manually only, no auto-scan on every ride (battery)

Recording auto-called ble_connect each ride, and the Kotlin service held a
GATT connect to an absent band (radio busy) plus START_STICKY churn -
draining the battery when the band was away or Bluetooth off.

- gps.js _startHrMonitor: drop the auto ble_connect; keep only the cheap HR
  poll so a manual connect (now or mid-ride) lands HR in the track.
- Settings: a 'Подключить' button for the paired band, usable any time incl.
  during a ride. BT off -> ble_request_enable (system enable dialog); on ->
  ble_connect, start the poll if recording, report connected / not found.
- ble.rs: ble_request_enable command (+ handler registration).
- MainActivity: ble_request_enable -> ACTION_REQUEST_ENABLE (BLUETOOTH_CONNECT
  already in manifest).
- BleHrService: START_NOT_STICKY; if the 5s scan doesn't find the address,
  stopSelf instead of directConnect to an absent device.
This commit is contained in:
4aiman 2026-10-02 14:03:16 +03:00
commit dd1642b6e9
9 changed files with 121 additions and 19 deletions

View file

@ -0,0 +1,41 @@
# Сессия 2026-10-02 - BLE-пульсометр: подключение вручную, без авто-поиска
По утверждённому плану `~/.claude/plans/merry-discovering-dream.md`.
## Проблема
Расход батареи: при КАЖДОМ старте записи `GPS._startHrMonitor` безусловно звал `ble_connect`, а
Kotlin `BleHrService` при отсутствии браслета всё равно делал `directConnect` (держит радио) +
сервис `START_STICKY`. Если браслета нет рядом или BT выключен - расход впустую.
## Поведение (по указанию пользователя)
1. BT включён: НЕ искать/коннектиться автоматически. Подключение к сопряжённому браслету - только
вручную, кнопкой в настройках, доступной в любой момент (в т.ч. во время записи). Нажал ->
пульс пишется в трек с этого момента.
2. BT выключен: ничего не делать; при ручной попытке - системный запрос включить BT.
## Правки
- `frontend/js/gps.js` `_startHrMonitor`: убран авто `ble_connect`. Остался только дешёвый опрос
`ble_get_hr` (2с -> `currentHr`), чтобы ручное подключение (сейчас или позже по ходу записи)
начало класть пульс в трек.
- `frontend/js/main.js` настройки "Пульсометр (BLE)": кнопка **"Подключить"** (видна, когда
устройство сопряжено). Обработчик: `ble_check_bluetooth`; `off` -> `ble_request_enable` +
подсказка; `on` -> `ble_connect(addr,type)`; если идёт запись - поднять опрос
`GPS._startHrMonitor()`; короткий опрос статуса ~6с -> "подключён"/"браслет не найден".
- `src-tauri/src/ble.rs`: команда `ble_request_enable` (android -> send_command
"ble_request_enable"); зарегистрирована в `lib.rs` invoke_handler.
- `MainActivity.kt`: ветка `ble_request_enable` -> `startActivity(ACTION_REQUEST_ENABLE)` под
`ensureBlePermissions()`. Разрешение BLUETOOTH_CONNECT в манифесте уже есть.
- `BleHrService.kt`: `START_STICKY` -> `START_NOT_STICKY` (scan/connect; нет churn после убийства);
`connectDevice` - если скан 5с НЕ нашёл адрес, `stopSelf` вместо `directConnect` к отсутствующему
устройству (именно directConnect держал радио).
## Коммит
Одним коммитом (JS+Rust+Kotlin - одна связная фича: кнопка зовёт новую команду; дробить на
нерабочие промежутки смысла нет).
## Проверка (устройство, debug)
- Запись без браслета / BT off: нет "Поиск BLE", нет коннекта (logcat BleHrService молчит). GPS ок.
- BT off -> "Подключить": системный запрос включить BT.
- BT on, браслет надет -> "Подключить" (в т.ч. во время записи): подключается, heart_rate пишется
в точки с момента подключения.
- BT on, браслета нет -> "Подключить": "браслет не найден", сервис остановился (не висит).