Merge pull request #255 from geeksville/dev

1.1.50
This commit is contained in:
Kevin Hester 2021-03-02 14:20:24 +08:00 committed by GitHub
commit 2614cba6a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 69 additions and 72 deletions

View file

@ -31,8 +31,8 @@ android {
applicationId "com.geeksville.mesh"
minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works)
targetSdkVersion 29
versionCode 20148 // format is Mmmss (where M is 1+the numeric major number
versionName "1.1.48"
versionCode 20150 // format is Mmmss (where M is 1+the numeric major number
versionName "1.1.50"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// per https://developer.android.com/studio/write/vector-asset-studio
@ -90,7 +90,7 @@ play {
// per protobuf-gradle-plugin docs, this is recommended for android
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.13.0'
artifact = 'com.google.protobuf:protoc:3.15.3'
}
generateProtoTasks {
all().each { task ->
@ -130,7 +130,7 @@ dependencies {
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"
testImplementation 'junit:junit:4.13.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
@ -145,7 +145,7 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
// For now I'm not using javalite, because I want JSON printing
implementation ('com.google.protobuf:protobuf-java:3.14.0')
implementation ('com.google.protobuf:protobuf-java:3.15.3')
// For UART access
// implementation 'com.google.android.things:androidthings:1.0'
@ -158,7 +158,7 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
// location services
implementation 'com.google.android.gms:play-services-location:17.1.0'
implementation 'com.google.android.gms:play-services-location:18.0.0'
// For Google Sign-In (owner name accesss)
implementation 'com.google.android.gms:play-services-auth:19.0.0'

View file

@ -20,10 +20,14 @@ 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
import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
@ -64,6 +68,7 @@ import java.nio.charset.Charset
import java.text.DateFormat
import java.util.*
/*
UI design
@ -619,26 +624,38 @@ class MainActivity : AppCompatActivity(), Logging,
debug("Getting latest radioconfig from service")
try {
model.radioConfig.value =
MeshProtos.RadioConfig.parseFrom(service.radioConfig)
val info = service.myNodeInfo
model.myNodeInfo.value = info
val isOld = info.minAppVersion > BuildConfig.VERSION_CODE
if (isOld)
MaterialAlertDialogBuilder(this)
if (isOld) {
// make links clickable per https://stackoverflow.com/a/62642807
val messageStr = getText(R.string.must_update)
val builder = MaterialAlertDialogBuilder(this)
.setTitle(getString(R.string.app_too_old))
.setMessage(getString(R.string.must_update))
.setMessage(messageStr)
.setPositiveButton("Okay") { _, _ ->
info("User acknowledged app is old")
}
.show()
updateNodesFromDevice()
val dialog = builder.show()
// we have a connection to our device now, do the channel change
perhapsChangeChannel()
// 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
model.radioConfig.value =
MeshProtos.RadioConfig.parseFrom(service.radioConfig)
updateNodesFromDevice()
// 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")
model.isConnected.value = oldConnection
@ -931,7 +948,8 @@ class MainActivity : AppCompatActivity(), Logging,
}
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
menu.findItem(R.id.stress_test).isVisible = BuildConfig.DEBUG // only show stress test for debug builds (for now)
menu.findItem(R.id.stress_test).isVisible =
BuildConfig.DEBUG // only show stress test for debug builds (for now)
return super.onPrepareOptionsMenu(menu)
}
@ -972,7 +990,7 @@ class MainActivity : AppCompatActivity(), Logging,
)
}
item.isChecked = !item.isChecked // toggle ping test
if(item.isChecked)
if (item.isChecked)
postPing()
else
handler.removeCallbacksAndMessages(null)

View file

@ -73,6 +73,9 @@ class MeshService : Service(), Logging {
class NodeNumNotFoundException(id: Int) : NodeNotFoundException("NodeNum not found $id")
class IdNotFoundException(id: String) : NodeNotFoundException("ID not found $id")
class NoRadioConfigException(message: String = "No radio settings received (is our app too old?)") :
RadioNotConnectedException(message)
/** We treat software update as similar to loss of comms to the regular bluetooth service (so things like sendPosition for background GPS ignores the problem */
class IsUpdatingException() :
RadioNotConnectedException("Operation prohibited during firmware update")
@ -569,7 +572,7 @@ class MeshService : Service(), Logging {
val hopLimit = packet.hopLimit
// If the rxTime was not set by the device (because device software was old), guess at a time
val rxTime = if (packet.rxTime == 0) packet.rxTime else currentSecond()
val rxTime = if (packet.rxTime != 0) packet.rxTime else currentSecond()
when {
fromId == null -> {
@ -638,11 +641,10 @@ class MeshService : Service(), Logging {
if (myInfo.myNodeNum == packet.from) {
// Handle position updates from the device
if (data.portnumValue == Portnums.PortNum.POSITION_APP_VALUE) {
val rxTime = if (packet.rxTime != 0) packet.rxTime else currentSecond()
handleReceivedPosition(
packet.from,
MeshProtos.Position.parseFrom(data.payload),
rxTime
dataPacket.time
)
} else
debug("Ignoring packet sent from our node, portnum=${data.portnumValue} ${bytes.size} bytes")
@ -660,9 +662,8 @@ class MeshService : Service(), Logging {
// Handle new style position info
Portnums.PortNum.POSITION_APP_VALUE -> {
val rxTime = if (packet.rxTime != 0) packet.rxTime else currentSecond()
val u = MeshProtos.Position.parseFrom(data.payload)
handleReceivedPosition(packet.from, u, rxTime)
handleReceivedPosition(packet.from, u, dataPacket.time)
}
// Handle new style user info
@ -702,15 +703,17 @@ class MeshService : Service(), Logging {
}
}
/// Update our DB of users based on someone sending out a Position subpacket
/** Update our DB of users based on someone sending out a Position subpacket
* @param defaultTime in msecs since 1970
*/
private fun handleReceivedPosition(
fromNum: Int,
p: MeshProtos.Position,
defaultTime: Int = Position.currentTime()
defaultTime: Long = System.currentTimeMillis()
) {
updateNodeInfo(fromNum) {
it.position = Position(p)
updateNodeInfoTime(it, defaultTime)
updateNodeInfoTime(it, (defaultTime / 1000).toInt())
}
}
@ -791,8 +794,6 @@ class MeshService : Service(), Logging {
packet.toString()
)
insertPacket(packetToSave)
// If the rxTime was not set by the device (because device software was old), guess at a time
val rxTime = if (packet.rxTime != 0) packet.rxTime else currentSecond()
// Update last seen for the node that sent the packet, but also for _our node_ because anytime a packet passes
// through our node on the way to the phone that means that local node is also alive in the mesh
@ -801,8 +802,11 @@ class MeshService : Service(), Logging {
it.position = it.position?.copy(time = currentSecond())
}
if (p.hasPosition())
handleReceivedPosition(fromNum, p.position, rxTime)
// If the rxTime was not set by the device (because device software was old), guess at a time
val rxTime = if (packet.rxTime != 0) packet.rxTime else currentSecond()
if (p.hasPosition()) {
handleReceivedPosition(fromNum, p.position, rxTime.toLong() * 1000)
}
else
updateNodeInfo(fromNum) {
// Update our last seen based on any valid timestamps. If the device didn't provide a timestamp make one
@ -1589,7 +1593,7 @@ class MeshService : Service(), Logging {
override fun getRadioConfig(): ByteArray = toRemoteExceptions {
this@MeshService.radioConfig?.toByteArray()
?: throw RadioNotConnectedException()
?: throw NoRadioConfigException()
}
override fun setRadioConfig(payload: ByteArray) = toRemoteExceptions {

View file

@ -26,6 +26,7 @@ open class RadioNotConnectedException(message: String = "Not connected to radio"
BLEException(message)
/**
* Handles the bluetooth link with a mesh radio device. Does not cache any device state,
* just does bluetooth comms etc...

@ -1 +1 @@
Subproject commit b1aed06442025624841b2288fac273d9bc41c438
Subproject commit 512d1aca0a066107de749c0c47397c7f9bf9cb99

View file

@ -1,20 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M17.5,8c0.46,0 0.91,-0.05 1.34,-0.12C17.44,5.56 14.9,4 12,4c-0.46,0 -0.91,0.05 -1.34,0.12C12.06,6.44 14.6,8 17.5,8zM8.08,5.03C6.37,6 5.05,7.58 4.42,9.47c1.71,-0.97 3.03,-2.55 3.66,-4.44z"
android:fillAlpha=".3"/>
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,4c2.9,0 5.44,1.56 6.84,3.88 -0.43,0.07 -0.88,0.12 -1.34,0.12 -2.9,0 -5.44,-1.56 -6.84,-3.88 0.43,-0.07 0.88,-0.12 1.34,-0.12zM8.08,5.03C7.45,6.92 6.13,8.5 4.42,9.47 5.05,7.58 6.37,6 8.08,5.03zM12,20c-4.41,0 -8,-3.59 -8,-8 0,-0.05 0.01,-0.1 0.01,-0.15 2.6,-0.98 4.68,-2.99 5.74,-5.55 1.83,2.26 4.62,3.7 7.75,3.7 0.75,0 1.47,-0.09 2.17,-0.24 0.21,0.71 0.33,1.46 0.33,2.24 0,4.41 -3.59,8 -8,8z"/>
<path
android:fillColor="@android:color/white"
android:pathData="M9,13m-1.25,0a1.25,1.25 0,1 1,2.5 0a1.25,1.25 0,1 1,-2.5 0"/>
<path
android:fillColor="@android:color/white"
android:pathData="M15,13m-1.25,0a1.25,1.25 0,1 1,2.5 0a1.25,1.25 0,1 1,-2.5 0"/>
</vector>

View file

@ -4,7 +4,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF">
>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/positionBroadcastPeriodView"

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>

View file

@ -10,7 +10,7 @@
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:clickable="true" android:focusable="true"
mapbox:mapbox_uiZoomGestures="true"
mapbox:mapbox_uiScrollGestures="true"></com.mapbox.mapboxsdk.maps.MapView>

View file

@ -15,11 +15,11 @@
android:id="@+id/stress_test"
android:checkable="true"
android:checked="false"
android:title="Protocol stress test" />
android:title="@string/protocol_stress_test" />
<item
android:id="@+id/advanced_settings"
app:showAsAction="withText"
android:title="Advanced settings" />
android:title="@string/advanced_settings" />
<item
android:id="@+id/about"
android:title="@string/about"

View file

@ -2,7 +2,6 @@
<resources>
<color name="colorPrimary">#3700B3</color>
<color name="colorPrimaryDark">#3700B3</color>
<color name="colorAccent">#D81B60</color>
<color name="colorMsg">#F2F2F2</color>
<color name="colorMyMsg">#EDEAF4</color>
</resources>

View file

@ -1,4 +1,3 @@
<resources>
<dimen name="fab_margin">16dp</dimen>
<dimen name="message_offset">64dp</dimen>
</resources>

View file

@ -1,4 +1,5 @@
<resources>
<string name="app_name" translatable="false">Meshtastic</string>
<string name="action_settings">Settings</string>
<string name="channel_name">Channel Name</string>
<string name="channel_options">Channel options</string>
@ -59,8 +60,8 @@
<string name="not_connected">Not connected, select radio below</string>
<string name="connected_sleeping">Connected to radio, but it is sleeping</string>
<string name="update_to">Update to %s</string>
<string name="app_too_old">Application too old</string>
<string name="must_update">You must update this application on the Google Play store (or Github). It is too old to talk to this radio.</string>
<string name="app_too_old">Application update required</string>
<string name="must_update">You must update this application on the Google Play store (or Github). It is too old to talk to this radio firmware. Please read our <a href="https://www.meshtastic.org/software/android-too-old.html">wiki</a> on this topic.</string>
<string name="none">None (disable)</string>
<string name="modem_config_short">Short range (but fast)</string>
<string name="modem_config_medium">Medium range (but fast)</string>
@ -86,4 +87,6 @@
<string name="ls_sleep_secs">Device sleep period (in seconds)</string>
<string name="meshtastic_messages_notifications">Notifications about messages</string>
<string name="broadcast_period_too_small">Minimum broadcast period for this channel is %d</string>
<string name="protocol_stress_test">Protocol stress test</string>
<string name="advanced_settings">Advanced settings</string>
</resources>

View file

@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.4.30'
ext.kotlin_version = '1.4.31'
ext.coroutines_version = "1.3.9"
repositories {
@ -20,11 +20,11 @@ buildscript {
// Add the Crashlytics Gradle plugin.
// Check that you have the Google Services Gradle plugin v4.3.2 or later
// (if not, add it).
classpath 'com.google.gms:google-services:4.3.4'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.4.1'
classpath 'com.google.gms:google-services:4.3.5'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.5.0'
// protobuf plugin - docs here https://github.com/google/protobuf-gradle-plugin
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.14'
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.15'
//classpath "app.brant:amazonappstorepublisher:0.1.0"
classpath 'com.github.triplet.gradle:play-publisher:2.8.0'

@ -1 +1 @@
Subproject commit cd0d0ab688af967af7e609f6f10fdf2dde1249bc
Subproject commit ff93b088b4652f099ab99c0359388f2d0541ddc9