Compare commits
No commits in common. "a27b8713a9d59596ef4e44f0a505c60e4b14340f" and "c6a0212fb8cac76a6925ab25fed500b03c521d14" have entirely different histories.
a27b8713a9
...
c6a0212fb8
6 changed files with 62 additions and 69 deletions
|
|
@ -9,27 +9,23 @@ import java.io.File
|
|||
class Database(val trackbook: Trackbook)
|
||||
{
|
||||
var ready: Boolean = false
|
||||
var ready_at: Long = 0
|
||||
lateinit var file: File
|
||||
lateinit var connection: SQLiteDatabase
|
||||
|
||||
fun close()
|
||||
{
|
||||
Log.i("VOUSSOIR", "Database.close")
|
||||
this.connection.close()
|
||||
this.ready = false
|
||||
this.ready_at = 0
|
||||
this.trackbook.call_database_changed_listeners()
|
||||
}
|
||||
|
||||
fun connect(file: File)
|
||||
{
|
||||
Log.i("VOUSSOIR", "Database.connect: " + file.absolutePath)
|
||||
Log.i("VOUSSOIR", "Connecting to database " + file.absolutePath)
|
||||
this.file = file
|
||||
this.connection = openOrCreateDatabase(file, null)
|
||||
this.initialize_tables()
|
||||
this.ready = true
|
||||
this.ready_at = System.currentTimeMillis()
|
||||
Log.i("VOUSSOIR", "Database.open: Calling all listeners")
|
||||
}
|
||||
|
||||
|
|
@ -56,21 +52,29 @@ class Database(val trackbook: Trackbook)
|
|||
this.connection.endTransaction()
|
||||
}
|
||||
|
||||
fun delete_trkpt(device_id: String, time: Long)
|
||||
fun delete_trkpt(device_id: String, time: Long, commit: Boolean=false)
|
||||
{
|
||||
Log.i("VOUSSOIR", "Database.delete_trkpt")
|
||||
begin_transaction()
|
||||
connection.delete("trkpt", "device_id = ? AND time = ?", arrayOf(device_id, time.toString()))
|
||||
if (commit)
|
||||
{
|
||||
this.commit()
|
||||
}
|
||||
}
|
||||
|
||||
fun delete_trkpt_start_end(device_id: String, start_time: Long, end_time: Long)
|
||||
fun delete_trkpt_start_end(device_id: String, start_time: Long, end_time: Long, commit: Boolean=false)
|
||||
{
|
||||
Log.i("VOUSSOIR", "Track.delete ${device_id} ${start_time} -- ${end_time}.")
|
||||
this.begin_transaction()
|
||||
this.connection.delete("trkpt", "device_id = ? AND time >= ? AND time <= ?", arrayOf(device_id, start_time.toString(), end_time.toString()))
|
||||
if (commit)
|
||||
{
|
||||
this.commit()
|
||||
}
|
||||
}
|
||||
|
||||
fun insert_trkpt(trkpt: Trkpt)
|
||||
fun insert_trkpt(trkpt: Trkpt, commit: Boolean=false)
|
||||
{
|
||||
Log.i("VOUSSOIR", "Database.insert_trkpt")
|
||||
val values = ContentValues().apply {
|
||||
|
|
@ -85,6 +89,10 @@ class Database(val trackbook: Trackbook)
|
|||
}
|
||||
begin_transaction()
|
||||
connection.insert("trkpt", null, values)
|
||||
if (commit)
|
||||
{
|
||||
this.commit()
|
||||
}
|
||||
}
|
||||
|
||||
fun select_trkpt_start_end(device_id: String, start_time: Long, end_time: Long, max_accuracy: Float=Keys.DEFAULT_MAX_ACCURACY, order: String="ASC"): Iterator<Trkpt>
|
||||
|
|
@ -148,14 +156,18 @@ class Database(val trackbook: Trackbook)
|
|||
}
|
||||
}
|
||||
|
||||
fun delete_homepoint(id: Long)
|
||||
fun delete_homepoint(id: Long, commit: Boolean=false)
|
||||
{
|
||||
Log.i("VOUSSOIR", "Database.delete_homepoint")
|
||||
begin_transaction()
|
||||
connection.delete("homepoints", "id = ?", arrayOf(id.toString()))
|
||||
if (commit)
|
||||
{
|
||||
this.commit()
|
||||
}
|
||||
}
|
||||
|
||||
fun insert_homepoint(id: Long, name: String, latitude: Double, longitude: Double, radius: Double)
|
||||
fun insert_homepoint(id: Long, name: String, latitude: Double, longitude: Double, radius: Double, commit: Boolean=false)
|
||||
{
|
||||
Log.i("VOUSSOIR", "Database.insert_homepoint")
|
||||
val values = ContentValues().apply {
|
||||
|
|
@ -167,9 +179,13 @@ class Database(val trackbook: Trackbook)
|
|||
}
|
||||
begin_transaction()
|
||||
connection.insert("homepoints", null, values)
|
||||
if (commit)
|
||||
{
|
||||
this.commit()
|
||||
}
|
||||
}
|
||||
|
||||
fun update_homepoint(id: Long, name: String, radius: Double)
|
||||
fun update_homepoint(id: Long, name: String, radius: Double, commit: Boolean=false)
|
||||
{
|
||||
Log.i("VOUSSOIR", "Database.update_homepoint")
|
||||
val values = ContentValues().apply {
|
||||
|
|
@ -178,9 +194,13 @@ class Database(val trackbook: Trackbook)
|
|||
}
|
||||
begin_transaction()
|
||||
connection.update("homepoints", values, "id = ?", arrayOf(id.toString()))
|
||||
if (commit)
|
||||
{
|
||||
this.commit()
|
||||
}
|
||||
}
|
||||
|
||||
fun update_trkpt(trkpt: Trkpt)
|
||||
fun update_trkpt(trkpt: Trkpt, commit: Boolean=false)
|
||||
{
|
||||
Log.i("VOUSSOIR", "Database.update_trkpt")
|
||||
val values = ContentValues().apply {
|
||||
|
|
@ -193,11 +213,14 @@ class Database(val trackbook: Trackbook)
|
|||
}
|
||||
begin_transaction()
|
||||
connection.update("trkpt", values, "device_id = ? AND time = ?", arrayOf(trkpt.device_id, trkpt.time.toString()))
|
||||
if (commit)
|
||||
{
|
||||
this.commit()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initialize_tables()
|
||||
{
|
||||
Log.i("VOUSSOIR", "Database.initialize_tables")
|
||||
begin_transaction()
|
||||
this.connection.execSQL("CREATE TABLE IF NOT EXISTS meta(name TEXT PRIMARY KEY, value TEXT)")
|
||||
this.connection.execSQL("CREATE TABLE IF NOT EXISTS trkpt(device_id INTEGER NOT NULL, time INTEGER NOT NULL, lat REAL NOT NULL, lon REAL NOT NULL, provider TEXT, accuracy REAL, ele INTEGER, sat INTEGER, PRIMARY KEY(device_id, time))")
|
||||
|
|
|
|||
|
|
@ -168,8 +168,8 @@ class MapFragment : Fragment()
|
|||
latitude=point.latitude,
|
||||
longitude=point.longitude,
|
||||
radius=radius,
|
||||
commit=true,
|
||||
)
|
||||
trackbook.database.commit()
|
||||
trackbook.load_homepoints()
|
||||
create_homepoint_overlays()
|
||||
dialog.dismiss()
|
||||
|
|
@ -548,16 +548,14 @@ class MapFragment : Fragment()
|
|||
val save_button: Button = dialog.findViewById(R.id.homepoint_save_button)
|
||||
delete_button.text = "Delete"
|
||||
delete_button.setOnClickListener {
|
||||
trackbook.database.delete_homepoint(homepoint.id)
|
||||
trackbook.database.commit()
|
||||
trackbook.database.delete_homepoint(homepoint.id, commit=true)
|
||||
trackbook.load_homepoints()
|
||||
create_homepoint_overlays()
|
||||
dialog.dismiss()
|
||||
}
|
||||
save_button.setOnClickListener {
|
||||
val radius = radius_input.text.toString().toDoubleOrNull() ?: 25.0
|
||||
trackbook.database.update_homepoint(homepoint.id, name=name_input.text.toString(), radius=radius)
|
||||
trackbook.database.commit()
|
||||
trackbook.database.update_homepoint(homepoint.id, name=name_input.text.toString(), radius=radius, commit=true)
|
||||
trackbook.load_homepoints()
|
||||
create_homepoint_overlays()
|
||||
dialog.dismiss()
|
||||
|
|
@ -672,12 +670,11 @@ class MapFragment : Fragment()
|
|||
state: ${state_name()}
|
||||
clock: ${iso8601_local_noms(System.currentTimeMillis())}
|
||||
location: ${iso8601_local_noms(tracker.currentBestLocation.time)}
|
||||
database: ${iso8601_local_noms(trackbook.database.ready_at)}
|
||||
listeners: ${iso8601_local_noms(tracker.listeners_enabled_at)}
|
||||
motion: ${iso8601_local_noms(tracker.last_significant_motion)}
|
||||
watchdog: ${iso8601_local_noms(tracker.last_watchdog)}
|
||||
home: ${iso8601_local_noms(tracker.arrived_at_home)}
|
||||
died: ${iso8601_local_noms(tracker.dead_at)}
|
||||
died: ${iso8601_local_noms(tracker.gave_up_at)}
|
||||
power: ${tracker.device_is_charging}
|
||||
wakelock: ${tracker.wakelock.isHeld}
|
||||
accuracy: ${accuracy_text} m
|
||||
|
|
|
|||
|
|
@ -97,9 +97,8 @@ data class Track (
|
|||
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"
|
||||
>
|
||||
""".trimIndent())
|
||||
val name_escaped = this.name.replace("&", "&").replace("<", "<").replace(">", ">")
|
||||
write("\t<metadata>")
|
||||
write("\t\t<name>${name_escaped}</name>")
|
||||
write("\t\t<name>${this.name}</name>")
|
||||
write("\t\t<application>${BuildConfig.APPLICATION_ID} ${BuildConfig.VERSION_NAME}</application>")
|
||||
write("\t\t<device>${this.device_id}</device>")
|
||||
write("\t</metadata>")
|
||||
|
|
|
|||
|
|
@ -271,8 +271,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.commit()
|
||||
trackbook.database.delete_trkpt(selected.device_id, selected.time, commit=true)
|
||||
deselect_trkpt()
|
||||
mapView.invalidate()
|
||||
}
|
||||
|
|
@ -455,10 +454,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
|
|||
}
|
||||
override fun onMarkerDragEnd(marker: Marker?)
|
||||
{
|
||||
selected_trkpt?.let {
|
||||
trackbook.database.update_trkpt(it)
|
||||
trackbook.database.commit()
|
||||
}
|
||||
selected_trkpt?.let { trackbook.database.update_trkpt(it, commit=true) }
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -635,8 +631,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
|
|||
mid_location.accuracy = 0f
|
||||
val mid_trkpt = Trkpt(trkpt.device_id, mid_location)
|
||||
deselect_trkpt()
|
||||
trackbook.database.insert_trkpt(mid_trkpt)
|
||||
trackbook.database.commit()
|
||||
trackbook.database.insert_trkpt(mid_trkpt, commit=true)
|
||||
requery_and_render.run()
|
||||
select_trkpt_by_timestamp(mid_trkpt.time)
|
||||
return
|
||||
|
|
@ -700,7 +695,7 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
|
|||
trkpt.latitude = new_location.latitude
|
||||
trkpt.longitude = new_location.longitude
|
||||
trkpt.altitude = a.altitude + (ele_span * proportion)
|
||||
trackbook.database.update_trkpt(trkpt)
|
||||
trackbook.database.update_trkpt(trkpt, commit=false)
|
||||
}
|
||||
trackbook.database.commit()
|
||||
}
|
||||
|
|
@ -867,8 +862,8 @@ class TrackFragment : Fragment(), MapListener, YesNoDialog.YesNoDialogListener
|
|||
track.device_id,
|
||||
track.trkpts.first().time,
|
||||
track.trkpts.last().time,
|
||||
commit=true,
|
||||
)
|
||||
trackbook.database.commit()
|
||||
handler.removeCallbacks(requery_and_render)
|
||||
handler.postDelayed(requery_and_render, RERENDER_DELAY)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,22 +68,19 @@ class Trackbook : Application()
|
|||
{
|
||||
Log.i("VOUSSOIR", "Trackbook.load_database")
|
||||
val folder = PreferencesHelper.load_database_folder()
|
||||
this.database.commit()
|
||||
if (this.database.ready)
|
||||
{
|
||||
Log.i("VOUSSOIR", "Trackbook.load_database: closing and re-opening.")
|
||||
this.database.commit()
|
||||
this.database.close()
|
||||
}
|
||||
if (folder == "")
|
||||
{
|
||||
Log.i("VOUSSOIR", "Trackbook.load_database: folder came up blank.")
|
||||
this.database.ready = false
|
||||
return
|
||||
}
|
||||
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
val device_id = PreferencesHelper.load_device_id()
|
||||
this.database.connect(File(folder + "/trkpt_${device_id}.db"))
|
||||
this.database.connect(File(folder + "/trkpt_${PreferencesHelper.load_device_id()}.db"))
|
||||
this.load_homepoints()
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -56,8 +56,7 @@ class TrackerService: Service()
|
|||
var listeners_enabled_at: Long = 0
|
||||
var last_significant_motion: Long = 0
|
||||
var last_watchdog: Long = 0
|
||||
var dead_at: Long = 0
|
||||
var dead_reason: String = ""
|
||||
var gave_up_at: Long = 0
|
||||
var arrived_at_home: Long = 0
|
||||
val TIME_UNTIL_SLEEP: Long = 5 * Keys.ONE_MINUTE_IN_MILLISECONDS
|
||||
val TIME_UNTIL_DEAD: Long = 3 * Keys.ONE_MINUTE_IN_MILLISECONDS
|
||||
|
|
@ -186,7 +185,7 @@ class TrackerService: Service()
|
|||
Keys.STATE_FULL_RECORDING -> state_full_recording()
|
||||
Keys.STATE_ARRIVED_AT_HOME -> state_arrived_at_home()
|
||||
Keys.STATE_SLEEP -> state_sleep()
|
||||
Keys.STATE_DEAD -> state_dead(dead_reason="Loaded previous state")
|
||||
Keys.STATE_DEAD -> state_dead()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -201,8 +200,7 @@ class TrackerService: Service()
|
|||
trackbook.database.commit()
|
||||
recent_displacement_locations.clear()
|
||||
arrived_at_home = 0
|
||||
dead_at = 0
|
||||
dead_reason = ""
|
||||
gave_up_at = 0
|
||||
if (foreground_started > 0)
|
||||
{
|
||||
stopForeground(STOP_FOREGROUND_DETACH)
|
||||
|
|
@ -217,17 +215,11 @@ class TrackerService: Service()
|
|||
// at full power. A wakelock is used to resist Android's doze. This state should be active
|
||||
// while out and about.
|
||||
Log.i("VOUSSOIR", "TrackerService.state_full_power")
|
||||
if (! trackbook.database.ready)
|
||||
{
|
||||
state_dead("Database not ready")
|
||||
}
|
||||
trackbook.load_database()
|
||||
tracking_state = Keys.STATE_FULL_RECORDING
|
||||
PreferencesHelper.saveTrackingState(tracking_state)
|
||||
reset_location_listeners(Keys.LOCATION_INTERVAL_FULL_POWER)
|
||||
arrived_at_home = 0
|
||||
dead_at = 0
|
||||
dead_reason = ""
|
||||
gave_up_at = 0
|
||||
if (foreground_started == 0L)
|
||||
{
|
||||
startForeground(Keys.TRACKER_SERVICE_NOTIFICATION_ID, displayNotification())
|
||||
|
|
@ -239,7 +231,7 @@ class TrackerService: Service()
|
|||
}
|
||||
else
|
||||
{
|
||||
state_dead("No listeners enabled")
|
||||
state_dead()
|
||||
}
|
||||
displayNotification()
|
||||
}
|
||||
|
|
@ -253,8 +245,7 @@ class TrackerService: Service()
|
|||
reset_location_listeners(Keys.LOCATION_INTERVAL_FULL_POWER)
|
||||
trackbook.database.commit()
|
||||
arrived_at_home = System.currentTimeMillis()
|
||||
dead_at = 0
|
||||
dead_reason = ""
|
||||
gave_up_at = 0
|
||||
stop_wakelock()
|
||||
displayNotification()
|
||||
}
|
||||
|
|
@ -267,12 +258,11 @@ class TrackerService: Service()
|
|||
PreferencesHelper.saveTrackingState(tracking_state)
|
||||
reset_location_listeners(Keys.LOCATION_INTERVAL_SLEEP)
|
||||
arrived_at_home = arrived_at_home
|
||||
dead_at = 0
|
||||
dead_reason = ""
|
||||
gave_up_at = 0
|
||||
stop_wakelock()
|
||||
displayNotification()
|
||||
}
|
||||
fun state_dead(dead_reason: String)
|
||||
fun state_dead()
|
||||
{
|
||||
// This state is activated when the device is struggling to receive a GPS fix due to being
|
||||
// indoors / underground. It will be woken up again by the accelerometers or by plugging /
|
||||
|
|
@ -284,8 +274,7 @@ class TrackerService: Service()
|
|||
trackbook.database.commit()
|
||||
recent_displacement_locations.clear()
|
||||
arrived_at_home = 0
|
||||
dead_at = System.currentTimeMillis()
|
||||
this.dead_reason = dead_reason
|
||||
gave_up_at = System.currentTimeMillis()
|
||||
stop_wakelock()
|
||||
displayNotification()
|
||||
}
|
||||
|
|
@ -298,13 +287,12 @@ class TrackerService: Service()
|
|||
PreferencesHelper.saveTrackingState(tracking_state)
|
||||
reset_location_listeners(Keys.LOCATION_INTERVAL_FULL_POWER)
|
||||
arrived_at_home = 0
|
||||
dead_at = 0
|
||||
dead_reason = ""
|
||||
gave_up_at = 0
|
||||
stop_wakelock()
|
||||
displayNotification()
|
||||
if (!gpsLocationListenerRegistered && !networkLocationListenerRegistered)
|
||||
{
|
||||
state_dead(dead_reason="No listeners enabled")
|
||||
state_dead()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -377,8 +365,7 @@ class TrackerService: Service()
|
|||
|
||||
if(! trackbook.database.ready)
|
||||
{
|
||||
Log.i("VOUSSOIR", "TrackerService.onLocationChanged: database is not ready!!.")
|
||||
state_dead(dead_reason="Database not ready")
|
||||
Log.i("VOUSSOIR", "Omitting due to database not ready.")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -462,7 +449,7 @@ class TrackerService: Service()
|
|||
}
|
||||
|
||||
val trkpt = Trkpt(device_id=device_id, location=location)
|
||||
trackbook.database.insert_trkpt(trkpt)
|
||||
trackbook.database.insert_trkpt(trkpt, commit=false)
|
||||
|
||||
if (trkpt.accuracy <= max_accuracy)
|
||||
{
|
||||
|
|
@ -516,31 +503,26 @@ class TrackerService: Service()
|
|||
if (tracking_state == Keys.STATE_FULL_RECORDING)
|
||||
{
|
||||
notification_builder.setContentTitle("${timestamp} (recording)")
|
||||
notification_builder.setContentText(null)
|
||||
notification_builder.setSmallIcon(R.drawable.ic_satellite_24dp)
|
||||
}
|
||||
else if (tracking_state == Keys.STATE_ARRIVED_AT_HOME)
|
||||
{
|
||||
notification_builder.setContentTitle("${timestamp} (home)")
|
||||
notification_builder.setContentText(null)
|
||||
notification_builder.setSmallIcon(R.drawable.ic_homepoint_24dp)
|
||||
}
|
||||
else if (tracking_state == Keys.STATE_SLEEP)
|
||||
{
|
||||
notification_builder.setContentTitle("${timestamp} (sleeping)")
|
||||
notification_builder.setContentText(null)
|
||||
notification_builder.setSmallIcon(R.drawable.ic_sleep_24dp)
|
||||
}
|
||||
else if (tracking_state == Keys.STATE_DEAD)
|
||||
{
|
||||
notification_builder.setContentTitle("${timestamp} (dead)")
|
||||
notification_builder.setContentText(dead_reason)
|
||||
notification_builder.setSmallIcon(R.drawable.ic_skull_24dp)
|
||||
}
|
||||
else if (tracking_state == Keys.STATE_STOP || tracking_state == Keys.STATE_MAPVIEW)
|
||||
{
|
||||
notification_builder.setContentTitle("${timestamp} (stopped)")
|
||||
notification_builder.setContentText(null)
|
||||
notification_builder.setSmallIcon(R.drawable.ic_fiber_manual_stop_24dp)
|
||||
}
|
||||
|
||||
|
|
@ -850,7 +832,7 @@ class TrackerService: Service()
|
|||
(now - last_significant_motion) > TIME_UNTIL_DEAD
|
||||
)
|
||||
{
|
||||
state_dead(dead_reason="No GPS reception")
|
||||
state_dead()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue