diff options
Diffstat (limited to 'android-app/app/src')
3 files changed, 44 insertions, 1 deletions
diff --git a/android-app/app/src/main/AndroidManifest.xml b/android-app/app/src/main/AndroidManifest.xml index 7cbafc7..7b9a9e4 100644 --- a/android-app/app/src/main/AndroidManifest.xml +++ b/android-app/app/src/main/AndroidManifest.xml @@ -27,12 +27,18 @@ <activity android:name=".MainActivity" android:exported="true" + android:launchMode="singleTop" android:screenOrientation="portrait" android:configChanges="orientation|screenSize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> + <intent-filter> + <action android:name="android.intent.action.VIEW" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:mimeType="application/gpx+xml" /> + </intent-filter> </activity> </application> </manifest> diff --git a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt index 0df4069..10eb0a8 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt @@ -3,6 +3,10 @@ package org.terst.nav import android.Manifest import android.content.Intent import android.content.pm.PackageManager +import android.util.Log +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.terst.nav.track.GpxParser import android.graphics.Bitmap import android.graphics.Canvas import android.media.MediaPlayer @@ -127,6 +131,30 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener { unitPrefs = UnitPrefs(this) checkForegroundPermissions() initializeUI() + handleIncomingGpx(intent) + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + handleIncomingGpx(intent) + } + + private fun handleIncomingGpx(intent: Intent?) { + if (intent?.action != Intent.ACTION_VIEW) return + val uri = intent.data ?: return + lifecycleScope.launch { + runCatching { + val points = withContext(Dispatchers.IO) { + contentResolver.openInputStream(uri)?.use { GpxParser.parse(it) } ?: emptyList() + } + if (points.isNotEmpty()) { + viewModel.addImportedTrack(points) + showOverlay(SavedTracksFragment()) + } + }.onFailure { e -> + Log.e("MainActivity", "Failed to open GPX: ${e.message}") + } + } } private fun initializeUI() { @@ -242,7 +270,8 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener { showOverlay(SavedTracksFragment()) bottomSheetBehavior.isHideable = true bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN - bottomNav.selectedItemId = R.id.nav_map // keep map tab highlighted + // Note: do NOT set selectedItemId here — it triggers the nav listener + // which calls hideOverlays(), immediately undoing showOverlay(). } } diff --git a/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt b/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt index cc51dd1..dcbd98e 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/ui/MainViewModel.kt @@ -18,6 +18,7 @@ import org.terst.nav.track.SavedTrack import org.terst.nav.track.TrackPoint import org.terst.nav.track.TrackRepository import org.terst.nav.track.TrackStats +import org.terst.nav.track.toSavedTrack import org.terst.nav.settings.FeatureFlags import org.terst.nav.settings.HardwareSource import org.terst.nav.vessel.CrewMember @@ -410,6 +411,13 @@ class MainViewModel( fun selectTrack(track: SavedTrack) { _selectedTrack.value = track } fun clearSelectedTrack() { _selectedTrack.value = null } + /** Adds a track parsed from an external GPX file (not persisted to storage). */ + fun addImportedTrack(points: List<TrackPoint>) { + val updated = _pastTracks.value.toMutableList().also { it.add(0, points) } + _pastTracks.value = updated + _savedTracks.value = updated.filter { it.isNotEmpty() }.map { it.toSavedTrack() } + } + fun panToTrackPoint(lat: Double, lon: Double) { viewModelScope.launch { _panToPosition.emit(lat to lon) } } |
