From bff0d29ee846da145e04216830282ce46dfeacb1 Mon Sep 17 00:00:00 2001 From: ua1zbe Date: Fri, 14 Aug 2026 09:34:26 +0300 Subject: [PATCH] Talk group switcher on main screen, auto-connect on launch - Tapping the TG badge opens a group list; picking a group saves it and reconnects to the server with the new group - Groups configured in settings (comma-separated), defaults 9,11,12,13 - Auto-connect at app launch to the default group from settings --- .../java/ru/ua1zbe/svxremote/MainActivity.kt | 101 +++++++++++++----- .../ru/ua1zbe/svxremote/SettingsActivity.kt | 10 +- .../java/ru/ua1zbe/svxremote/prefs/Prefs.kt | 11 +- app/src/main/res/layout/activity_settings.xml | 22 +++- app/src/main/res/values/strings.xml | 5 +- 5 files changed, 118 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/ru/ua1zbe/svxremote/MainActivity.kt b/app/src/main/java/ru/ua1zbe/svxremote/MainActivity.kt index 02f3125..e695c10 100644 --- a/app/src/main/java/ru/ua1zbe/svxremote/MainActivity.kt +++ b/app/src/main/java/ru/ua1zbe/svxremote/MainActivity.kt @@ -105,38 +105,18 @@ class MainActivity : Activity(), SvxService.Listener { startActivity(Intent(this, SettingsActivity::class.java)) } + lblTg.setOnClickListener { showGroupsDialog() } + connectZone.setOnClickListener { - val s = svc - if (connected && s != null) { - s.disconnect() + if (connected) { + svc?.disconnect() } else { - settings = Prefs.load(this) if (settings.host.isBlank() || settings.callsign.isBlank()) { toast(getString(R.string.toast_need_settings)) return@setOnClickListener } - if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { - requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), REQ_MIC) - return@setOnClickListener - } - if (Build.VERSION.SDK_INT >= 33 && - checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED - ) { - requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), REQ_NOTIF) - } - startForegroundService(Intent(this, SvxService::class.java)) - bindService(Intent(this, SvxService::class.java), svcConn, Context.BIND_AUTO_CREATE) - mainHandler.postDelayed({ - svc?.connect( - ReflectorClient.Settings( - host = settings.host, - port = settings.port, - callsign = settings.callsign, - authKey = settings.authKey, - talkGroup = settings.talkGroup - ) - ) - }, 300) + requestPermissionsIfNeeded() + connect() } } @@ -167,10 +147,23 @@ class MainActivity : Activity(), SvxService.Listener { refreshUi() } + private var autoConnectAttempted = false + override fun onResume() { super.onResume() settings = Prefs.load(this) refreshUi() + if (!autoConnectAttempted && + settings.host.isNotBlank() && + settings.callsign.isNotBlank() + ) { + autoConnectAttempted = true + requestPermissionsIfNeeded() + connect() + } + if (pendingUpdate != null && updateDialog == null && canInstall()) { + startUpdate() + } } override fun onDestroy() { @@ -311,6 +304,62 @@ class MainActivity : Activity(), SvxService.Listener { pttButton.enabled2 = connected } + private fun requestPermissionsIfNeeded() { + if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { + requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), REQ_MIC) + } + if (Build.VERSION.SDK_INT >= 33 && + checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED + ) { + requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), REQ_NOTIF) + } + } + + /** Запустить сервис и подключиться с текущими настройками. */ + private fun connect() { + startForegroundService(Intent(this, SvxService::class.java)) + bindService(Intent(this, SvxService::class.java), svcConn, Context.BIND_AUTO_CREATE) + mainHandler.postDelayed({ + svc?.connect( + ReflectorClient.Settings( + host = settings.host, + port = settings.port, + callsign = settings.callsign, + authKey = settings.authKey, + talkGroup = settings.talkGroup + ) + ) + }, 300) + } + + /** Переключиться на другую группу: пересохранить и переподключиться. */ + private fun switchGroup(tg: Long) { + settings = settings.copy(talkGroup = tg) + Prefs.save(this, settings) + refreshUi() + svc?.disconnect() + mainHandler.postDelayed({ connect() }, 500) + } + + private fun showGroupsDialog() { + val groups = (settings.groups + settings.talkGroup).distinct() + if (groups.isEmpty()) { + toast(getString(R.string.toast_groups_empty)) + return + } + val current = settings.talkGroup + AlertDialog.Builder(this) + .setTitle(R.string.select_tg) + .setItems(groups.map { tg -> + val label = getString(R.string.tg_badge, tg) + if (tg == current) "$label ✓" else label + }.toTypedArray()) { _, which -> + val tg = groups[which] + if (tg != current) switchGroup(tg) + } + .show() + } + private fun checkForUpdates() { Thread { val version = try { diff --git a/app/src/main/java/ru/ua1zbe/svxremote/SettingsActivity.kt b/app/src/main/java/ru/ua1zbe/svxremote/SettingsActivity.kt index 69d28f0..9d8d753 100644 --- a/app/src/main/java/ru/ua1zbe/svxremote/SettingsActivity.kt +++ b/app/src/main/java/ru/ua1zbe/svxremote/SettingsActivity.kt @@ -15,6 +15,7 @@ class SettingsActivity : Activity() { private lateinit var inputCallsign: EditText private lateinit var inputAuthKey: EditText private lateinit var inputTg: EditText + private lateinit var inputGroups: EditText override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -25,6 +26,7 @@ class SettingsActivity : Activity() { inputCallsign = findViewById(R.id.input_callsign) inputAuthKey = findViewById(R.id.input_auth_key) inputTg = findViewById(R.id.input_tg) + inputGroups = findViewById(R.id.input_groups) val s = Prefs.load(this) inputHost.setText(s.host) @@ -32,6 +34,7 @@ class SettingsActivity : Activity() { inputCallsign.setText(s.callsign) inputAuthKey.setText(s.authKey) inputTg.setText(s.talkGroup.toString()) + inputGroups.setText(s.groups.joinToString(", ")) findViewById