summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-05-12 13:47:05 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-05-12 13:47:05 -1000
commitc30e5089d6e0e30dd9b8c3e6164bd065f393dd7e (patch)
treee5d413bcdacfb29a4a421f0203ed9d647f2f670e
parentf881a1f91f4e9f832ab987fce2b5220e100cee68 (diff)
fix(track): broaden MediaStore query to find saved GPX files
RELATIVE_PATH equality matching was returning 0 rows — MediaStore normalises the path differently across Android versions and devices. DISPLAY_NAME LIKE nav_%.gpx is unique enough on its own. Also log path + IS_PENDING per found file to aid future diagnosis. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/track/TrackStorage.kt24
1 files changed, 17 insertions, 7 deletions
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 7e9064c..4147128 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
@@ -114,10 +114,16 @@ class TrackStorage(private val context: Context) {
private fun loadViaMediaStore(): List<List<TrackPoint>> {
val tracks = mutableListOf<List<TrackPoint>>()
val uri = MediaStore.Files.getContentUri("external")
- val projection = arrayOf(MediaStore.Files.FileColumns._ID)
- val selection = "${MediaStore.Files.FileColumns.RELATIVE_PATH} = ? " +
- "AND ${MediaStore.Files.FileColumns.DISPLAY_NAME} LIKE ?"
- val args = arrayOf("Documents/Nav/", "nav_%.gpx")
+ val projection = arrayOf(
+ MediaStore.Files.FileColumns._ID,
+ MediaStore.Files.FileColumns.RELATIVE_PATH,
+ MediaStore.MediaColumns.IS_PENDING
+ )
+ // Do NOT filter by RELATIVE_PATH — equality matching is fragile across
+ // Android versions and devices (trailing-slash normalisation, volume prefix,
+ // etc.). The display-name pattern is specific enough on its own.
+ val selection = "${MediaStore.Files.FileColumns.DISPLAY_NAME} LIKE ?"
+ val args = arrayOf("nav_%.gpx")
val cursor = runCatching {
context.contentResolver.query(uri, projection, selection, args, null)
@@ -126,11 +132,15 @@ class TrackStorage(private val context: Context) {
}.getOrNull()
NavLogger.i("track", "loadViaMediaStore: cursor=${cursor?.count ?: "null"} rows")
cursor?.use { c ->
- val idCol = c.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID)
+ val idCol = c.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID)
+ val pathCol = c.getColumnIndex(MediaStore.Files.FileColumns.RELATIVE_PATH)
+ val pendingCol = c.getColumnIndex(MediaStore.MediaColumns.IS_PENDING)
while (c.moveToNext()) {
- val id = c.getLong(idCol)
+ val id = c.getLong(idCol)
+ val path = if (pathCol >= 0) c.getString(pathCol) else "?"
+ val pending = if (pendingCol >= 0) c.getInt(pendingCol) else -1
val fileUri = android.net.Uri.withAppendedPath(uri, id.toString())
- NavLogger.i("track", "loadViaMediaStore: parsing id=$id uri=$fileUri")
+ NavLogger.i("track", "loadViaMediaStore: id=$id path=$path pending=$pending")
runCatching {
val stream = context.contentResolver.openInputStream(fileUri)
if (stream == null) {