kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
commit
60b2fe6768
1
TODO.md
1
TODO.md
|
@ -1,7 +1,6 @@
|
|||
# Remaining tasks before declaring 1.0
|
||||
|
||||
* add a low level settings screen (let user change any of the RadioConfig parameters)
|
||||
* if user edits the channel, generate a new AES256 key
|
||||
* add play store link with https://developers.google.com/analytics/devguides/collection/android/v4/campaigns#google-play-url-builder and the play icon
|
||||
|
||||
Things for the betaish period.
|
||||
|
|
|
@ -17,8 +17,8 @@ android {
|
|||
applicationId "com.geeksville.mesh"
|
||||
minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works)
|
||||
targetSdkVersion 29
|
||||
versionCode 176
|
||||
versionName "0.7.6"
|
||||
versionCode 10771 // format is Mmmss (where M is 1+the numeric major number
|
||||
versionName "0.7.71"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
|
|
|
@ -14,10 +14,12 @@ data class Channel(
|
|||
val settings: MeshProtos.ChannelSettings = MeshProtos.ChannelSettings.getDefaultInstance()
|
||||
) {
|
||||
companion object {
|
||||
// Note: this string _SHOULD NOT BE LOCALIZED_ because it directly hashes to values used on the device for the default channel name.
|
||||
val defaultChannelName = "Default"
|
||||
|
||||
// Placeholder when emulating
|
||||
val emulated = Channel(
|
||||
// Note: this string _SHOULD NOT BE LOCALIZED_ because it directly hashes to values used on the device for the default channel name.
|
||||
MeshProtos.ChannelSettings.newBuilder().setName("Default")
|
||||
MeshProtos.ChannelSettings.newBuilder().setName(defaultChannelName)
|
||||
.setModemConfig(MeshProtos.ChannelSettings.ModemConfig.Bw125Cr45Sf128).build()
|
||||
)
|
||||
|
||||
|
|
|
@ -620,6 +620,7 @@ class MeshService : Service(), Logging {
|
|||
private var radioConfig: MeshProtos.RadioConfig? = null
|
||||
|
||||
/// True after we've done our initial node db init
|
||||
@Volatile
|
||||
private var haveNodeDB = false
|
||||
|
||||
// The database of active nodes, index is the node number
|
||||
|
@ -933,6 +934,7 @@ class MeshService : Service(), Logging {
|
|||
// decided to pass through to us (except for broadcast packets)
|
||||
//val toNum = packet.to
|
||||
|
||||
debug("Recieved: $packet")
|
||||
val p = packet.decoded
|
||||
|
||||
// If the rxTime was not set by the device (because device software was old), guess at a time
|
||||
|
@ -1154,12 +1156,10 @@ class MeshService : Service(), Logging {
|
|||
}
|
||||
|
||||
RadioInterfaceService.RECEIVE_FROMRADIO_ACTION -> {
|
||||
val bytes = intent.getByteArrayExtra(EXTRA_PAYLOAD)!!
|
||||
try {
|
||||
val proto =
|
||||
MeshProtos.FromRadio.parseFrom(
|
||||
intent.getByteArrayExtra(
|
||||
EXTRA_PAYLOAD
|
||||
)!!
|
||||
)
|
||||
MeshProtos.FromRadio.parseFrom(bytes)
|
||||
info("Received from radio service: ${proto.toOneLineString()}")
|
||||
when (proto.variantCase.number) {
|
||||
MeshProtos.FromRadio.PACKET_FIELD_NUMBER -> handleReceivedMeshPacket(
|
||||
|
@ -1178,6 +1178,9 @@ class MeshService : Service(), Logging {
|
|||
|
||||
else -> errormsg("Unexpected FromRadio variant")
|
||||
}
|
||||
} catch (ex: InvalidProtocolBufferException) {
|
||||
Exceptions.report(ex, "Invalid Protobuf from radio, len=${bytes.size}")
|
||||
}
|
||||
}
|
||||
|
||||
else -> errormsg("Unexpected radio interface broadcast")
|
||||
|
|
|
@ -18,12 +18,15 @@ import com.geeksville.android.GeeksvilleApplication
|
|||
import com.geeksville.android.Logging
|
||||
import com.geeksville.android.hideKeyboard
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.model.Channel
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.geeksville.mesh.service.MeshService
|
||||
import com.geeksville.util.Exceptions
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.protobuf.ByteString
|
||||
import kotlinx.android.synthetic.main.channel_fragment.*
|
||||
import java.security.SecureRandom
|
||||
|
||||
|
||||
// Make an image view dim
|
||||
|
@ -142,7 +145,15 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
|
|||
UIViewModel.getChannel(model.radioConfig.value)?.let { old ->
|
||||
val newSettings = old.settings.toBuilder()
|
||||
newSettings.name = channelNameEdit.text.toString().trim()
|
||||
// FIXME, regenerate a new preshared key!
|
||||
|
||||
// Generate a new AES256 key (for any channel not named Default)
|
||||
if (newSettings.name != Channel.defaultChannelName) {
|
||||
debug("ASSIGNING NEW AES256 KEY")
|
||||
val random = SecureRandom()
|
||||
val bytes = ByteArray(32)
|
||||
random.nextBytes(bytes)
|
||||
newSettings.psk = ByteString.copyFrom(bytes)
|
||||
}
|
||||
|
||||
// Try to change the radio, if it fails, tell the user why and throw away their redits
|
||||
try {
|
||||
|
|
|
@ -6,7 +6,6 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import com.geeksville.android.GeeksvilleApplication
|
||||
import com.geeksville.android.Logging
|
||||
import com.geeksville.mesh.NodeInfo
|
||||
|
@ -131,7 +130,7 @@ class MapFragment : ScreenFragment("Map"), Logging {
|
|||
}
|
||||
|
||||
var mapView: MapView? = null
|
||||
|
||||
var mapboxMap: MapboxMap? = null
|
||||
|
||||
override fun onViewCreated(viewIn: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(viewIn, savedInstanceState)
|
||||
|
@ -146,6 +145,7 @@ class MapFragment : ScreenFragment("Map"), Logging {
|
|||
// Each time the pane is shown start fetching new map info (we do this here instead of
|
||||
// onCreate because getMapAsync can die in native code if the view goes away)
|
||||
v.getMapAsync { map ->
|
||||
mapboxMap = map
|
||||
|
||||
if (view != null) { // it might have gone away by now
|
||||
// val markerIcon = BitmapFactory.decodeResource(context.resources, R.drawable.ic_twotone_person_pin_24)
|
||||
|
@ -159,11 +159,6 @@ class MapFragment : ScreenFragment("Map"), Logging {
|
|||
style.addLayer(labelLayer)
|
||||
}
|
||||
|
||||
model.nodeDB.nodes.observe(viewLifecycleOwner, Observer { nodes ->
|
||||
if (view != null)
|
||||
onNodesChanged(map, nodes.values)
|
||||
})
|
||||
|
||||
//map.uiSettings.isScrollGesturesEnabled = true
|
||||
//map.uiSettings.isZoomGesturesEnabled = true
|
||||
}
|
||||
|
@ -190,6 +185,16 @@ class MapFragment : ScreenFragment("Map"), Logging {
|
|||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapView?.onResume()
|
||||
|
||||
// FIXME: for now we just set the node positions when the user pages to the map - because
|
||||
// otherwise we try to update in the background which breaks mapbox native code (when view is not shown
|
||||
mapboxMap?.let { map ->
|
||||
// model.nodeDB.nodes.observe(viewLifecycleOwner, Observer { nodes ->
|
||||
model.nodeDB.nodes.value?.values?.let {
|
||||
onNodesChanged(map, it)
|
||||
}
|
||||
//})
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
|
|
@ -574,7 +574,8 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
|||
b.text = device.name
|
||||
b.id = View.generateViewId()
|
||||
b.isEnabled = enabled
|
||||
b.isChecked = device.address == scanModel.selectedNotNull
|
||||
b.isChecked =
|
||||
device.address == scanModel.selectedNotNull && device.bonded // Only show checkbox if device is still paired
|
||||
deviceRadioGroup.addView(b)
|
||||
|
||||
// Once we have at least one device, don't show the "looking for" animation - it makes uers think
|
||||
|
|
Ładowanie…
Reference in New Issue