diff --git a/README.md b/README.md
index e7355a6ed..bb4040be5 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ The app is also distributed for Amazon Fire devices via the Amazon appstore: [![
If you would like to develop this application we'd love your help! These build instructions are brief
and should be improved, please send a PR if you can.
-* Use Android Studio 4.0 RC 1 to build/debug (other versions might work but no promises)
+* Use Android Studio 4.1.2 to build/debug (other versions might work but no promises)
* Use "git submodule update --init --recursive" to pull in the various submodules we depend on
* There are a few config files which you'll need to copy from templates included in the project.
Run the following commands to do so:
diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt
index 136169f67..4791427b4 100644
--- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt
+++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt
@@ -20,9 +20,7 @@ import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.RemoteException
-import android.text.SpannableString
import android.text.method.LinkMovementMethod
-import android.text.util.Linkify
import android.view.Menu
import android.view.MenuItem
import android.view.MotionEvent
@@ -44,7 +42,6 @@ import com.geeksville.android.Logging
import com.geeksville.android.ServiceClient
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
@@ -307,11 +304,7 @@ class MainActivity : AppCompatActivity(), Logging,
if (deniedPermissions.isNotEmpty()) {
errormsg("Denied permissions: ${deniedPermissions.joinToString(",")}")
- Toast.makeText(
- this,
- getString(R.string.permission_missing),
- Toast.LENGTH_LONG
- ).show()
+ showToast(R.string.permission_missing)
}
}
@@ -659,7 +652,7 @@ class MainActivity : AppCompatActivity(), Logging,
val curVer = DeviceVersion(info.firmwareVersion ?: "0.0.0")
val minVer = DeviceVersion("1.2.0")
- if(curVer < minVer)
+ if (curVer < minVer)
showAlert(R.string.firmware_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
@@ -687,40 +680,52 @@ class MainActivity : AppCompatActivity(), Logging,
}
}
+ private fun showToast(msgId: Int) {
+ Toast.makeText(
+ this,
+ msgId,
+ Toast.LENGTH_LONG
+ ).show()
+ }
+
+ private fun showToast(msg: String) {
+ Toast.makeText(
+ this,
+ msg,
+ Toast.LENGTH_LONG
+ ).show()
+ }
+
private fun perhapsChangeChannel() {
// If the is opening a channel URL, handle it now
requestedChannelUrl?.let { url ->
try {
val channels = ChannelSet(url)
val primary = channels.primaryChannel
- requestedChannelUrl = null
+ if (primary == null)
+ showToast(R.string.channel_invalid)
+ else {
+ requestedChannelUrl = null
- MaterialAlertDialogBuilder(this)
- .setTitle(R.string.new_channel_rcvd)
- .setMessage(getString(R.string.do_you_want_switch).format(primary.name))
- .setNeutralButton(R.string.cancel) { _, _ ->
- // Do nothing
- }
- .setPositiveButton(R.string.accept) { _, _ ->
- debug("Setting channel from URL")
- try {
- model.setChannels(channels)
- } catch (ex: RemoteException) {
- errormsg("Couldn't change channel ${ex.message}")
- Toast.makeText(
- this,
- "Couldn't change channel, because radio is not yet connected. Please try again.",
- Toast.LENGTH_SHORT
- ).show()
+ MaterialAlertDialogBuilder(this)
+ .setTitle(R.string.new_channel_rcvd)
+ .setMessage(getString(R.string.do_you_want_switch).format(primary.name))
+ .setNeutralButton(R.string.cancel) { _, _ ->
+ // Do nothing
}
- }
- .show()
+ .setPositiveButton(R.string.accept) { _, _ ->
+ debug("Setting channel from URL")
+ try {
+ model.setChannels(channels)
+ } catch (ex: RemoteException) {
+ errormsg("Couldn't change channel ${ex.message}")
+ showToast(R.string.cant_change_no_radio)
+ }
+ }
+ .show()
+ }
} catch (ex: InvalidProtocolBufferException) {
- Toast.makeText(
- this,
- R.string.channel_invalid,
- Toast.LENGTH_LONG
- ).show()
+ showToast(R.string.channel_invalid)
}
}
}
@@ -869,8 +874,7 @@ class MainActivity : AppCompatActivity(), Logging,
errormsg("Device error during init ${ex.message}")
model.isConnected.value =
MeshService.ConnectionState.valueOf(service.connectionState())
- }
- finally {
+ } finally {
connectionJob = null
}
@@ -1037,7 +1041,7 @@ class MainActivity : AppCompatActivity(), Logging,
try {
val packageInfo: PackageInfo = packageManager.getPackageInfo(packageName, 0)
val versionName = packageInfo.versionName
- Toast.makeText(applicationContext, versionName, Toast.LENGTH_LONG).show()
+ showToast(versionName)
} catch (e: PackageManager.NameNotFoundException) {
errormsg("Can not find the version: ${e.message}")
}
diff --git a/app/src/main/java/com/geeksville/mesh/model/ChannelSet.kt b/app/src/main/java/com/geeksville/mesh/model/ChannelSet.kt
index d6b0bcf5e..59269184a 100644
--- a/app/src/main/java/com/geeksville/mesh/model/ChannelSet.kt
+++ b/app/src/main/java/com/geeksville/mesh/model/ChannelSet.kt
@@ -47,9 +47,11 @@ data class ChannelSet(
/**
* Return the primary channel info
*/
- val primaryChannel: Channel get() {
- return Channel(protobuf.getSettings(0))
- }
+ val primaryChannel: Channel? get() =
+ if(protobuf.settingsCount > 0)
+ Channel(protobuf.getSettings(0))
+ else
+ null
/// Return an URL that represents the current channel values
/// @param upperCasePrefix - portions of the URL can be upper case to make for more efficient QR codes
diff --git a/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt
index d4c5e8303..bc32450c5 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/ChannelFragment.kt
@@ -79,11 +79,10 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
/// Pull the latest data from the model (discarding any user edits)
private fun setGUIfromModel() {
val channels = model.channels.value
+ val channel = channels?.primaryChannel
binding.editableCheckbox.isChecked = false // start locked
- if (channels != null) {
- val channel = channels.primaryChannel
-
+ if (channel != null) {
binding.qrView.visibility = View.VISIBLE
binding.channelNameEdit.visibility = View.VISIBLE
binding.channelNameEdit.setText(channel.humanName)
@@ -156,8 +155,8 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
val checked = binding.editableCheckbox.isChecked
if (checked) {
// User just unlocked for editing - remove the # goo around the channel name
- model.channels.value?.let { channels ->
- binding.channelNameEdit.setText(channels.primaryChannel.name)
+ model.channels.value?.primaryChannel?.let { ch ->
+ binding.channelNameEdit.setText(ch.name)
}
} else {
// User just locked it, we should warn and then apply changes to radio
@@ -169,8 +168,7 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
}
.setPositiveButton(getString(R.string.accept)) { _, _ ->
// Generate a new channel with only the changes the user can change in the GUI
- model.channels.value?.let { old ->
- val oldPrimary = old.primaryChannel
+ model.channels.value?.primaryChannel?.let { oldPrimary ->
val newSettings = oldPrimary.settings.toBuilder()
newSettings.name = binding.channelNameEdit.text.toString().trim()
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b953889e2..c0f9644ea 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -94,4 +94,5 @@
Okay
You must set a region!
Region
+ Couldn\'t change channel, because radio is not yet connected. Please try again.