diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index 2edcbb917..c3abeabe5 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -46,6 +46,7 @@ import com.geeksville.concurrent.handledLaunch import com.geeksville.mesh.databinding.ActivityMainBinding import com.geeksville.mesh.model.Channel import com.geeksville.mesh.model.ChannelSet +import com.geeksville.mesh.model.DeviceVersion import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.service.* import com.geeksville.mesh.ui.* @@ -613,6 +614,29 @@ class MainActivity : AppCompatActivity(), Logging, } } + /** Show an alert that may contain HTML */ + private fun showAlert(titleText: Int, messageText: Int) { + // make links clickable per https://stackoverflow.com/a/62642807 + // val messageStr = getText(messageText) + + val builder = MaterialAlertDialogBuilder(this) + .setTitle(titleText) + .setMessage(messageText) + .setPositiveButton("Okay") { _, _ -> + info("User acknowledged") + } + + val dialog = builder.show() + + // Make the textview clickable. Must be called after show() + val view = (dialog.findViewById(android.R.id.message) as TextView?)!! + // Linkify.addLinks(view, Linkify.ALL) // not needed with this method + view.movementMethod = LinkMovementMethod.getInstance() + + showSettingsPage() // Default to the settings page in this case + } + + /// Called when we gain/lose a connection to our mesh radio private fun onMeshConnectionChanged(connected: MeshService.ConnectionState) { debug("connchange ${model.isConnected.value} -> $connected") @@ -629,33 +653,25 @@ class MainActivity : AppCompatActivity(), Logging, model.myNodeInfo.value = info val isOld = info.minAppVersion > BuildConfig.VERSION_CODE - if (isOld) { - // make links clickable per https://stackoverflow.com/a/62642807 - val messageStr = getText(R.string.must_update) + if (isOld) + showAlert(R.string.app_too_old, R.string.must_update) + else { - val builder = MaterialAlertDialogBuilder(this) - .setTitle(getString(R.string.app_too_old)) - .setMessage(messageStr) - .setPositiveButton("Okay") { _, _ -> - info("User acknowledged app is old") - } + val curVer = DeviceVersion(info.firmwareVersion ?: "0.0.0") + val minVer = DeviceVersion("1.2.0") + if(curVer < minVer) + showAlert(R.string.app_too_old, R.string.firmware_old) + else { + // If our app is too old/new, we probably don't understand the new radioconfig messages, so we don't read them until here - val dialog = builder.show() + model.radioConfig.value = + RadioConfigProtos.RadioConfig.parseFrom(service.radioConfig) - // Make the textview clickable. Must be called after show() - val view = (dialog.findViewById(android.R.id.message) as TextView?)!! - // Linkify.addLinks(view, Linkify.ALL) // not needed with this method - view.movementMethod = LinkMovementMethod.getInstance() - } else { - // If our app is too old, we probably don't understand the new radioconfig messages + updateNodesFromDevice() - model.radioConfig.value = - RadioConfigProtos.RadioConfig.parseFrom(service.radioConfig) - - updateNodesFromDevice() - - // we have a connection to our device now, do the channel change - perhapsChangeChannel() + // we have a connection to our device now, do the channel change + perhapsChangeChannel() + } } } catch (ex: RemoteException) { warn("Abandoning connect $ex, because we probably just lost device connection") diff --git a/app/src/main/java/com/geeksville/mesh/service/DeviceVersion.kt b/app/src/main/java/com/geeksville/mesh/model/DeviceVersion.kt similarity index 96% rename from app/src/main/java/com/geeksville/mesh/service/DeviceVersion.kt rename to app/src/main/java/com/geeksville/mesh/model/DeviceVersion.kt index 13ef461e0..961524b66 100644 --- a/app/src/main/java/com/geeksville/mesh/service/DeviceVersion.kt +++ b/app/src/main/java/com/geeksville/mesh/model/DeviceVersion.kt @@ -1,4 +1,4 @@ -package com.geeksville.mesh.service +package com.geeksville.mesh.model import com.geeksville.android.Logging diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index 9b40d025c..15b21f8e6 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -23,6 +23,7 @@ import com.geeksville.mesh.MeshProtos.ToRadio import com.geeksville.mesh.database.MeshtasticDatabase import com.geeksville.mesh.database.PacketRepository import com.geeksville.mesh.database.entity.Packet +import com.geeksville.mesh.model.DeviceVersion import com.geeksville.mesh.service.SoftwareUpdateService.Companion.ProgressNotStarted import com.geeksville.util.* import com.google.android.gms.common.api.ApiException diff --git a/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt b/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt index d7b3cc2dd..b9050105e 100644 --- a/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/SoftwareUpdateService.kt @@ -9,6 +9,7 @@ import androidx.core.app.JobIntentService import com.geeksville.android.Logging import com.geeksville.mesh.MainActivity import com.geeksville.mesh.R +import com.geeksville.mesh.model.DeviceVersion import com.geeksville.util.exceptionReporter import java.util.* import java.util.zip.CRC32 diff --git a/app/src/main/java/com/geeksville/mesh/ui/MessagesFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/MessagesFragment.kt index 92c1d0d73..668f789d3 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/MessagesFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/MessagesFragment.kt @@ -237,17 +237,22 @@ class MessagesFragment : ScreenFragment("Messages"), Logging { }) // If connection state _OR_ myID changes we have to fix our ability to edit outgoing messages - model.isConnected.observe(viewLifecycleOwner, Observer { connected -> - // If we don't know our node ID and we are offline don't let user try to send + fun updateTextEnabled() { binding.textInputLayout.isEnabled = - connected != MeshService.ConnectionState.DISCONNECTED && model.nodeDB.myId.value != null - }) + model.isConnected.value != MeshService.ConnectionState.DISCONNECTED && model.nodeDB.myId.value != null && model.radioConfig.value != null + } - model.nodeDB.myId.observe(viewLifecycleOwner, Observer { myId -> + model.isConnected.observe(viewLifecycleOwner, Observer { _ -> // If we don't know our node ID and we are offline don't let user try to send - binding.textInputLayout.isEnabled = - model.isConnected.value != MeshService.ConnectionState.DISCONNECTED && myId != null - }) + updateTextEnabled() }) + + model.nodeDB.myId.observe(viewLifecycleOwner, Observer { _ -> + // If we don't know our node ID and we are offline don't let user try to send + updateTextEnabled() }) + + model.radioConfig.observe(viewLifecycleOwner, Observer { _ -> + // If we don't know our node ID and we are offline don't let user try to send + updateTextEnabled() }) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 33c6f745f..6a45820ed 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -89,4 +89,6 @@ Minimum broadcast period for this channel is %d Protocol stress test Advanced settings + Firmware update required + The radio firmware is too old to talk to this application, please go to the settings pane and choose "Update Firmware". For more information on this see our wiki.