Prompt to enable Bluetooth/location at recording start + two 'don't ask' settings

User forgets to turn BT/GPS on. Modern Android won't let an app toggle them
silently, so prompt and act: BT via the system enable dialog, location via
the location-settings screen.

- ensureSystemReady(needBt, needGps) runs before startRecording: BT off ->
  confirm -> ble_request_enable; location off -> confirm -> open settings.
  Gated by two settings (baldav_dontask_bt / _gps); declining proceeds.
- GPS.isLocationEnabled polls a new Kotlin check (check_location writes
  location_state.json via LocationManager; read_state_file reads it);
  open_location_settings opens ACTION_LOCATION_SOURCE_SETTINGS.
- Settings: 'Не спрашивать про Bluetooth' / '... геолокацию' checkboxes.
This commit is contained in:
4aiman 2026-10-17 02:07:44 +03:00
commit 2d0e51bd8d
5 changed files with 104 additions and 1 deletions

View file

@ -514,6 +514,19 @@ class MainActivity : TauriActivity() {
catch (e: Exception) { Log.e("BalDav", "BT enable request failed: ${e.message}") }
}
}
cmd == "check_location" -> {
val lm = getSystemService(LOCATION_SERVICE) as? LocationManager
val enabled = when {
lm == null -> false
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P -> lm.isLocationEnabled
else -> lm.isProviderEnabled(LocationManager.GPS_PROVIDER) || lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
}
File(appDataDir, "location_state.json").writeText("""{"enabled":$enabled}""")
}
cmd == "open_location_settings" -> {
try { startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)) }
catch (e: Exception) { Log.e("BalDav", "open location settings: ${e.message}") }
}
cmd == "check_update" -> {
checkForUpdate(appDataDir)
}

View file

@ -228,6 +228,14 @@ fn read_points_file(app: tauri::AppHandle, filename: String) -> Result<String, S
}
}
// Read a small app state file (allowlisted) written by Kotlin, e.g. the location on/off state.
#[tauri::command]
fn read_state_file(app: tauri::AppHandle, name: String) -> Result<String, String> {
if name != "location_state.json" { return Err("bad name".to_string()); }
let p = native_root(&app).join(&name);
if p.exists() { std::fs::read_to_string(&p).map_err(|e| e.to_string()) } else { Ok(String::new()) }
}
// Download binary file from URL to local path (for tile DB import from router)
// read_to_vec() has a 10MB limit, so use as_reader() for unlimited binary reads
#[tauri::command]
@ -1154,7 +1162,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, ble::ble_request_enable])
.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, read_state_file])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}