checkpoint
This commit is contained in:
parent
df77b089ac
commit
04fa76249b
7 changed files with 197 additions and 191 deletions
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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)}"
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue