diff --git a/app/src/main/java/net/duhowpi/ftmsbridge/AppSettings.kt b/app/src/main/java/net/duhowpi/ftmsbridge/AppSettings.kt new file mode 100644 index 0000000..6414e07 --- /dev/null +++ b/app/src/main/java/net/duhowpi/ftmsbridge/AppSettings.kt @@ -0,0 +1,19 @@ +package net.duhowpi.ftmsbridge + +import android.content.Context +import android.content.SharedPreferences + +class AppSettings(context: Context) { + private val prefs: SharedPreferences = + context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + + var autoconnectMinRssi: Int + get() = prefs.getInt(KEY_AUTOCONNECT_MIN_RSSI, DEFAULT_AUTOCONNECT_MIN_RSSI) + set(value) { prefs.edit().putInt(KEY_AUTOCONNECT_MIN_RSSI, value).apply() } + + companion object { + private const val PREFS_NAME = "app_settings" + private const val KEY_AUTOCONNECT_MIN_RSSI = "autoconnect_min_rssi" + const val DEFAULT_AUTOCONNECT_MIN_RSSI = -40 + } +} diff --git a/app/src/main/java/net/duhowpi/ftmsbridge/MainActivity.kt b/app/src/main/java/net/duhowpi/ftmsbridge/MainActivity.kt index 2b30fdb..2237836 100644 --- a/app/src/main/java/net/duhowpi/ftmsbridge/MainActivity.kt +++ b/app/src/main/java/net/duhowpi/ftmsbridge/MainActivity.kt @@ -17,6 +17,7 @@ import android.view.Menu import android.view.MenuItem import android.view.View import android.widget.Button +import android.widget.EditText import android.widget.SeekBar import android.widget.ScrollView import android.widget.TextView @@ -65,6 +66,7 @@ class MainActivity : AppCompatActivity() { private lateinit var hrDebugLogger: BtDebugLogger private lateinit var db: AppDatabase private lateinit var scanAdapter: ScanResultAdapter + private lateinit var appSettings: AppSettings private var ftmsConnectionManager: BleConnectionManager? = null private var hrConnectionManager: BleConnectionManager? = null @@ -228,6 +230,7 @@ class MainActivity : AppCompatActivity() { hrDebugLogger = BtDebugLogger(BuildConfig.DEBUG, this) bleScanner = BleScanner(this) stateMachine = SessionStateMachine(binding, this) + appSettings = AppSettings(this) createDebugSampleDataIfNeeded() @@ -249,6 +252,7 @@ class MainActivity : AppCompatActivity() { override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.action_history -> { startActivity(Intent(this, WorkoutHistoryActivity::class.java)); true } + R.id.action_settings -> { showSettingsDialog(); true } R.id.action_debug -> { showDebugDialog(); true } R.id.action_about -> { showAboutDialog(); true } else -> super.onOptionsItemSelected(item) @@ -263,6 +267,31 @@ class MainActivity : AppCompatActivity() { .show() } + private fun showSettingsDialog() { + val input = EditText(this).apply { + inputType = android.text.InputType.TYPE_CLASS_NUMBER or + android.text.InputType.TYPE_NUMBER_FLAG_SIGNED + setText(appSettings.autoconnectMinRssi.toString()) + hint = AppSettings.DEFAULT_AUTOCONNECT_MIN_RSSI.toString() + } + AlertDialog.Builder(this) + .setTitle(getString(R.string.settings)) + .setMessage(getString(R.string.settings_autoconnect_min_rssi)) + .setView(input) + .setPositiveButton(android.R.string.ok) { _, _ -> + val text = input.text.toString() + val value = text.toIntOrNull() + if (value == null || value >= 0) { + Toast.makeText(this, getString(R.string.settings_invalid_rssi), Toast.LENGTH_LONG).show() + } else { + appSettings.autoconnectMinRssi = value + } + } + .setNegativeButton(android.R.string.cancel, null) + .show() + } + + private fun setupScanList() { scanAdapter = ScanResultAdapter( onConnect = { info -> onDeviceConnectTapped(info) }, @@ -549,6 +578,22 @@ class MainActivity : AppCompatActivity() { ) debugLogger.logMessage("Discovered: $name (${device.address}) FTMS=$isFtms HR=$isHr RSSI=${result.rssi}") } + + // Auto-connect: if this is an FTMS device with strong enough signal and + // no FTMS device is already connected or connecting. + if (isFtms && result.rssi >= appSettings.autoconnectMinRssi) { + runOnUiThread { + if (ftmsConnectionManager?.isConnected != true + && stateMachine.state is SessionState.Idle + && dummyTreadmill == null && dummyBike == null + ) { + val info = scanResultsMap[device.address] ?: return@runOnUiThread + knownDevicesMap[device.address] = info + debugLogger.logMessage("Auto-connecting to $name (${device.address}) RSSI=${result.rssi}") + connectFtmsDevice(device) + } + } + } } override fun onScanFailed(errorCode: Int) { diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index e321928..0eea74a 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -8,6 +8,11 @@ android:title="@string/history" app:showAsAction="always" /> + + Enregistrament d\'entrenament Enregistrament d\'entrenament en curs + + + Ajustos + RSSI mín. de connexió automàtica (dBm) + Valor de RSSI no vàlid. Introdueix un nombre negatiu (p. ex. -40). diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 072a80c..f3da9d3 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -141,4 +141,9 @@ Grabación de entrenamiento Grabación de entrenamiento en curso + + + Ajustes + RSSI mín. de conexión automática (dBm) + Valor de RSSI no válido. Introduce un número negativo (p. ej. -40). diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a578e5a..6cffabe 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -110,6 +110,11 @@ Recent BT Events Log Files + + Settings + Auto-connect min. RSSI (dBm) + Invalid RSSI value. Enter a negative number (e.g. -40). + About About FTMS Bridge diff --git a/fastlane/metadata/android/en-US/changelogs/5.txt b/fastlane/metadata/android/en-US/changelogs/5.txt index fd41c9f..f96ef0f 100644 --- a/fastlane/metadata/android/en-US/changelogs/5.txt +++ b/fastlane/metadata/android/en-US/changelogs/5.txt @@ -1 +1,3 @@ - Fixed BLE disconnection when the app is in the background during long workouts +- Added auto-connect to FTMS devices: the app automatically connects to the nearest FTMS machine when its signal strength meets the configured minimum RSSI threshold. +- Added Settings option in the menu to configure the auto-connect minimum RSSI (default: -40 dBm).