kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
Merge branch 'meshtastic:master' into osmdroid-phase3
commit
cc1814b499
|
@ -43,8 +43,8 @@ android {
|
|||
applicationId "com.geeksville.mesh"
|
||||
minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works)
|
||||
targetSdkVersion 30
|
||||
versionCode 20343 // format is Mmmss (where M is 1+the numeric major number
|
||||
versionName "1.3.43"
|
||||
versionCode 20345 // format is Mmmss (where M is 1+the numeric major number
|
||||
versionName "1.3.45"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
// per https://developer.android.com/studio/write/vector-asset-studio
|
||||
|
|
|
@ -13,7 +13,6 @@ import android.text.method.LinkMovementMethod
|
|||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
|
@ -58,7 +57,7 @@ import kotlinx.coroutines.Job
|
|||
import kotlinx.coroutines.cancel
|
||||
import java.nio.charset.Charset
|
||||
import java.text.DateFormat
|
||||
import java.util.*
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
|
||||
/*
|
||||
|
@ -303,8 +302,7 @@ class MainActivity : BaseActivity(), Logging {
|
|||
}
|
||||
|
||||
private fun initToolbar() {
|
||||
val toolbar =
|
||||
findViewById<View>(R.id.toolbar) as Toolbar
|
||||
val toolbar = binding.toolbar as Toolbar
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.setDisplayShowTitleEnabled(false)
|
||||
}
|
||||
|
@ -497,11 +495,7 @@ class MainActivity : BaseActivity(), Logging {
|
|||
|
||||
private fun showSnackbar(msgId: Int) {
|
||||
try {
|
||||
Snackbar.make(
|
||||
findViewById(android.R.id.content),
|
||||
msgId,
|
||||
Snackbar.LENGTH_LONG
|
||||
).show()
|
||||
Snackbar.make(binding.root, msgId, Snackbar.LENGTH_LONG).show()
|
||||
} catch (ex: IllegalStateException) {
|
||||
errormsg("Snackbar couldn't find view for msgId $msgId")
|
||||
}
|
||||
|
@ -509,11 +503,7 @@ class MainActivity : BaseActivity(), Logging {
|
|||
|
||||
private fun showSnackbar(msg: String) {
|
||||
try {
|
||||
Snackbar.make(
|
||||
findViewById(android.R.id.content),
|
||||
msg,
|
||||
Snackbar.LENGTH_INDEFINITE
|
||||
)
|
||||
Snackbar.make(binding.root, msg, Snackbar.LENGTH_INDEFINITE)
|
||||
.apply { view.findViewById<TextView>(R.id.snackbar_text).isSingleLine = false }
|
||||
.setAction(R.string.okay) {
|
||||
// dismiss
|
||||
|
|
|
@ -29,7 +29,8 @@ data class Channel(
|
|||
// The default channel that devices ship with
|
||||
val default = Channel(
|
||||
channelSettings { psk = ByteString.copyFrom(defaultPSK) },
|
||||
loRaConfig { usePreset = true; modemPreset = ModemPreset.LONG_FAST }
|
||||
// reference: NodeDB::installDefaultConfig
|
||||
loRaConfig { txEnabled = true; modemPreset = ModemPreset.LONG_FAST; hopLimit = 3 }
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -44,8 +44,9 @@ import java.io.BufferedWriter
|
|||
import java.io.FileNotFoundException
|
||||
import java.io.FileWriter
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/// Given a human name, strip out the first letter of the first three words and return that as the initials for
|
||||
|
@ -312,17 +313,17 @@ class UIViewModel @Inject constructor(
|
|||
private var _channelSet: AppOnlyProtos.ChannelSet
|
||||
get() = channels.value.protobuf
|
||||
set(value) {
|
||||
val asChannels = value.settingsList.mapIndexed { i, c ->
|
||||
(0 until max(_channelSet.settingsCount, value.settingsCount)).map { i ->
|
||||
channel {
|
||||
role = if (i == 0) ChannelProtos.Channel.Role.PRIMARY
|
||||
else ChannelProtos.Channel.Role.SECONDARY
|
||||
role = when (i) {
|
||||
0 -> ChannelProtos.Channel.Role.PRIMARY
|
||||
in 1 until value.settingsCount -> ChannelProtos.Channel.Role.SECONDARY
|
||||
else -> ChannelProtos.Channel.Role.DISABLED
|
||||
}
|
||||
index = i
|
||||
settings = c
|
||||
settings = value.settingsList.getOrNull(i) ?: channelSettings { }
|
||||
}
|
||||
}
|
||||
|
||||
debug("Sending channels to device")
|
||||
asChannels.forEach {
|
||||
}.forEach {
|
||||
meshService?.setChannel(it.toByteArray())
|
||||
}
|
||||
|
||||
|
@ -383,7 +384,8 @@ class UIViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
val adminChannelIndex: Int get() = channelSet.settingsList.map { it.name }.indexOf("admin")
|
||||
val adminChannelIndex: Int
|
||||
get() = channelSet.settingsList.map { it.name.lowercase() }.indexOf("admin")
|
||||
|
||||
fun requestShutdown(idNum: Int) {
|
||||
try {
|
||||
|
|
|
@ -42,7 +42,7 @@ class ChannelSetRepository @Inject constructor(
|
|||
|
||||
suspend fun addSettings(channel: ChannelProtos.Channel) {
|
||||
channelSetStore.updateData { preference ->
|
||||
preference.toBuilder().addSettings(channel.index, channel.settings).build()
|
||||
preference.toBuilder().addSettings(channel.settings).build()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -712,28 +712,8 @@ class MeshService : Service(), Logging {
|
|||
val ch = a.getChannelResponse
|
||||
debug("Admin: Received channel ${ch.index}")
|
||||
|
||||
val packetToSave = MeshLog(
|
||||
UUID.randomUUID().toString(),
|
||||
"Channel",
|
||||
System.currentTimeMillis(),
|
||||
ch.toString()
|
||||
)
|
||||
insertMeshLog(packetToSave)
|
||||
|
||||
if (ch.index + 1 < mi.maxChannels) {
|
||||
|
||||
// Stop once we get to the first disabled entry
|
||||
if (/* ch.hasSettings() || */ ch.role != ChannelProtos.Channel.Role.DISABLED) {
|
||||
// Not done yet, add new entries and request next channel
|
||||
addChannelSettings(ch)
|
||||
requestChannel(ch.index + 1)
|
||||
} else {
|
||||
debug("We've received the last channel, allowing rest of app to start...")
|
||||
onHasSettings()
|
||||
}
|
||||
} else {
|
||||
debug("Received max channels, starting app")
|
||||
onHasSettings()
|
||||
handleChannel(ch)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -930,7 +910,7 @@ class MeshService : Service(), Logging {
|
|||
}
|
||||
|
||||
private fun addChannelSettings(ch: ChannelProtos.Channel) {
|
||||
if (ch.index == 0 || ch.settings.name == "admin") adminChannelIndex = ch.index
|
||||
if (ch.index == 0 || ch.settings.name.lowercase() == "admin") adminChannelIndex = ch.index
|
||||
serviceScope.handledLaunch {
|
||||
channelSetRepository.addSettings(ch)
|
||||
}
|
||||
|
@ -1110,6 +1090,7 @@ class MeshService : Service(), Logging {
|
|||
MeshProtos.FromRadio.CONFIG_COMPLETE_ID_FIELD_NUMBER -> handleConfigComplete(proto.configCompleteId)
|
||||
MeshProtos.FromRadio.MY_INFO_FIELD_NUMBER -> handleMyInfo(proto.myInfo)
|
||||
MeshProtos.FromRadio.NODE_INFO_FIELD_NUMBER -> handleNodeInfo(proto.nodeInfo)
|
||||
MeshProtos.FromRadio.CHANNEL_FIELD_NUMBER -> handleChannel(proto.channel)
|
||||
MeshProtos.FromRadio.CONFIG_FIELD_NUMBER -> handleDeviceConfig(proto.config)
|
||||
MeshProtos.FromRadio.MODULECONFIG_FIELD_NUMBER -> handleModuleConfig(proto.moduleConfig)
|
||||
else -> errormsg("Unexpected FromRadio variant")
|
||||
|
@ -1152,6 +1133,18 @@ class MeshService : Service(), Logging {
|
|||
// setModuleConfig(config)
|
||||
}
|
||||
|
||||
private fun handleChannel(ch: ChannelProtos.Channel) {
|
||||
debug("Received channel ${ch.index}")
|
||||
val packetToSave = MeshLog(
|
||||
UUID.randomUUID().toString(),
|
||||
"Channel",
|
||||
System.currentTimeMillis(),
|
||||
ch.toString()
|
||||
)
|
||||
insertMeshLog(packetToSave)
|
||||
if (ch.role != ChannelProtos.Channel.Role.DISABLED) addChannelSettings(ch)
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a protobuf NodeInfo into our model objects and update our node DB
|
||||
*/
|
||||
|
@ -1328,8 +1321,8 @@ class MeshService : Service(), Logging {
|
|||
if (deviceVersion < minDeviceVersion || appVersion < minAppVersion) {
|
||||
info("Device firmware or app is too old, faking config so firmware update can occur")
|
||||
clearLocalConfig()
|
||||
onHasSettings()
|
||||
} else requestChannel(0) // Now start reading channels
|
||||
}
|
||||
onHasSettings()
|
||||
}
|
||||
} else
|
||||
warn("Ignoring stale config complete")
|
||||
|
@ -1354,7 +1347,7 @@ class MeshService : Service(), Logging {
|
|||
}
|
||||
|
||||
private fun setChannel(ch: ChannelProtos.Channel) {
|
||||
if (ch.index == 0 || ch.settings.name == "admin") adminChannelIndex = ch.index
|
||||
if (ch.index == 0 || ch.settings.name.lowercase() == "admin") adminChannelIndex = ch.index
|
||||
sendToRadio(newMeshPacketTo(myNodeNum).buildAdminPacket(wantResponse = true) {
|
||||
setChannel = ch
|
||||
})
|
||||
|
|
|
@ -26,7 +26,6 @@ import com.geeksville.mesh.model.map.CustomTileSource
|
|||
import com.geeksville.mesh.model.map.NOAAWmsTileSource
|
||||
import com.geeksville.mesh.util.formatAgo
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.osmdroid.api.IMapController
|
||||
import org.osmdroid.config.Configuration
|
||||
|
@ -58,7 +57,6 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener {
|
|||
// UI Elements
|
||||
private lateinit var binding: MapViewBinding
|
||||
private lateinit var map: MapView
|
||||
private lateinit var downloadBtn: FloatingActionButton
|
||||
private lateinit var cacheEstimate: TextView
|
||||
private lateinit var executeJob: Button
|
||||
private var downloadPrompt: AlertDialog? = null
|
||||
|
@ -96,8 +94,6 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener {
|
|||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = MapViewBinding.inflate(inflater)
|
||||
downloadBtn = binding.root.findViewById(R.id.downloadButton)
|
||||
binding.cacheLayout.visibility = View.GONE
|
||||
return binding.root
|
||||
}
|
||||
|
||||
|
@ -138,7 +134,7 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener {
|
|||
}
|
||||
zoomToNodes(mapController)
|
||||
}
|
||||
downloadBtn.setOnClickListener(this)
|
||||
binding.downloadButton.setOnClickListener(this)
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
|
@ -389,9 +385,9 @@ class MapFragment : ScreenFragment("Map"), Logging, View.OnClickListener {
|
|||
|
||||
private fun renderDownloadButton() {
|
||||
if (!(map.tileProvider.tileSource as OnlineTileSourceBase).tileSourcePolicy.acceptsBulkDownload()) {
|
||||
downloadBtn.hide()
|
||||
binding.downloadButton.hide()
|
||||
} else {
|
||||
downloadBtn.show()
|
||||
binding.downloadButton.show()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -299,14 +299,15 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
model.localConfig.asLiveData().observe(viewLifecycleOwner) {
|
||||
if (!model.isConnected()) {
|
||||
val configCount = it.allFields.size
|
||||
binding.scanStatusText.text = "Device config ($configCount / 7)"
|
||||
if (configCount > 0)
|
||||
binding.scanStatusText.text = "Device config ($configCount / 7)"
|
||||
} else updateNodeInfo()
|
||||
}
|
||||
|
||||
model.channels.asLiveData().observe(viewLifecycleOwner) {
|
||||
if (!model.isConnected()) {
|
||||
val channelCount = it.protobuf.settingsCount
|
||||
if (channelCount > 0) binding.scanStatusText.text = "Channels ($channelCount / 8)"
|
||||
if (!model.isConnected()) it.protobuf.let { ch ->
|
||||
if (!ch.hasLoraConfig() && ch.settingsCount > 0)
|
||||
binding.scanStatusText.text = "Channels (${ch.settingsCount} / 8)"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d3dfaa63a5108c1da7571cd780efaf561b99cc74
|
||||
Subproject commit c85caacf3c92717ad5547927c784cbe527ee1d74
|
|
@ -28,6 +28,7 @@
|
|||
android:id="@+id/cache_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
|
Ładowanie…
Reference in New Issue