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:
parent
93908e3365
commit
dd1642b6e9
9 changed files with 121 additions and 19 deletions
|
|
@ -72,7 +72,7 @@ class BleHrService : Service() {
|
|||
ACTION_SCAN -> {
|
||||
startForeground(NOTIFICATION_ID, buildNotification("Поиск BLE..."))
|
||||
scanDevices()
|
||||
return START_STICKY
|
||||
return START_NOT_STICKY // don't let Android restart us into an empty null-intent churn
|
||||
}
|
||||
else -> {
|
||||
val address = intent?.getStringExtra(EXTRA_ADDRESS)
|
||||
|
|
@ -84,7 +84,7 @@ class BleHrService : Service() {
|
|||
dataFile = File(appDataDir, "ble_hr_data.json")
|
||||
connectDevice(address)
|
||||
}
|
||||
return START_STICKY
|
||||
return START_NOT_STICKY // connect is user-initiated; no sticky restart
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -184,8 +184,12 @@ class BleHrService : Service() {
|
|||
android.os.Handler(mainLooper).postDelayed({
|
||||
scanner.stopScan(scanCallback)
|
||||
if (gatt == null) {
|
||||
Log.d(TAG, "Scan timeout, trying direct connect to $address")
|
||||
directConnect(adapter, address)
|
||||
// Not seen in the scan → the band isn't nearby/on. Do NOT hold a GATT connect to
|
||||
// an absent device (that keeps the radio busy and drains the battery). Give up;
|
||||
// the user re-taps "Подключить" once the band is on.
|
||||
Log.d(TAG, "Scan timeout, device $address not found - stopping")
|
||||
writeData("""{"status":"not_found","ts":${System.currentTimeMillis()/1000}}""")
|
||||
stopSelf()
|
||||
}
|
||||
}, 5000)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -507,6 +507,13 @@ class MainActivity : TauriActivity() {
|
|||
intent.action = BleHrService.ACTION_STOP
|
||||
startService(intent)
|
||||
}
|
||||
cmd == "ble_request_enable" -> {
|
||||
Log.d("BalDav", "Requesting Bluetooth enable")
|
||||
if (ensureBlePermissions()) {
|
||||
try { startActivity(Intent(android.bluetooth.BluetoothAdapter.ACTION_REQUEST_ENABLE)) }
|
||||
catch (e: Exception) { Log.e("BalDav", "BT enable request failed: ${e.message}") }
|
||||
}
|
||||
}
|
||||
cmd == "check_update" -> {
|
||||
checkForUpdate(appDataDir)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -438,6 +438,21 @@ pub async fn ble_disconnect(
|
|||
}
|
||||
}
|
||||
|
||||
// Ask the OS to turn Bluetooth on (system ACTION_REQUEST_ENABLE dialog). BLUETOOTH_CONNECT is
|
||||
// already granted, so no extra permission. Called when the user taps "Подключить" with BT off.
|
||||
#[tauri::command]
|
||||
pub async fn ble_request_enable(
|
||||
app: tauri::AppHandle,
|
||||
) -> Result<String, String> {
|
||||
#[cfg(not(target_os = "android"))]
|
||||
{ let _ = &app; Ok("desktop: no-op".to_string()) }
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
android::send_command(&app, "ble_request_enable")?;
|
||||
Ok("Requesting enable".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn ble_get_hr(
|
||||
app: tauri::AppHandle,
|
||||
|
|
|
|||
|
|
@ -1154,7 +1154,7 @@ pub fn run() {
|
|||
.add_migrations("sqlite:baldav.db", migrations)
|
||||
.build(),
|
||||
)
|
||||
.invoke_handler(tauri::generate_handler![get_safe_insets, import_seed_products, import_tiles, download_file, get_points_filename, delete_points_file, gps_set_session_id, list_points_files, read_points_file, pick_file_open, get_picked_file, debug_native_paths, rebuild_roads, get_road_points, get_ride_graph, get_app_info, gps_service_command, gps_service_read_points, brouter_route, brouter_download_tile, brouter_download_status, brouter_list_tiles, save_file, export_image, read_file_base64, export_db, import_db, restart_app, get_update_info, http_request, chzn_http, ble::ble_scan, ble::ble_scan_results, ble::ble_connect, ble::ble_disconnect, ble::ble_get_hr, ble::ble_is_connected, ble::ble_check_bluetooth, ble::ble_save_device, ble::ble_clear_hr])
|
||||
.invoke_handler(tauri::generate_handler![get_safe_insets, import_seed_products, import_tiles, download_file, get_points_filename, delete_points_file, gps_set_session_id, list_points_files, read_points_file, pick_file_open, get_picked_file, debug_native_paths, rebuild_roads, get_road_points, get_ride_graph, get_app_info, gps_service_command, gps_service_read_points, brouter_route, brouter_download_tile, brouter_download_status, brouter_list_tiles, save_file, export_image, read_file_base64, export_db, import_db, restart_app, get_update_info, http_request, chzn_http, ble::ble_scan, ble::ble_scan_results, ble::ble_connect, ble::ble_disconnect, ble::ble_get_hr, ble::ble_is_connected, ble::ble_check_bluetooth, ble::ble_save_device, ble::ble_clear_hr, ble::ble_request_enable])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue