From ef28986512f355b4038049b3cc531db794c86941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Thu, 23 Apr 2026 09:50:12 -0400 Subject: [PATCH] GTFS-RT > Trip Updates > Read from source > use `header.timestamp` --- .../commons/provider/gtfs/GtfsRealTimeStorage.kt | 16 ++++++++++++++++ .../status/GTFSRealTimeTripUpdatesProvider.kt | 14 +++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/mtransit/android/commons/provider/gtfs/GtfsRealTimeStorage.kt b/src/main/java/org/mtransit/android/commons/provider/gtfs/GtfsRealTimeStorage.kt index 63f6b8da..907ccf60 100644 --- a/src/main/java/org/mtransit/android/commons/provider/gtfs/GtfsRealTimeStorage.kt +++ b/src/main/java/org/mtransit/android/commons/provider/gtfs/GtfsRealTimeStorage.kt @@ -24,6 +24,22 @@ object GtfsRealTimeStorage { PreferenceUtils.savePrefLclSync(context, PREF_KEY_TRIP_UPDATE_LAST_UPDATE_MS, lastUpdateInMs) } + /** + * Override if multiple {@link GTFSRealTimeDbHelper} implementations in same app. + */ + private const val PREF_KEY_TRIP_UPDATE_READ_FROM_SOURCE_MS = "pGTFSRealTimeTripUpdatesReadFromSource" + + @JvmStatic + @WorkerThread + fun getTripUpdateReadFromSourceMs(context: Context, default: Long) = + PreferenceUtils.getPrefLcl(context, PREF_KEY_TRIP_UPDATE_READ_FROM_SOURCE_MS, default) + + @JvmStatic + @WorkerThread + fun saveTripUpdateReadFromSourceMs(context: Context, readFromSourceMs: Long?) { + PreferenceUtils.savePrefLclSync(context, PREF_KEY_TRIP_UPDATE_READ_FROM_SOURCE_MS, readFromSourceMs) + } + /** * Override if multiple {@link GTFSRealTimeDbHelper} implementations in same app. */ diff --git a/src/main/java/org/mtransit/android/commons/provider/status/GTFSRealTimeTripUpdatesProvider.kt b/src/main/java/org/mtransit/android/commons/provider/status/GTFSRealTimeTripUpdatesProvider.kt index 18980c0f..4434c023 100644 --- a/src/main/java/org/mtransit/android/commons/provider/status/GTFSRealTimeTripUpdatesProvider.kt +++ b/src/main/java/org/mtransit/android/commons/provider/status/GTFSRealTimeTripUpdatesProvider.kt @@ -3,6 +3,7 @@ package org.mtransit.android.commons.provider.status import android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND import android.content.Context import android.util.Log +import com.google.transit.realtime.headerOrNull import org.mtransit.android.commons.Constants import org.mtransit.android.commons.MTLog import org.mtransit.android.commons.SecurityUtils @@ -16,6 +17,7 @@ import org.mtransit.android.commons.data.toNoData import org.mtransit.android.commons.provider.GTFSRealTimeProvider import org.mtransit.android.commons.provider.gtfs.GtfsRealTimeStorage import org.mtransit.android.commons.provider.gtfs.GtfsRealtimeExt.optDirectionIdValid +import org.mtransit.android.commons.provider.gtfs.GtfsRealtimeExt.optTimestampMs import org.mtransit.android.commons.provider.gtfs.GtfsRealtimeExt.optTrip import org.mtransit.android.commons.provider.gtfs.GtfsRealtimeExt.sortTripUpdates import org.mtransit.android.commons.provider.gtfs.GtfsRealtimeExt.toStringExt @@ -112,8 +114,10 @@ object GTFSRealTimeTripUpdatesProvider : MTLog.Loggable { filter: Schedule.ScheduleStatusFilter, tripIds: List ): POIStatus? { - val readFromSourceMs = GtfsRealTimeStorage.getTripUpdateLastUpdateMs(context, 0L) + val lastUpdateInMs = GtfsRealTimeStorage.getTripUpdateLastUpdateMs(context, 0L) .takeIf { it > 0L } ?: return null // never loaded + val readFromSourceMs = GtfsRealTimeStorage.getTripUpdateReadFromSourceMs(context, 0L) + .takeIf { it > 0L } ?: lastUpdateInMs val gTripUpdates = gTripUpdates ?: return null val sourceLabel = SourceUtils.getSourceLabel( // always use source from official API GTFSRealTimeProvider.getAgencyTripUpdatesUrlString(context, "T") @@ -305,7 +309,9 @@ object GTFSRealTimeTripUpdatesProvider : MTLog.Loggable { ?.inputStream() ?.use { inputStream -> try { - GFeedMessage.parseFrom(inputStream) + val gFeedMessage = GFeedMessage.parseFrom(inputStream) + GtfsRealTimeStorage.saveTripUpdateReadFromSourceMs(context, gFeedMessage.headerOrNull?.optTimestampMs) + gFeedMessage .entityList .toTripUpdates() } catch (e: IOException) { @@ -343,7 +349,9 @@ object GTFSRealTimeTripUpdatesProvider : MTLog.Loggable { try { val responseBodyByes = response.body.bytes() File(context.cacheDir, GTFS_RT_TRIP_UPDATE_PB_FILE_NAME).writeBytes(responseBodyByes) - gTripUpdates = GFeedMessage.parseFrom(responseBodyByes).entityList.toTripUpdates() // will be used soon + val gFeedMessage = GFeedMessage.parseFrom(responseBodyByes) + GtfsRealTimeStorage.saveTripUpdateReadFromSourceMs(context, gFeedMessage.headerOrNull?.optTimestampMs) + gTripUpdates = gFeedMessage.entityList.toTripUpdates() // will be used soon @Suppress("SimplifyBooleanWithConstants", "KotlinConstantConditions") if (Constants.DEBUG && PRINT_ALL_LOADED_TRIP_UPDATES) { MTLog.d(LOG_TAG, "loadAgencyDataFromWWW() > GTFS trip updates[${gTripUpdates?.size}]: ")