checkpoint

This commit is contained in:
voussoir 2023-03-09 21:34:02 -08:00
parent df77b089ac
commit 04fa76249b
7 changed files with 197 additions and 191 deletions

View file

@ -58,7 +58,7 @@ class MapFragment : Fragment()
// https://gist.github.com/Dvik/a3de88d39da9d1d6d175025a56c5e797#file-viewextension-kt and // https://gist.github.com/Dvik/a3de88d39da9d1d6d175025a56c5e797#file-viewextension-kt and
// https://proandroiddev.com/android-full-screen-ui-with-transparent-status-bar-ef52f3adde63 // https://proandroiddev.com/android-full-screen-ui-with-transparent-status-bar-ef52f3adde63
// get current best location // get current best location
currentBestLocation = LocationHelper.getLastKnownLocation(activity as Context) currentBestLocation = getLastKnownLocation(activity as Context)
// get saved tracking state // get saved tracking state
trackingState = PreferencesHelper.loadTrackingState() trackingState = PreferencesHelper.loadTrackingState()
requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

View file

@ -20,7 +20,9 @@ import YesNoDialog
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.preference.* import androidx.preference.*
@ -118,6 +120,10 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
preferenceDeviceID.summary = getString(R.string.pref_device_id_summary) + "\n" + PreferencesHelper.load_device_id() preferenceDeviceID.summary = getString(R.string.pref_device_id_summary) + "\n" + PreferencesHelper.load_device_id()
preferenceDeviceID.setDefaultValue(random_device_id()) preferenceDeviceID.setDefaultValue(random_device_id())
preferenceCategoryGeneral.contains(preferenceDeviceID) preferenceCategoryGeneral.contains(preferenceDeviceID)
preferenceDeviceID.setOnPreferenceChangeListener { preference, newValue ->
preferenceDeviceID.summary = getString(R.string.pref_device_id_summary) + "\n" + newValue
return@setOnPreferenceChangeListener true
}
screen.addPreference(preferenceDeviceID) screen.addPreference(preferenceDeviceID)
val preferenceCategoryAbout: PreferenceCategory = PreferenceCategory(context) val preferenceCategoryAbout: PreferenceCategory = PreferenceCategory(context)

View file

