summaryrefslogtreecommitdiff
path: root/android-app/app/src
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-04-13 04:13:47 +0000
committerClaude <noreply@anthropic.com>2026-04-13 04:13:47 +0000
commit23ca7ead82bb92f39467babfad6d89f4300516bb (patch)
tree02f81afb928c9b97779db709254a1a92ac033b2a /android-app/app/src
parent888dcf5283b92eb6feb1ff35451f357359daab74 (diff)
Wire NavLogger into track save/load pipeline
TrackStorage now writes to NavLogger at every decision point: - Before MediaStore insert (shows the filename being written) - Successful save: "saved nav_<ts>.gpx (N bytes) → <uri>" - Every failure path: storage not mounted, insert null, openOutputStream null, write exception, load parse error - After loadViaMediaStore: count of tracks found TrackRepository logs stopTrack summary (pts / duration / distance) and explicitly logs when saveTrack returns false. Long-press the drag handle after injecting a test track to see exactly where the save pipeline breaks. https://claude.ai/code/session_01HXPjBsogsJVRwCiekDGkJX
Diffstat (limited to 'android-app/app/src')
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/track/TrackRepository.kt7
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/track/TrackStorage.kt20
2 files changed, 21 insertions, 6 deletions
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/track/TrackRepository.kt b/android-app/app/src/main/kotlin/org/terst/nav/track/TrackRepository.kt
index 7ef67af..54bf8e6 100644
--- a/android-app/app/src/main/kotlin/org/terst/nav/track/TrackRepository.kt
+++ b/android-app/app/src/main/kotlin/org/terst/nav/track/TrackRepository.kt
@@ -4,6 +4,7 @@ import android.content.Context
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
+import org.terst.nav.ui.NavLogger
class TrackRepository(context: Context) {
@@ -45,9 +46,13 @@ class TrackRepository(context: Context) {
// Discard tracks shorter than 2 minutes — likely accidental taps
if (summary.durationMs < 2 * 60_000L) return@withContext null
+ NavLogger.i("track", "stopTrack: ${points.size} pts dur=${summary.durationMs / 60_000}min dist=%.2fnm".format(summary.distanceNm))
_pastTracks.add(0, points)
val saved = storage.saveTrack(points, trackStartMs)
- if (!saved) Log.e("TrackRepository", "GPX save failed — ${points.size} points will be lost on restart")
+ if (!saved) {
+ Log.e("TrackRepository", "GPX save failed — ${points.size} points will be lost on restart")
+ NavLogger.e("track", "saveTrack returned false — ${points.size} pts lost on restart")
+ }
summary
}
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/track/TrackStorage.kt b/android-app/app/src/main/kotlin/org/terst/nav/track/TrackStorage.kt
index 08e1dc9..3a04688 100644
--- a/android-app/app/src/main/kotlin/org/terst/nav/track/TrackStorage.kt
+++ b/android-app/app/src/main/kotlin/org/terst/nav/track/TrackStorage.kt
@@ -6,6 +6,7 @@ import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.util.Log
+import org.terst.nav.ui.NavLogger
import java.io.File
import java.time.Instant
import java.time.ZoneOffset
@@ -62,7 +63,8 @@ class TrackStorage(private val context: Context) {
// Guard: external storage must be mounted before touching MediaStore
val storageState = Environment.getExternalStorageState()
if (storageState != Environment.MEDIA_MOUNTED) {
- Log.e(TAG, "External storage not mounted (state=$storageState) — cannot save $fileName")
+ val msg = "storage not mounted (state=$storageState) — cannot save $fileName"
+ Log.e(TAG, msg); NavLogger.e("track", msg)
return false
}
@@ -75,10 +77,12 @@ class TrackStorage(private val context: Context) {
put(MediaStore.Files.FileColumns.RELATIVE_PATH, "Documents/Nav/")
put(MediaStore.MediaColumns.IS_PENDING, 1)
}
+ NavLogger.i("track", "MediaStore insert → Documents/Nav/$fileName")
val uri = context.contentResolver.insert(
MediaStore.Files.getContentUri("external"), values
) ?: run {
- Log.e(TAG, "MediaStore insert returned null for $fileName")
+ val msg = "MediaStore insert returned null for $fileName"
+ Log.e(TAG, msg); NavLogger.e("track", msg)
return false
}
@@ -86,7 +90,8 @@ class TrackStorage(private val context: Context) {
val stream = context.contentResolver.openOutputStream(uri)
if (stream == null) {
context.contentResolver.delete(uri, null, null)
- Log.e(TAG, "openOutputStream null for $fileName — deleted orphan entry")
+ val msg = "openOutputStream null for $fileName — deleted orphan entry"
+ Log.e(TAG, msg); NavLogger.e("track", msg)
return@runCatching false
}
stream.use { it.write(gpx.toByteArray()) }
@@ -95,10 +100,12 @@ class TrackStorage(private val context: Context) {
val update = ContentValues().apply { put(MediaStore.MediaColumns.IS_PENDING, 0) }
context.contentResolver.update(uri, update, null, null)
- Log.d(TAG, "Saved $fileName (${gpx.length} bytes) → $uri")
+ val msg = "saved $fileName (${gpx.length} bytes) → $uri"
+ Log.d(TAG, msg); NavLogger.i("track", msg)
true
}.getOrElse { e ->
- Log.e(TAG, "Write failed for $fileName: ${e.message}")
+ val msg = "write failed for $fileName: ${e.javaClass.simpleName}: ${e.message}"
+ Log.e(TAG, msg); NavLogger.e("track", msg)
runCatching { context.contentResolver.delete(uri, null, null) }
false
}
@@ -121,9 +128,12 @@ class TrackStorage(private val context: Context) {
val points = GpxParser.parse(stream)
if (points.isNotEmpty()) tracks.add(points)
}
+ }.onFailure { e ->
+ NavLogger.e("track", "load parse error: ${e.javaClass.simpleName}: ${e.message}")
}
}
}
+ NavLogger.i("track", "loadViaMediaStore: ${tracks.size} tracks found")
return tracks
}