mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-04 06:04:19 -04:00
@@ -298,13 +298,13 @@ class MainActivity : AppCompatActivity(), Logging,
|
||||
fun requestScanPermission() = requestPermission(getScanPermissions(), true)
|
||||
|
||||
/** Ask the user to grant camera permission */
|
||||
fun requestCameraPermission() = requestPermission(getCameraPermissions(), false)
|
||||
fun requestCameraPermission() = requestPermission(getCameraPermissions())
|
||||
|
||||
/** Ask the user to grant foreground location permission */
|
||||
fun requestLocationPermission() = requestPermission(getLocationPermissions(), false)
|
||||
fun requestLocationPermission() = requestPermission(getLocationPermissions())
|
||||
|
||||
/** Ask the user to grant background location permission */
|
||||
fun requestBackgroundPermission() = requestPermission(getBackgroundPermissions(), false)
|
||||
fun requestBackgroundPermission() = requestPermission(getBackgroundPermissions())
|
||||
|
||||
/**
|
||||
* @return a localized string warning user about missing permissions. Or null if everything is find
|
||||
@@ -344,7 +344,7 @@ class MainActivity : AppCompatActivity(), Logging,
|
||||
*/
|
||||
private fun requestPermission(
|
||||
missingPerms: List<String> = getMinimumPermissions(),
|
||||
shouldShowDialog: Boolean = true
|
||||
shouldShowDialog: Boolean = false
|
||||
): Boolean =
|
||||
if (missingPerms.isNotEmpty()) {
|
||||
val shouldShow = missingPerms.filter {
|
||||
|
||||
@@ -135,7 +135,7 @@ class MeshService : Service(), Logging {
|
||||
}
|
||||
|
||||
private val locationCallback = MeshServiceLocationCallback(
|
||||
::perhapsSendPosition,
|
||||
::sendPositionScoped,
|
||||
onSendPositionFailed = { onConnectionChanged(ConnectionState.DEVICE_SLEEP) },
|
||||
getNodeNum = { myNodeNum }
|
||||
)
|
||||
@@ -170,7 +170,7 @@ class MeshService : Service(), Logging {
|
||||
* We first check to see if our local device has already sent a position and if so, we punt until the next check.
|
||||
* This allows us to only 'fill in' with GPS positions when the local device happens to have no good GPS sats.
|
||||
*/
|
||||
private fun perhapsSendPosition(
|
||||
private fun sendPositionScoped(
|
||||
lat: Double = 0.0,
|
||||
lon: Double = 0.0,
|
||||
alt: Int = 0,
|
||||
@@ -181,17 +181,7 @@ class MeshService : Service(), Logging {
|
||||
// do most of the work in my service thread
|
||||
serviceScope.handledLaunch {
|
||||
// if android called us too soon, just ignore
|
||||
|
||||
val myInfo = localNodeInfo
|
||||
val lastLat = (myInfo?.position?.latitude ?: 0.0)
|
||||
val lastLon = (myInfo?.position?.longitude ?: 0.0)
|
||||
val lastSendMsec = (myInfo?.position?.time ?: 0) * 1000L
|
||||
val now = System.currentTimeMillis()
|
||||
if ((lastLat == 0.0 && lastLon == 0.0) || (now - lastSendMsec > locationIntervalMsec)) // && minBroadcastPeriod ?
|
||||
sendPosition(lat, lon, alt, destNum, wantResponse)
|
||||
else {
|
||||
debug("Not sending position - local node sent ${(now - lastSendMsec) / 1000L}s ago ${myInfo?.position?.toPIIString()}")
|
||||
}
|
||||
sendPosition(lat, lon, alt, destNum, wantResponse)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1028,10 +1018,10 @@ class MeshService : Service(), Logging {
|
||||
else
|
||||
broadcastSecs * 1000L
|
||||
|
||||
// if (prefs.locationShare == RadioConfigProtos.LocationSharing.LocDisabled) {
|
||||
// info("GPS location sharing is disabled")
|
||||
// desiredInterval = 0
|
||||
// }
|
||||
if (prefs.locationShare == RadioConfigProtos.LocationSharing.LocDisabled) {
|
||||
info("GPS location sharing is disabled")
|
||||
desiredInterval = 0
|
||||
}
|
||||
|
||||
// if (prefs.fixedPosition) {
|
||||
// info("Node has fixed position, therefore not overriding position")
|
||||
@@ -1043,6 +1033,7 @@ class MeshService : Service(), Logging {
|
||||
startLocationRequests(desiredInterval)
|
||||
} else {
|
||||
info("No GPS assistance desired, but sending UTC time to mesh")
|
||||
warnUserAboutLocation()
|
||||
sendPosition()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,9 @@ class MeshServiceLocationCallback(
|
||||
if (location.isAccurateForMesh) { // if within 200 meters, or accuracy is unknown
|
||||
|
||||
try {
|
||||
// Do we want to broadcast this position globally, or are we just telling the local node what its current position is (
|
||||
// Do we want to broadcast this position globally, or are we just telling the local node what its current position is
|
||||
val shouldBroadcast =
|
||||
true // no need to rate limit, because we are just sending at the interval requested by the preferences
|
||||
false // no need to rate limit, because we are just sending to the local node
|
||||
val destinationNumber =
|
||||
if (shouldBroadcast) DataPacket.NODENUM_BROADCAST else getNodeNum()
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class AdvancedSettingsFragment : ScreenFragment("Advanced Settings"), Logging {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
): View {
|
||||
_binding = AdvancedSettingsBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
@@ -39,6 +39,7 @@ class AdvancedSettingsFragment : ScreenFragment("Advanced Settings"), Logging {
|
||||
model.radioConfig.observe(viewLifecycleOwner, {
|
||||
binding.positionBroadcastPeriodEditText.setText(model.positionBroadcastSecs.toString())
|
||||
binding.lsSleepEditText.setText(model.lsSleepSecs.toString())
|
||||
binding.positionBroadcastPeriodView.isEnabled = model.locationShare ?: true
|
||||
binding.positionBroadcastSwitch.isChecked = model.locationShare ?: true
|
||||
binding.lsSleepView.isEnabled = model.isPowerSaving ?: false
|
||||
binding.lsSleepSwitch.isChecked = model.isPowerSaving ?: false
|
||||
@@ -47,7 +48,7 @@ class AdvancedSettingsFragment : ScreenFragment("Advanced Settings"), Logging {
|
||||
|
||||
model.isConnected.observe(viewLifecycleOwner, { connectionState ->
|
||||
val connected = connectionState == MeshService.ConnectionState.CONNECTED
|
||||
binding.positionBroadcastPeriodView.isEnabled = connected
|
||||
binding.positionBroadcastPeriodView.isEnabled = connected && model.locationShare ?: true
|
||||
binding.lsSleepView.isEnabled = connected && model.isPowerSaving ?: false
|
||||
binding.positionBroadcastSwitch.isEnabled = connected
|
||||
binding.lsSleepSwitch.isEnabled = connected
|
||||
|
||||
@@ -615,22 +615,29 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
||||
regionAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
spinner.adapter = regionAdapter
|
||||
|
||||
model.bluetoothEnabled.observe(
|
||||
viewLifecycleOwner, {
|
||||
if (it) binding.changeRadioButton.show()
|
||||
else binding.changeRadioButton.hide()
|
||||
})
|
||||
model.bluetoothEnabled.observe(viewLifecycleOwner, {
|
||||
if (it) binding.changeRadioButton.show()
|
||||
else binding.changeRadioButton.hide()
|
||||
})
|
||||
|
||||
model.ownerName.observe(viewLifecycleOwner, { name ->
|
||||
binding.usernameEditText.setText(name)
|
||||
})
|
||||
|
||||
// Only let user edit their name or set software update while connected to a radio
|
||||
model.isConnected.observe(
|
||||
viewLifecycleOwner, {
|
||||
updateNodeInfo()
|
||||
updateDevicesButtons(scanModel.devices.value)
|
||||
})
|
||||
model.isConnected.observe(viewLifecycleOwner, {
|
||||
updateNodeInfo()
|
||||
updateDevicesButtons(scanModel.devices.value)
|
||||
})
|
||||
|
||||
model.radioConfig.observe(viewLifecycleOwner, {
|
||||
binding.provideLocationCheckbox.isEnabled =
|
||||
isGooglePlayAvailable(requireContext()) && model.locationShare ?: true
|
||||
if (model.locationShare == false) {
|
||||
model.provideLocation.value = false
|
||||
binding.provideLocationCheckbox.isChecked = false
|
||||
}
|
||||
})
|
||||
|
||||
// Also watch myNodeInfo because it might change later
|
||||
model.myNodeInfo.observe(viewLifecycleOwner, {
|
||||
@@ -659,7 +666,6 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
||||
requireActivity().hideKeyboard()
|
||||
}
|
||||
|
||||
binding.provideLocationCheckbox.isEnabled = isGooglePlayAvailable(requireContext())
|
||||
binding.provideLocationCheckbox.setOnCheckedChangeListener { view, isChecked ->
|
||||
if (view.isPressed && isChecked) { // We want to ignore changes caused by code (as opposed to the user)
|
||||
// Don't check the box until the system setting changes
|
||||
@@ -896,7 +902,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
|
||||
debug("We have location access")
|
||||
}
|
||||
|
||||
locationSettingsResponse.addOnFailureListener { _ ->
|
||||
locationSettingsResponse.addOnFailureListener {
|
||||
errormsg("Failed to get location access")
|
||||
// We always show the toast regardless of what type of exception we receive. Because even non
|
||||
// resolvable api exceptions mean user still needs to fix something.
|
||||
|
||||
Reference in New Issue
Block a user