@ -57,7 +57,7 @@ class TrackerService: Service(), SensorEventListener
var device_id: String = random_device_id() var device_id: String = random_device_id()
var recording_started: Date = GregorianCalendar.getInstance().time var recording_started: Date = GregorianCalendar.getInstance().time
var commitInterval: Int = Keys.COMMIT_INTERVAL var commitInterval: Int = Keys.COMMIT_INTERVAL
var currentBestLocation: Location = LocationHelper.getDefaultLocation() var currentBestLocation: Location = getDefaultLocation()
var lastCommit: Date = Keys.DEFAULT_DATE var lastCommit: Date = Keys.DEFAULT_DATE
var stepCountOffset: Float = 0f var stepCountOffset: Float = 0f
lateinit var track: Track lateinit var track: Track
@ -74,7 +74,6 @@ class TrackerService: Service(), SensorEventListener
private lateinit var gpsLocationListener: LocationListener private lateinit var gpsLocationListener: LocationListener
private lateinit var networkLocationListener: LocationListener private lateinit var networkLocationListener: LocationListener
/* Adds a GPS location listener to location manager */
private fun addGpsLocationListener() private fun addGpsLocationListener()
{ {
if (gpsLocationListenerRegistered) if (gpsLocationListenerRegistered)
@ -83,7 +82,7 @@ class TrackerService: Service(), SensorEventListener
return return
} }
gpsProviderActive = LocationHelper.isGpsEnabled(locationManager) gpsProviderActive = isGpsEnabled(locationManager)
if (! gpsProviderActive) if (! gpsProviderActive)
{ {
LogHelper.w(TAG, "Device GPS is not enabled.") LogHelper.w(TAG, "Device GPS is not enabled.")
@ -107,7 +106,6 @@ class TrackerService: Service(), SensorEventListener
LogHelper.v(TAG, "Added GPS location listener.") LogHelper.v(TAG, "Added GPS location listener.")
} }
/* Adds a Network location listener to location manager */
private fun addNetworkLocationListener() private fun addNetworkLocationListener()
{ {
if (gpsOnly) if (gpsOnly)
@ -122,7 +120,7 @@ class TrackerService: Service(), SensorEventListener
return return
} }
networkProviderActive = LocationHelper.isNetworkEnabled(locationManager) networkProviderActive = isNetworkEnabled(locationManager)
if (!networkProviderActive) if (!networkProviderActive)
{ {
LogHelper.w(TAG, "Unable to add Network location listener.") LogHelper.w(TAG, "Unable to add Network location listener.")
@ -151,7 +149,7 @@ class TrackerService: Service(), SensorEventListener
return object : LocationListener { return object : LocationListener {
override fun onLocationChanged(location: Location) override fun onLocationChanged(location: Location)
{ {
if (LocationHelper.isBetterLocation(location, currentBestLocation)) { if (isBetterLocation(location, currentBestLocation)) {
currentBestLocation = location currentBestLocation = location
} }
} }
@ -159,16 +157,16 @@ class TrackerService: Service(), SensorEventListener
{ {
LogHelper.v(TAG, "onProviderEnabled $provider") LogHelper.v(TAG, "onProviderEnabled $provider")
when (provider) { when (provider) {
LocationManager.GPS_PROVIDER -> gpsProviderActive = LocationHelper.isGpsEnabled(locationManager) LocationManager.GPS_PROVIDER -> gpsProviderActive = isGpsEnabled(locationManager)
LocationManager.NETWORK_PROVIDER -> networkProviderActive = LocationHelper.isNetworkEnabled(locationManager) LocationManager.NETWORK_PROVIDER -> networkProviderActive = isNetworkEnabled(locationManager)
} }
} }
override fun onProviderDisabled(provider: String) override fun onProviderDisabled(provider: String)
{ {
LogHelper.v(TAG, "onProviderDisabled $provider") LogHelper.v(TAG, "onProviderDisabled $provider")
when (provider) { when (provider) {
LocationManager.GPS_PROVIDER -> gpsProviderActive = LocationHelper.isGpsEnabled(locationManager) LocationManager.GPS_PROVIDER -> gpsProviderActive = isGpsEnabled(locationManager)
LocationManager.NETWORK_PROVIDER -> networkProviderActive = LocationHelper.isNetworkEnabled(locationManager) LocationManager.NETWORK_PROVIDER -> networkProviderActive = isNetworkEnabled(locationManager)
} }
} }
override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?)
@ -179,7 +177,8 @@ class TrackerService: Service(), SensorEventListener
} }
/* Displays or updates notification */ /* Displays or updates notification */
private fun displayNotification(): Notification { private fun displayNotification(): Notification
{
val notification: Notification = notificationHelper.createNotification( val notification: Notification = notificationHelper.createNotification(
trackingState, trackingState,
iso8601(GregorianCalendar.getInstance().time) iso8601(GregorianCalendar.getInstance().time)
@ -189,7 +188,8 @@ class TrackerService: Service(), SensorEventListener
} }
/* Overrides onAccuracyChanged from SensorEventListener */ /* Overrides onAccuracyChanged from SensorEventListener */
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) { override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int)
{
LogHelper.v(TAG, "Accuracy changed: $accuracy") LogHelper.v(TAG, "Accuracy changed: $accuracy")
} }
@ -220,24 +220,24 @@ class TrackerService: Service(), SensorEventListener
sensorManager = this.getSystemService(Context.SENSOR_SERVICE) as SensorManager sensorManager = this.getSystemService(Context.SENSOR_SERVICE) as SensorManager
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationHelper = NotificationHelper(this) notificationHelper = NotificationHelper(this)
gpsProviderActive = LocationHelper.isGpsEnabled(locationManager) gpsProviderActive = isGpsEnabled(locationManager)
networkProviderActive = LocationHelper.isNetworkEnabled(locationManager) networkProviderActive = isNetworkEnabled(locationManager)
gpsLocationListener = createLocationListener() gpsLocationListener = createLocationListener()
networkLocationListener = createLocationListener() networkLocationListener = createLocationListener()
trackingState = PreferencesHelper.loadTrackingState() trackingState = PreferencesHelper.loadTrackingState()
currentBestLocation = LocationHelper.getLastKnownLocation(this) currentBestLocation = getLastKnownLocation(this)
PreferencesHelper.registerPreferenceChangeListener(sharedPreferenceChangeListener) PreferencesHelper.registerPreferenceChangeListener(sharedPreferenceChangeListener)
} }
/* Overrides onDestroy from Service */ /* Overrides onDestroy from Service */
override fun onDestroy() { override fun onDestroy() {
LogHelper.i("VOUSSOIR", "TrackerService.onDestroy.")
super.onDestroy() super.onDestroy()
LogHelper.i(TAG, "onDestroy called.")
if (trackingState == Keys.STATE_TRACKING_ACTIVE) if (trackingState == Keys.STATE_TRACKING_ACTIVE)
{ {
pauseTracking() pauseTracking()
} }
stopForeground(true) stopForeground(STOP_FOREGROUND_REMOVE)
notificationManager.cancel(Keys.TRACKER_SERVICE_NOTIFICATION_ID) // this call was not necessary prior to Android 12 notificationManager.cancel(Keys.TRACKER_SERVICE_NOTIFICATION_ID) // this call was not necessary prior to Android 12
PreferencesHelper.unregisterPreferenceChangeListener(sharedPreferenceChangeListener) PreferencesHelper.unregisterPreferenceChangeListener(sharedPreferenceChangeListener)
removeGpsLocationListener() removeGpsLocationListener()
@ -316,7 +316,6 @@ class TrackerService: Service(), SensorEventListener
} }
} }
/* Adds location listeners to location manager */
fun removeNetworkLocationListener() fun removeNetworkLocationListener()
{ {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
@ -365,15 +364,14 @@ class TrackerService: Service(), SensorEventListener
stopForeground(STOP_FOREGROUND_DETACH) stopForeground(STOP_FOREGROUND_DETACH)
} }
/*
* Defines the listener for changes in shared preferences
*/
private val sharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key -> private val sharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
when (key) { when (key)
{
Keys.PREF_GPS_ONLY -> Keys.PREF_GPS_ONLY ->
{ {
gpsOnly = PreferencesHelper.loadGpsOnly() gpsOnly = PreferencesHelper.loadGpsOnly()
when (gpsOnly) { when (gpsOnly)
{
true -> removeNetworkLocationListener() true -> removeNetworkLocationListener()
false -> addNetworkLocationListener() false -> addNetworkLocationListener()
} }
@ -418,12 +416,12 @@ class TrackerService: Service(), SensorEventListener
Log.i("VOUSSOIR", "Omitting due to 0,0 location.") Log.i("VOUSSOIR", "Omitting due to 0,0 location.")
return false return false
} }
if (! LocationHelper.isRecentEnough(location)) if (! isRecentEnough(location))
{ {
Log.i("VOUSSOIR", "Omitting due to not recent enough.") Log.i("VOUSSOIR", "Omitting due to not recent enough.")
return false return false
} }
if (! LocationHelper.isAccurateEnough(location, Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY)) if (! isAccurateEnough(location, Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY))
{ {
Log.i("VOUSSOIR", "Omitting due to not accurate enough.") Log.i("VOUSSOIR", "Omitting due to not accurate enough.")
return false return false
@ -440,7 +438,7 @@ class TrackerService: Service(), SensorEventListener
{ {
return true return true
} }
if (! LocationHelper.isDifferentEnough(track.trkpts.last().toLocation(), location, omitRests)) if (! isDifferentEnough(track.trkpts.last().toLocation(), location, omitRests))
{ {
Log.i("VOUSSOIR", "Omitting due to too close to previous.") Log.i("VOUSSOIR", "Omitting due to too close to previous.")
return false return false

View file

@ -17,7 +17,7 @@
package org.y20k.trackbook package org.y20k.trackbook
import android.location.Location import android.location.Location
import org.y20k.trackbook.helpers.LocationHelper import org.y20k.trackbook.helpers.getNumberOfSatellites
import java.util.* import java.util.*
/* /*
@ -42,7 +42,7 @@ data class Trkpt(
altitude=location.altitude, altitude=location.altitude,
accuracy=location.accuracy, accuracy=location.accuracy,
time=location.time, time=location.time,
numberSatellites=LocationHelper.getNumberOfSatellites(location), numberSatellites=getNumberOfSatellites(location),
) )
/* Converts WayPoint into Location */ /* Converts WayPoint into Location */

View file

@ -27,159 +27,163 @@ import androidx.core.content.ContextCompat
import org.y20k.trackbook.Keys import org.y20k.trackbook.Keys
import kotlin.math.pow import kotlin.math.pow
/* /* Get default location */
* Keys object fun getDefaultLocation(): Location
*/ {
object LocationHelper { val defaultLocation: Location = Location(LocationManager.NETWORK_PROVIDER)
defaultLocation.latitude = Keys.DEFAULT_LATITUDE
/* Define log tag */ defaultLocation.longitude = Keys.DEFAULT_LONGITUDE
private val TAG: String = LogHelper.makeLogTag(LocationHelper::class.java) defaultLocation.accuracy = Keys.DEFAULT_ACCURACY
defaultLocation.altitude = Keys.DEFAULT_ALTITUDE
/* Get default location */ defaultLocation.time = Keys.DEFAULT_DATE.time
fun getDefaultLocation(): Location { return defaultLocation
val defaultLocation: Location = Location(LocationManager.NETWORK_PROVIDER) }
defaultLocation.latitude = Keys.DEFAULT_LATITUDE
defaultLocation.longitude = Keys.DEFAULT_LONGITUDE /* Tries to return the last location that the system has stored */
defaultLocation.accuracy = Keys.DEFAULT_ACCURACY fun getLastKnownLocation(context: Context): Location
defaultLocation.altitude = Keys.DEFAULT_ALTITUDE {
defaultLocation.time = Keys.DEFAULT_DATE.time // get last location that Trackbook has stored
return defaultLocation var lastKnownLocation: Location = PreferencesHelper.loadCurrentBestLocation()
} // try to get the last location the system has stored - it is probably more recent
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
/* Tries to return the last location that the system has stored */ val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
fun getLastKnownLocation(context: Context): Location { val lastKnownLocationGps: Location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) ?: lastKnownLocation
// get last location that Trackbook has stored val lastKnownLocationNetwork: Location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) ?: lastKnownLocation
var lastKnownLocation: Location = PreferencesHelper.loadCurrentBestLocation() when (isBetterLocation(lastKnownLocationGps, lastKnownLocationNetwork)) {
// try to get the last location the system has stored - it is probably more recent true -> lastKnownLocation = lastKnownLocationGps
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { false -> lastKnownLocation = lastKnownLocationNetwork
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager }
val lastKnownLocationGps: Location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) ?: lastKnownLocation }
val lastKnownLocationNetwork: Location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) ?: lastKnownLocation return lastKnownLocation
when (isBetterLocation(lastKnownLocationGps, lastKnownLocationNetwork)) { }
true -> lastKnownLocation = lastKnownLocationGps
false -> lastKnownLocation = lastKnownLocationNetwork /* Determines whether one location reading is better than the current location fix */
} fun isBetterLocation(location: Location, currentBestLocation: Location?): Boolean
} {
return lastKnownLocation // Credit: https://developer.android.com/guide/topics/location/strategies.html#BestEstimate
}
if (currentBestLocation == null)
/* Determines whether one location reading is better than the current location fix */ {
fun isBetterLocation(location: Location, currentBestLocation: Location?): Boolean // a new location is always better than no location
{ return true
// Credit: https://developer.android.com/guide/topics/location/strategies.html#BestEstimate }
if (currentBestLocation == null) { // check whether the new location fix is newer or older
// a new location is always better than no location val timeDelta: Long = location.time - currentBestLocation.time
return true val isSignificantlyNewer: Boolean = timeDelta > Keys.SIGNIFICANT_TIME_DIFFERENCE
} val isSignificantlyOlder:Boolean = timeDelta < -Keys.SIGNIFICANT_TIME_DIFFERENCE
// check whether the new location fix is newer or older when {
val timeDelta: Long = location.time - currentBestLocation.time // if it's been more than two minutes since the current location, use the new location because the user has likely moved
val isSignificantlyNewer: Boolean = timeDelta > Keys.SIGNIFICANT_TIME_DIFFERENCE isSignificantlyNewer -> return true
val isSignificantlyOlder:Boolean = timeDelta < -Keys.SIGNIFICANT_TIME_DIFFERENCE // if the new location is more than two minutes older, it must be worse
isSignificantlyOlder -> return false
when { }
// if it's been more than two minutes since the current location, use the new location because the user has likely moved
isSignificantlyNewer -> return true // check whether the new location fix is more or less accurate
// if the new location is more than two minutes older, it must be worse val isNewer: Boolean = timeDelta > 0L
isSignificantlyOlder -> return false val accuracyDelta: Float = location.accuracy - currentBestLocation.accuracy
} val isLessAccurate: Boolean = accuracyDelta > 0f
val isMoreAccurate: Boolean = accuracyDelta < 0f
// check whether the new location fix is more or less accurate val isSignificantlyLessAccurate: Boolean = accuracyDelta > 200f
val isNewer: Boolean = timeDelta > 0L
val accuracyDelta: Float = location.accuracy - currentBestLocation.accuracy // check if the old and new location are from the same provider
val isLessAccurate: Boolean = accuracyDelta > 0f val isFromSameProvider: Boolean = location.provider == currentBestLocation.provider
val isMoreAccurate: Boolean = accuracyDelta < 0f
val isSignificantlyLessAccurate: Boolean = accuracyDelta > 200f // determine location quality using a combination of timeliness and accuracy
return when {
// check if the old and new location are from the same provider isMoreAccurate -> true
val isFromSameProvider: Boolean = location.provider == currentBestLocation.provider isNewer && !isLessAccurate -> true
isNewer && !isSignificantlyLessAccurate && isFromSameProvider -> true
// determine location quality using a combination of timeliness and accuracy else -> false
return when { }
isMoreAccurate -> true }
isNewer && !isLessAccurate -> true
isNewer && !isSignificantlyLessAccurate && isFromSameProvider -> true /* Checks if GPS location provider is available and enabled */
else -> false fun isGpsEnabled(locationManager: LocationManager): Boolean
} {
} if (locationManager.allProviders.contains(LocationManager.GPS_PROVIDER))
{
/* Checks if GPS location provider is available and enabled */ return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
fun isGpsEnabled(locationManager: LocationManager): Boolean }
{ else
if (locationManager.allProviders.contains(LocationManager.GPS_PROVIDER)) {
{ return false
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) }
} }
else
{ /* Checks if Network location provider is available and enabled */
return false fun isNetworkEnabled(locationManager: LocationManager): Boolean
} {
} if (locationManager.allProviders.contains(LocationManager.NETWORK_PROVIDER))
{
/* Checks if Network location provider is available and enabled */ return locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
fun isNetworkEnabled(locationManager: LocationManager): Boolean { }
if (locationManager.allProviders.contains(LocationManager.NETWORK_PROVIDER)) { else
return locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) {
} else { return false
return false }
} }
}
/* Checks if given location is new */
/* Checks if given location is new */ fun isRecentEnough(location: Location): Boolean
fun isRecentEnough(location: Location): Boolean { {
val locationAge: Long = SystemClock.elapsedRealtimeNanos() - location.elapsedRealtimeNanos val locationAge: Long = SystemClock.elapsedRealtimeNanos() - location.elapsedRealtimeNanos
return locationAge < Keys.DEFAULT_THRESHOLD_LOCATION_AGE return locationAge < Keys.DEFAULT_THRESHOLD_LOCATION_AGE
} }
/* Checks if given location is accurate */ /* Checks if given location is accurate */
fun isAccurateEnough(location: Location, locationAccuracyThreshold: Int): Boolean { fun isAccurateEnough(location: Location, locationAccuracyThreshold: Int): Boolean
val isAccurate: Boolean {
when (location.provider) { if (location.provider == LocationManager.GPS_PROVIDER)
LocationManager.GPS_PROVIDER -> isAccurate = location.accuracy < locationAccuracyThreshold {
else -> isAccurate = location.accuracy < locationAccuracyThreshold + 10 // a bit more relaxed when location comes from network provider return location.accuracy < locationAccuracyThreshold
} }
return isAccurate else
} {
return location.accuracy < locationAccuracyThreshold + 10 // a bit more relaxed when location comes from network provider
/* Checks if given location is different enough compared to previous location */ }
fun isDifferentEnough(previousLocation: Location?, location: Location, omitRests: Boolean): Boolean { }
// check if previous location is (not) available
if (previousLocation == null) /* Checks if given location is different enough compared to previous location */
{ fun isDifferentEnough(previousLocation: Location?, location: Location, omitRests: Boolean): Boolean
return true {
} // check if previous location is (not) available
if (previousLocation == null)
if (! omitRests) {
{ return true
return true }
}
// location.accuracy is given as 1 standard deviation, with a 68% chance if (! omitRests)
// that the true position is within a circle of this radius. {
// These formulas determine if the difference between the last point and return true
// new point is statistically significant. }
val accuracy: Float = if (location.accuracy != 0.0f) location.accuracy else Keys.DEFAULT_THRESHOLD_DISTANCE
val previousAccuracy: Float = if (previousLocation.accuracy != 0.0f) previousLocation.accuracy else Keys.DEFAULT_THRESHOLD_DISTANCE // location.accuracy is given as 1 standard deviation, with a 68% chance
val accuracyDelta: Double = Math.sqrt((accuracy.pow(2) + previousAccuracy.pow(2)).toDouble()) // that the true position is within a circle of this radius.
val distance: Float = previousLocation.distanceTo(location) // These formulas determine if the difference between the last point and
// new point is statistically significant.
// With 1*accuracyDelta we have 68% confidence that the points are val accuracy: Float = if (location.accuracy != 0.0f) location.accuracy else Keys.DEFAULT_THRESHOLD_DISTANCE
// different. We can multiply this number to increase confidence but val previousAccuracy: Float = if (previousLocation.accuracy != 0.0f) previousLocation.accuracy else Keys.DEFAULT_THRESHOLD_DISTANCE
// decrease point recording frequency if needed. val accuracyDelta: Double = Math.sqrt((accuracy.pow(2) + previousAccuracy.pow(2)).toDouble())
return distance > accuracyDelta val distance: Float = previousLocation.distanceTo(location)
}
// With 1*accuracyDelta we have 68% confidence that the points are
/* Get number of satellites from Location extras */ // different. We can multiply this number to increase confidence but
fun getNumberOfSatellites(location: Location): Int { // decrease point recording frequency if needed.
val numberOfSatellites: Int return distance > accuracyDelta
val extras: Bundle? = location.extras }
if (extras != null && extras.containsKey("satellites")) {
numberOfSatellites = extras.getInt("satellites", 0) /* Get number of satellites from Location extras */
} else { fun getNumberOfSatellites(location: Location): Int
numberOfSatellites = 0 {
} val numberOfSatellites: Int
return numberOfSatellites val extras: Bundle? = location.extras
} if (extras != null && extras.containsKey("satellites")) {
numberOfSatellites = extras.getInt("satellites", 0)
} else {
numberOfSatellites = 0
}
return numberOfSatellites
} }

View file

@ -134,8 +134,6 @@ fun createSpecialMakersTrackOverlay(context: Context, map_view: MapView, track:
map_view.overlays.add(createOverlay(context, overlayItems)) map_view.overlays.add(createOverlay(context, overlayItems))
} }
fun createOverlayItem(context: Context, latitude: Double, longitude: Double, accuracy: Float, provider: String, time: Long): OverlayItem fun createOverlayItem(context: Context, latitude: Double, longitude: Double, accuracy: Float, provider: String, time: Long): OverlayItem
{ {
val title: String = "${context.getString(R.string.marker_description_time)}: ${SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM, Locale.getDefault()).format(time)}" val title: String = "${context.getString(R.string.marker_description_time)}: ${SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM, Locale.getDefault()).format(time)}"

View file

@ -65,7 +65,6 @@ data class MapFragmentLayoutHolder(
private val trackingState: Int private val trackingState: Int
) )
{ {
/* Main class variables */
val rootView: View val rootView: View
var userInteraction: Boolean = false var userInteraction: Boolean = false
val currentLocationButton: FloatingActionButton val currentLocationButton: FloatingActionButton
@ -75,12 +74,13 @@ data class MapFragmentLayoutHolder(
private var current_location_radius: Polygon = Polygon() private var current_location_radius: Polygon = Polygon()
private var currentTrackOverlay: SimpleFastPointOverlay? private var currentTrackOverlay: SimpleFastPointOverlay?
private var currentTrackSpecialMarkerOverlay: ItemizedIconOverlay<OverlayItem>? private var currentTrackSpecialMarkerOverlay: ItemizedIconOverlay<OverlayItem>?
private val useImperial: Boolean = PreferencesHelper.loadUseImperialUnits()
private var locationErrorBar: Snackbar private var locationErrorBar: Snackbar
private var controller: IMapController private var controller: IMapController
private var zoomLevel: Double private var zoomLevel: Double
init { init
{
Log.i("VOUSSOIR", "MapFragmentLayoutHolder.init")
// find views // find views
rootView = inflater.inflate(R.layout.fragment_map, container, false) rootView = inflater.inflate(R.layout.fragment_map, container, false)
mapView = rootView.findViewById(R.id.map) mapView = rootView.findViewById(R.id.map)
@ -164,7 +164,7 @@ data class MapFragmentLayoutHolder(
fun markCurrentPosition(location: Location, trackingState: Int = Keys.STATE_TRACKING_STOPPED) fun markCurrentPosition(location: Location, trackingState: Int = Keys.STATE_TRACKING_STOPPED)
{ {
Log.i("VOUSSOIR", "MapFragmentLayoutHolder.markCurrentPosition") Log.i("VOUSSOIR", "MapFragmentLayoutHolder.markCurrentPosition")
val locationIsOld: Boolean = !(LocationHelper.isRecentEnough(location)) val locationIsOld: Boolean = !(isRecentEnough(location))
// create marker // create marker
val newMarker: Drawable val newMarker: Drawable
@ -228,7 +228,7 @@ data class MapFragmentLayoutHolder(
val p = Polygon() val p = Polygon()
p.points = Polygon.pointsAsCircle(GeoPoint(homepoint.location.latitude, homepoint.location.longitude), homepoint.location.accuracy.toDouble()) p.points = Polygon.pointsAsCircle(GeoPoint(homepoint.location.latitude, homepoint.location.longitude), homepoint.location.accuracy.toDouble())
p.fillPaint.color = Color.argb(64, 255, 193, 7) p.fillPaint.color = Color.argb(64, 255, 193, 7)
p.outlinePaint.color = Color.argb(128, 255, 193, 7) p.outlinePaint.color = Color.argb(0, 0, 0, 0)
map_view.overlays.add(p) map_view.overlays.add(p)
} }
} }