Compare commits
	
		
			10 commits
		
	
	
		
			a27b8713a9
			...
			29a4a1dae3
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 29a4a1dae3 | |||
| 31c77528d7 | |||
| 535133ce22 | |||
| a04a0d3a3a | |||
| eb1ad45c4c | |||
| 47c338f38f | |||
| cd25415e9b | |||
| a75ee66ca4 | |||
| 70e6e64918 | |||
| d5df922d3d | 
					 7 changed files with 190 additions and 98 deletions
				
			
		|  | @ -10,8 +10,8 @@ android { | |||
|         applicationId 'net.voussoir.trkpt' | ||||
|         minSdkVersion 25 | ||||
|         targetSdk 32 | ||||
|         versionCode 56 | ||||
|         versionName '1.2.0' | ||||
|         versionCode 58 | ||||
|         versionName '1.3.0' | ||||
|         resConfigs "en", "da", "de", "fr", "hr", "id", "it", "ja", "nb-rNO", "nl", "pl", "pt-rBR", "ru", "sv", "tr", "zh-rCN" | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -56,11 +56,11 @@ class Database(val trackbook: Trackbook) | |||
|         this.connection.endTransaction() | ||||
|     } | ||||
| 
 | ||||
|     fun delete_trkpt(device_id: String, time: Long) | ||||
|     fun delete_trkpt(trkpt: Trkpt) | ||||
|     { | ||||
|         Log.i("VOUSSOIR", "Database.delete_trkpt") | ||||
|         begin_transaction() | ||||
|         connection.delete("trkpt", "device_id = ? AND time = ?", arrayOf(device_id, time.toString())) | ||||
|         connection.delete("trkpt", "device_id = ? AND time = ?", arrayOf(trkpt.device_id, trkpt.time.toString())) | ||||
|     } | ||||
| 
 | ||||
|     fun delete_trkpt_start_end(device_id: String, start_time: Long, end_time: Long) | ||||
|  | @ -101,18 +101,33 @@ class Database(val trackbook: Trackbook) | |||
|         )) | ||||
|     } | ||||
| 
 | ||||
|     fun select_trkpt_bounding_box(device_id: String, north: Double, south: Double, east: Double, west: Double, max_accuracy: Float=Keys.DEFAULT_MAX_ACCURACY): Iterator<Trkpt> | ||||
|     fun select_trkpt_bounding_box(device_id: String?, north: Double, south: Double, east: Double, west: Double, max_accuracy: Float=Keys.DEFAULT_MAX_ACCURACY): Iterator<Trkpt> | ||||
|     { | ||||
|         Log.i("VOUSSOIR", "Track.trkpt_generator: Querying points between $north, $south, $east, $west.") | ||||
|         return _trkpt_generator(this.connection.rawQuery( | ||||
|             """ | ||||
|         if (device_id == null) | ||||
|         { | ||||
|             return _trkpt_generator(this.connection.rawQuery( | ||||
|                 """ | ||||
|             SELECT device_id, lat, lon, time, provider, ele, accuracy, sat | ||||
|             FROM trkpt | ||||
|             WHERE lat >= ? AND lat <= ? AND lon >= ? AND lon <= ? AND accuracy <= ? | ||||
|             ORDER BY time ASC | ||||
|             """, | ||||
|                 arrayOf(south.toString(), north.toString(), west.toString(), east.toString(), max_accuracy.toString()) | ||||
|             )) | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return _trkpt_generator(this.connection.rawQuery( | ||||
|                 """ | ||||
|             SELECT device_id, lat, lon, time, provider, ele, accuracy, sat | ||||
|             FROM trkpt | ||||
|             WHERE device_id = ? AND lat >= ? AND lat <= ? AND lon >= ? AND lon <= ? AND accuracy <= ? | ||||
|             ORDER BY time ASC | ||||
|             """, | ||||
|             arrayOf(device_id, south.toString(), north.toString(), west.toString(), east.toString(), max_accuracy.toString()) | ||||
|         )) | ||||
|                 arrayOf(device_id, south.toString(), north.toString(), west.toString(), east.toString(), max_accuracy.toString()) | ||||
|             )) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fun _trkpt_generator(cursor: Cursor) = iterator<Trkpt> | ||||
|  |  | |||
|  | @ -79,6 +79,10 @@ object Keys { | |||
|     const val STATE_THEME_LIGHT_MODE: String = "stateLightMode" | ||||
|     const val STATE_THEME_DARK_MODE: String = "stateDarkMode" | ||||
| 
 | ||||
|     // Track view | ||||
|     const val SELECTION_MODE_STARTSTOP = 1 | ||||
|     const val SELECTION_MODE_SPATIAL = 2 | ||||
| 
 | ||||
|     // dialog types | ||||
|     const val DIALOG_DELETE_TRACK: Int = 1 | ||||
| 
 | ||||
|  |  | |||
|  | @ -47,6 +47,7 @@ class MainActivity: AppCompatActivity() | |||
|     /* Overrides onCreate from AppCompatActivity */ | ||||
|     override fun onCreate(savedInstanceState: Bundle?) | ||||
|     { | ||||
|         Log.i("VOUSSOIR", "MainActivity.onCreate") | ||||
|         trackbook = (applicationContext as Trackbook) | ||||
|         super.onCreate(savedInstanceState) | ||||
|         request_permissions(this) | ||||
|  | @ -125,6 +126,7 @@ class MainActivity: AppCompatActivity() | |||
|     /* Overrides onDestroy from AppCompatActivity */ | ||||
|     override fun onDestroy() | ||||
|     { | ||||
|         Log.i("VOUSSOIR", "MainActivity.onDestroy") | ||||
|         super.onDestroy() | ||||
|         // unregister listener for changes in shared preferences | ||||
|         PreferencesHelper.unregisterPreferenceChangeListener(sharedPreferenceChangeListener) | ||||
|  |  | |||
|  | @ -39,7 +39,6 @@ import androidx.core.view.isVisible | |||
| import androidx.fragment.app.Fragment | ||||
| import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton | ||||
| import com.google.android.material.floatingactionbutton.FloatingActionButton | ||||
| import com.google.android.material.snackbar.Snackbar | ||||
| import org.osmdroid.events.MapEventsReceiver | ||||
| import org.osmdroid.tileprovider.tilesource.TileSourceFactory | ||||
| import org.osmdroid.util.GeoPoint | ||||
|  | @ -57,15 +56,16 @@ class MapFragment : Fragment() | |||
| { | ||||
|     private lateinit var trackbook: Trackbook | ||||
| 
 | ||||
|     private var bound: Boolean = false | ||||
|     private var tracker_service_bound: Boolean = false | ||||
|     private var tracker_service: TrackerService? = null | ||||
| 
 | ||||
|     val handler: Handler = Handler(Looper.getMainLooper()) | ||||
| 
 | ||||
|     var continuous_auto_center: Boolean = true | ||||
|     private var trackerService: TrackerService? = null | ||||
|     private lateinit var database_changed_listener: DatabaseChangedListener | ||||
|     var show_debug: Boolean = false | ||||
| 
 | ||||
|     var thismapfragment: MapFragment? = null | ||||
|     private lateinit var database_changed_listener: DatabaseChangedListener | ||||
| 
 | ||||
|     lateinit var rootView: View | ||||
|     private lateinit var mapView: MapView | ||||
|     lateinit var mainButton: ExtendedFloatingActionButton | ||||
|  | @ -77,14 +77,12 @@ class MapFragment : Fragment() | |||
|     private var current_track_overlay: Polyline? = null | ||||
|     private var current_position_overlays = ArrayList<Overlay>() | ||||
|     private var homepoints_overlays = ArrayList<Overlay>() | ||||
|     private lateinit var locationErrorBar: Snackbar | ||||
| 
 | ||||
|     /* Overrides onCreate from Fragment */ | ||||
|     override fun onCreate(savedInstanceState: Bundle?) | ||||
|     { | ||||
|         Log.i("VOUSSOIR", "MapFragment.onCreate") | ||||
|         super.onCreate(savedInstanceState) | ||||
|         thismapfragment = this | ||||
|         this.trackbook = (requireContext().applicationContext as Trackbook) | ||||
|         database_changed_listener = object: DatabaseChangedListener | ||||
|         { | ||||
|  | @ -116,7 +114,6 @@ class MapFragment : Fragment() | |||
|         zoom_out_button = rootView.findViewById(R.id.zoom_out_button) | ||||
|         map_current_time = rootView.findViewById(R.id.map_current_time) | ||||
|         mainButton = rootView.findViewById(R.id.main_button) | ||||
|         locationErrorBar = Snackbar.make(mapView, String(), Snackbar.LENGTH_INDEFINITE) | ||||
| 
 | ||||
|         mapView.setOnLongClickListener{ | ||||
|             Log.i("VOUSSOIR", "mapview longpress") | ||||
|  | @ -198,7 +195,7 @@ class MapFragment : Fragment() | |||
|         } | ||||
| 
 | ||||
|         mainButton.setOnClickListener { | ||||
|             val tracker = trackerService | ||||
|             val tracker = tracker_service | ||||
|             if (tracker == null) | ||||
|             { | ||||
|                 return@setOnClickListener | ||||
|  | @ -214,7 +211,7 @@ class MapFragment : Fragment() | |||
|             handler.postDelayed(redraw_runnable, 0) | ||||
|         } | ||||
|         currentLocationButton.setOnClickListener { | ||||
|             val tracker = trackerService | ||||
|             val tracker = tracker_service | ||||
|             if (tracker == null) | ||||
|             { | ||||
|                 return@setOnClickListener | ||||
|  | @ -240,13 +237,7 @@ class MapFragment : Fragment() | |||
|     { | ||||
|         Log.i("VOUSSOIR", "MapFragment.onStart") | ||||
|         super.onStart() | ||||
|         // request location permission if denied | ||||
|         if (ContextCompat.checkSelfPermission(activity as Context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) | ||||
|         { | ||||
|             requestLocationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION) | ||||
|         } | ||||
|         // bind to TrackerService | ||||
|         activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE) | ||||
|         activity?.bindService(Intent(activity, TrackerService::class.java), tracker_service_connection, Context.BIND_AUTO_CREATE) | ||||
|         handler.post(redraw_runnable) | ||||
|     } | ||||
| 
 | ||||
|  | @ -270,13 +261,13 @@ class MapFragment : Fragment() | |||
|         super.onPause() | ||||
|         requireActivity().window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) | ||||
| 
 | ||||
|         val tracker = trackerService | ||||
|         val tracker = tracker_service | ||||
|         if (tracker == null) | ||||
|         { | ||||
|             return | ||||
|         } | ||||
|         saveBestLocationState(tracker.currentBestLocation) | ||||
|         if (bound && (tracker.tracking_state == Keys.STATE_MAPVIEW || tracker.tracking_state == Keys.STATE_STOP)) | ||||
|         if (tracker_service_bound && (tracker.tracking_state == Keys.STATE_MAPVIEW || tracker.tracking_state == Keys.STATE_STOP)) | ||||
|         { | ||||
|             tracker.remove_gps_location_listener() | ||||
|             tracker.remove_network_location_listener() | ||||
|  | @ -290,9 +281,9 @@ class MapFragment : Fragment() | |||
|     { | ||||
|         super.onStop() | ||||
|         // unbind from TrackerService | ||||
|         if (bound) | ||||
|         if (tracker_service_bound) | ||||
|         { | ||||
|             activity?.unbindService(connection) | ||||
|             activity?.unbindService(tracker_service_connection) | ||||
|             handleServiceUnbind() | ||||
|         } | ||||
|         handler.removeCallbacks(redraw_runnable) | ||||
|  | @ -317,24 +308,6 @@ class MapFragment : Fragment() | |||
|         handler.removeCallbacks(redraw_runnable) | ||||
|     } | ||||
| 
 | ||||
|     private val requestLocationPermissionLauncher = registerForActivityResult(RequestPermission()) { isGranted: Boolean -> | ||||
|         if (isGranted) | ||||
|         { | ||||
|             // permission was granted - re-bind service | ||||
|             activity?.unbindService(connection) | ||||
|             activity?.bindService(Intent(activity, TrackerService::class.java),  connection,  Context.BIND_AUTO_CREATE) | ||||
|             Log.i("VOUSSOIR", "Request result: Location permission has been granted.") | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // permission denied - unbind service | ||||
|             activity?.unbindService(connection) | ||||
|         } | ||||
|         val gpsProviderActive = if (trackerService == null) false else trackerService!!.gpsProviderActive | ||||
|         val networkProviderActive = if (trackerService == null) false else trackerService!!.networkProviderActive | ||||
|         toggleLocationErrorBar(gpsProviderActive, networkProviderActive) | ||||
|     } | ||||
| 
 | ||||
|     private fun startTracking() | ||||
|     { | ||||
|         // start service via intent so that it keeps running after unbind | ||||
|  | @ -348,9 +321,9 @@ class MapFragment : Fragment() | |||
|         { | ||||
|             activity?.startService(intent) | ||||
|         } | ||||
|         if (trackerService != null) | ||||
|         if (tracker_service != null) | ||||
|         { | ||||
|             trackerService!!.state_full_recording() | ||||
|             tracker_service!!.state_full_recording() | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -358,7 +331,7 @@ class MapFragment : Fragment() | |||
|     /* Handles state when service is being unbound */ | ||||
|     private fun handleServiceUnbind() | ||||
|     { | ||||
|         bound = false | ||||
|         tracker_service_bound = false | ||||
|         // unregister listener for changes in shared preferences | ||||
|         PreferencesHelper.unregisterPreferenceChangeListener(sharedPreferenceChangeListener) | ||||
|     } | ||||
|  | @ -397,12 +370,11 @@ class MapFragment : Fragment() | |||
|         current_position_overlays.clear() | ||||
|     } | ||||
| 
 | ||||
|     /* Mark current position on map */ | ||||
|     fun create_current_position_overlays() | ||||
|     { | ||||
|         clear_current_position_overlays() | ||||
| 
 | ||||
|         val tracker = trackerService | ||||
|         val tracker = tracker_service | ||||
|         if (tracker == null) | ||||
|         { | ||||
|             return | ||||
|  | @ -579,7 +551,7 @@ class MapFragment : Fragment() | |||
| 
 | ||||
|     fun update_main_button() | ||||
|     { | ||||
|         val tracker = trackerService | ||||
|         val tracker = tracker_service | ||||
|         mainButton.isEnabled = trackbook.database.ready | ||||
|         currentLocationButton.isVisible = true | ||||
|         if (! trackbook.database.ready) | ||||
|  | @ -601,27 +573,7 @@ class MapFragment : Fragment() | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fun toggleLocationErrorBar(gpsProviderActive: Boolean, networkProviderActive: Boolean) | ||||
|     { | ||||
|         if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) | ||||
|         { | ||||
|             // CASE: Location permission not granted | ||||
|             locationErrorBar.setText(R.string.snackbar_message_location_permission_denied) | ||||
|             if (!locationErrorBar.isShown) locationErrorBar.show() | ||||
|         } | ||||
|         else if (!gpsProviderActive && !networkProviderActive) | ||||
|         { | ||||
|             // CASE: Location setting is off | ||||
|             locationErrorBar.setText(R.string.snackbar_message_location_offline) | ||||
|             if (!locationErrorBar.isShown) locationErrorBar.show() | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             if (locationErrorBar.isShown) locationErrorBar.dismiss() | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private val connection = object : ServiceConnection { | ||||
|     private val tracker_service_connection = object : ServiceConnection { | ||||
|         override fun onServiceConnected(className: ComponentName, service: IBinder) | ||||
|         { | ||||
|             // get reference to tracker service] | ||||
|  | @ -630,8 +582,8 @@ class MapFragment : Fragment() | |||
|             { | ||||
|                 return | ||||
|             } | ||||
|             bound = true | ||||
|             trackerService = serviceref | ||||
|             tracker_service_bound = true | ||||
|             tracker_service = serviceref | ||||
|             // get state of tracking and update button if necessary | ||||
|             redraw() | ||||
|             // register listener for changes in shared preferences | ||||
|  | @ -648,7 +600,7 @@ class MapFragment : Fragment() | |||
|     { | ||||
|         // Log.i("VOUSSOIR", "MapFragment.redraw") | ||||
|         update_main_button() | ||||
|         val tracker = trackerService | ||||
|         val tracker = tracker_service | ||||
|         if (tracker == null) | ||||
|         { | ||||
|             return | ||||
|  | @ -693,7 +645,7 @@ class MapFragment : Fragment() | |||
| 
 | ||||
|     fun state_name(): String | ||||
|     { | ||||
|         val tracker = trackerService | ||||
|         val tracker = tracker_service | ||||
|         if (tracker == null) | ||||
|         { | ||||
|             return "null" | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ import java.util.* | |||
| 
 | ||||
| data class Track ( | ||||
|     val database: Database, | ||||
|     val device_id: String, | ||||
|     var device_id: String, | ||||
|     var name: String = "", | ||||
|     var _start_time: Long = 0L, | ||||
|     var _end_time: Long = 0L, | ||||
|  |  | |||
|  | @ -21,12 +21,17 @@ | |||
| package net.voussoir.trkpt | ||||
| 
 | ||||
| import YesNoDialog | ||||
| import android.Manifest | ||||
| import android.app.Activity | ||||
| import android.app.Dialog | ||||
| import android.content.Context | ||||
| import android.content.Intent | ||||
| import android.content.pm.PackageManager | ||||
| import android.graphics.Color | ||||
| import android.graphics.Paint | ||||
| import android.location.Location | ||||
| import android.location.LocationListener | ||||
| import android.location.LocationManager | ||||
| import android.net.Uri | ||||
| import android.os.Bundle | ||||
| import android.os.Handler | ||||
|  | @ -55,10 +60,7 @@ import org.osmdroid.events.ZoomEvent | |||
| import org.osmdroid.tileprovider.tilesource.TileSourceFactory | ||||
| import org.osmdroid.util.GeoPoint | ||||
| import org.osmdroid.views.MapView | ||||
| import org.osmdroid.views.overlay.MapEventsOverlay | ||||
| import org.osmdroid.views.overlay.Marker | ||||
| import org.osmdroid.views.overlay.Polyline | ||||
| import org.osmdroid.views.overlay.TilesOverlay | ||||
| import org.osmdroid.views.overlay.* | ||||
| import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlay | ||||
| import org.osmdroid.views.overlay.simplefastpoint.SimpleFastPointOverlayOptions | ||||
| import org.osmdroid.views.overlay.simplefastpoint.SimplePointTheme | ||||
|  | @ -71,7 +73,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
| 
 | ||||
|     lateinit var rootView: View | ||||
|     lateinit var save_track_button: ImageButton | ||||
|     lateinit var deleteButton: ImageButton | ||||
|     lateinit var delete_whole_track_button: ImageButton | ||||
|     lateinit var zoom_in_button: FloatingActionButton | ||||
|     lateinit var zoom_out_button: FloatingActionButton | ||||
|     lateinit var trackNameView: MaterialTextView | ||||
|  | @ -93,6 +95,8 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|     var ready_to_straighten: Boolean = false | ||||
|     var track_query_start_time_previous: Int = 0 | ||||
|     var track_query_end_time_previous: Int = 0 | ||||
|     var selection_mode: Int = Keys.SELECTION_MODE_STARTSTOP | ||||
| 
 | ||||
|     private lateinit var mapView: MapView | ||||
|     private lateinit var controller: IMapController | ||||
|     private lateinit var statisticsSheetBehavior: BottomSheetBehavior<View> | ||||
|  | @ -115,6 +119,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|     private lateinit var track_segment_overlays: ArrayDeque<Polyline> | ||||
|     private var track_geopoints: MutableList<IGeoPoint> = mutableListOf() | ||||
|     private var track_points_overlay: SimpleFastPointOverlay? = null | ||||
|     private var current_position_overlays = ArrayList<Overlay>() | ||||
|     // private lateinit var trkpt_infowindow: InfoWindow | ||||
|     private var useImperialUnits: Boolean = false | ||||
|     private val handler: Handler = Handler(Looper.getMainLooper()) | ||||
|  | @ -123,6 +128,10 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|     var selected_trkpt: Trkpt? = null | ||||
|     lateinit var selected_trkpt_marker: Marker | ||||
| 
 | ||||
|     private lateinit var locationManager: LocationManager | ||||
|     private lateinit var gpsLocationListener: LocationListener | ||||
|     private var gpslistenerregistered = false | ||||
| 
 | ||||
|     override fun onCreate(savedInstanceState: Bundle?) | ||||
|     { | ||||
|         super.onCreate(savedInstanceState) | ||||
|  | @ -156,10 +165,12 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|             end_time=requested_end_time, | ||||
|             max_accuracy=PreferencesHelper.load_max_accuracy(), | ||||
|         )) | ||||
|         selection_mode = Keys.SELECTION_MODE_STARTSTOP | ||||
| 
 | ||||
|         rootView = inflater.inflate(R.layout.fragment_track, container, false) | ||||
|         mapView = rootView.findViewById(R.id.map) | ||||
|         save_track_button = rootView.findViewById(R.id.save_button) | ||||
|         deleteButton = rootView.findViewById(R.id.delete_button) | ||||
|         delete_whole_track_button = rootView.findViewById(R.id.delete_button) | ||||
|         zoom_in_button = rootView.findViewById(R.id.zoom_in_button) | ||||
|         zoom_out_button = rootView.findViewById(R.id.zoom_out_button) | ||||
|         trackNameView = rootView.findViewById(R.id.statistics_track_name_headline) | ||||
|  | @ -178,6 +189,20 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|         } | ||||
|         controller.setZoom(Keys.DEFAULT_ZOOM_LEVEL) | ||||
| 
 | ||||
|         val has_permission: Boolean = ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED | ||||
|         if (has_permission) | ||||
|         { | ||||
|             locationManager = requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager | ||||
|             gpsLocationListener = createLocationListener() | ||||
|             locationManager.requestLocationUpdates( | ||||
|                 LocationManager.GPS_PROVIDER, | ||||
|                 0, | ||||
|                 0f, | ||||
|                 gpsLocationListener, | ||||
|             ) | ||||
|             gpslistenerregistered = true | ||||
|         } | ||||
| 
 | ||||
|         // trkpt_infowindow = MarkerInfoWindow(R.layout.trkpt_infowindow, mapView) | ||||
| 
 | ||||
|         statisticsSheet = rootView.findViewById(R.id.statistics_sheet) | ||||
|  | @ -271,7 +296,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|                 Log.i("VOUSSOIR", selected.rendered_by_polyline?.actualPoints?.size.toString()) | ||||
|                 selected.rendered_by_polyline?.setPoints(ArrayList(selected.rendered_by_polyline?.actualPoints)) | ||||
|                 Log.i("VOUSSOIR", selected.rendered_by_polyline?.actualPoints?.size.toString()) | ||||
|                 trackbook.database.delete_trkpt(selected.device_id, selected.time) | ||||
|                 trackbook.database.delete_trkpt(selected) | ||||
|                 trackbook.database.commit() | ||||
|                 deselect_trkpt() | ||||
|                 mapView.invalidate() | ||||
|  | @ -291,6 +316,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|                     end_time=track.trkpts.last().time, | ||||
|                     max_accuracy=PreferencesHelper.load_max_accuracy(), | ||||
|                 )) | ||||
|                 selection_mode = Keys.SELECTION_MODE_STARTSTOP | ||||
|                 deselect_trkpt() | ||||
|                 render_track() | ||||
|             } | ||||
|  | @ -309,6 +335,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|                     end_time=selected.time, | ||||
|                     max_accuracy=PreferencesHelper.load_max_accuracy(), | ||||
|                 )) | ||||
|                 selection_mode = Keys.SELECTION_MODE_STARTSTOP | ||||
|                 deselect_trkpt() | ||||
|                 render_track() | ||||
|             } | ||||
|  | @ -323,12 +350,14 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|                 val polyline = selected.rendered_by_polyline | ||||
|                 if (polyline != null) | ||||
|                 { | ||||
|                     track.device_id = selected.device_id | ||||
|                     track.load_trkpts(trackbook.database.select_trkpt_start_end( | ||||
|                         track.device_id, | ||||
|                         selected.device_id, | ||||
|                         start_time=(polyline.actualPoints.first() as Trkpt).time, | ||||
|                         end_time=(polyline.actualPoints.last() as Trkpt).time, | ||||
|                         max_accuracy=PreferencesHelper.load_max_accuracy(), | ||||
|                     )) | ||||
|                     selection_mode = Keys.SELECTION_MODE_STARTSTOP | ||||
| 
 | ||||
|                     track.expand_to_trkseg_bounds() | ||||
| 
 | ||||
|  | @ -342,13 +371,14 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|         when_was_i_here_button.setOnClickListener { | ||||
|             Log.i("VOUSSOIR", "when_was_i_here_button.") | ||||
|             track.load_trkpts(trackbook.database.select_trkpt_bounding_box( | ||||
|                 device_id=track.device_id, | ||||
|                 device_id=null, | ||||
|                 north=mapView.boundingBox.actualNorth, | ||||
|                 south=mapView.boundingBox.actualSouth, | ||||
|                 east=mapView.boundingBox.lonEast, | ||||
|                 west=mapView.boundingBox.lonWest, | ||||
|                 max_accuracy=PreferencesHelper.load_max_accuracy(), | ||||
|             )) | ||||
|             selection_mode = Keys.SELECTION_MODE_SPATIAL | ||||
|             set_datetimes_from_track() | ||||
|             render_track() | ||||
|         } | ||||
|  | @ -414,7 +444,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|             dialog.show() | ||||
|         } | ||||
| 
 | ||||
|         deleteButton.setOnClickListener { | ||||
|         delete_whole_track_button.setOnClickListener { | ||||
|             val dialogMessage = "${getString(R.string.dialog_yes_no_message_delete_recording)}\n\n${track.trkpts.size} trackpoints" | ||||
|             YesNoDialog(this@TrackFragment as YesNoDialog.YesNoDialogListener).show( | ||||
|                 context = activity as Context, | ||||
|  | @ -468,12 +498,78 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|         return rootView | ||||
|     } | ||||
| 
 | ||||
|     override fun onDestroyView() | ||||
|     { | ||||
|         super.onDestroyView() | ||||
|         if (gpslistenerregistered) | ||||
|         { | ||||
|             locationManager.removeUpdates(gpsLocationListener) | ||||
|             gpslistenerregistered = false | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fun clear_current_position_overlays() | ||||
|     { | ||||
|         for (ov in current_position_overlays) | ||||
|         { | ||||
|             if (ov in mapView.overlays) | ||||
|             { | ||||
|                 mapView.overlays.remove(ov) | ||||
|             } | ||||
|         } | ||||
|         current_position_overlays.clear() | ||||
|     } | ||||
| 
 | ||||
|     fun create_current_position_overlays(location: Location) | ||||
|     { | ||||
|         clear_current_position_overlays() | ||||
| 
 | ||||
|         val newMarker = ContextCompat.getDrawable(requireContext(), R.drawable.ic_marker_location_blue_24dp)!! | ||||
|         val fillcolor = Color.argb(64, 60, 152, 219) | ||||
| 
 | ||||
|         val current_location_radius = Polygon() | ||||
|         current_location_radius.points = Polygon.pointsAsCircle( | ||||
|             GeoPoint(location.latitude, location.longitude), | ||||
|             location.accuracy.toDouble() | ||||
|         ) | ||||
|         current_location_radius.fillPaint.color = fillcolor | ||||
|         current_location_radius.outlinePaint.color = Color.argb(0, 0, 0, 0) | ||||
|         current_position_overlays.add(current_location_radius) | ||||
| 
 | ||||
|         val overlayItems: java.util.ArrayList<OverlayItem> = java.util.ArrayList<OverlayItem>() | ||||
|         val overlayItem: OverlayItem = createOverlayItem( | ||||
|             location.latitude, | ||||
|             location.longitude, | ||||
|             title="Current location", | ||||
|             description="Current location", | ||||
|         ) | ||||
|         overlayItem.setMarker(newMarker) | ||||
|         overlayItems.add(overlayItem) | ||||
|         current_position_overlays.add(createOverlay(requireContext(), overlayItems)) | ||||
| 
 | ||||
|         for (ov in current_position_overlays) | ||||
|         { | ||||
|             mapView.overlays.add(ov) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /* Overrides onResume from Fragment */ | ||||
|     override fun onResume() | ||||
|     { | ||||
|         super.onResume() | ||||
|     } | ||||
| 
 | ||||
|     private fun createLocationListener(): LocationListener | ||||
|     { | ||||
|         return object : LocationListener | ||||
|         { | ||||
|             override fun onLocationChanged(location: Location) | ||||
|             { | ||||
|                 create_current_position_overlays(location) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fun select_trkpt(trkpt: Trkpt) | ||||
|     { | ||||
|         selected_trkpt = trkpt | ||||
|  | @ -657,6 +753,11 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|         { | ||||
|             create_start_end_markers(requireContext(), mapView, pl.actualPoints.first() as Trkpt, pl.actualPoints.last() as Trkpt) | ||||
|         } | ||||
| 
 | ||||
|         for (ov in current_position_overlays) | ||||
|         { | ||||
|             mapView.overlays.add(ov) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fun new_track_segment_overlay(): Polyline | ||||
|  | @ -830,6 +931,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|                 end_time=get_datetime(track_query_end_date, track_query_end_time, seconds=59).time, | ||||
|                 max_accuracy=PreferencesHelper.load_max_accuracy(), | ||||
|             )) | ||||
|             selection_mode = Keys.SELECTION_MODE_STARTSTOP | ||||
|             Log.i("VOUSSOIR", "TrackFragment.requery_and_render: Reloaded ${track.trkpts.size} trkpts.") | ||||
|             render_track() | ||||
|         } | ||||
|  | @ -863,14 +965,31 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener | |||
|     { | ||||
|         if (type == Keys.DIALOG_DELETE_TRACK && dialogResult && track.trkpts.isNotEmpty()) | ||||
|         { | ||||
|             trackbook.database.delete_trkpt_start_end( | ||||
|                 track.device_id, | ||||
|                 track.trkpts.first().time, | ||||
|                 track.trkpts.last().time, | ||||
|             ) | ||||
|             trackbook.database.commit() | ||||
|             handler.removeCallbacks(requery_and_render) | ||||
|             handler.postDelayed(requery_and_render, RERENDER_DELAY) | ||||
|             if (selection_mode == Keys.SELECTION_MODE_STARTSTOP) | ||||
|             { | ||||
|                 trackbook.database.delete_trkpt_start_end( | ||||
|                     track.device_id, | ||||
|                     track.trkpts.first().time, | ||||
|                     track.trkpts.last().time, | ||||
|                 ) | ||||
|                 trackbook.database.commit() | ||||
|                 handler.removeCallbacks(requery_and_render) | ||||
|                 handler.postDelayed(requery_and_render, RERENDER_DELAY) | ||||
|             } | ||||
|             else if (selection_mode == Keys.SELECTION_MODE_SPATIAL) | ||||
|             { | ||||
|                 // If the user clicked the "when was I here" button to select an area of points, and | ||||
|                 // then presses the Track delete button, we don't want to delete all points between | ||||
|                 // the earliest start and latest stop -- we just want to delete the points that are | ||||
|                 // shown on screen. | ||||
|                 for (trkpt in track.trkpts) | ||||
|                 { | ||||
|                     trackbook.database.delete_trkpt(trkpt) | ||||
|                 } | ||||
|                 trackbook.database.commit() | ||||
|                 handler.removeCallbacks(requery_and_render) | ||||
|                 handler.postDelayed(requery_and_render, RERENDER_DELAY) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue