summaryrefslogtreecommitdiff
path: root/android-app/app/src/main/kotlin
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-03-15 07:39:39 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-03-15 07:39:39 +0000
commita66e96f70b1d46961fc5a3f6324d0d960bc1337b (patch)
tree8ae6e484d176b8bfeccbed121e6b72f384b664d7 /android-app/app/src/main/kotlin
parent9124d1390a0655f62b1de859c2ce0c353c4d9c45 (diff)
fix: rasterise vector drawable for MapLibre; add startup smoke test
Bug: BitmapFactory.decodeResource() returns null for vector drawables (ic_tidal_arrow.xml). style.addImage(id, null) then NPE-crashed inside MapLibre's native layer. The previous style URL was invalid so the setStyle callback never fired and the bug was hidden; fixing the URL in c7b42ab exposed it. Fix: draw the VectorDrawable onto a Canvas to produce a real Bitmap before handing it to MapLibre, matching the pattern already used in MapFragment for the wind-arrow icon. Also adds: - MainActivitySmokeTest: Espresso test that launches MainActivity and asserts it doesn't immediately crash — catches this class of bug. - CI smoke-test job: runs the Espresso test on an API-30 emulator via reactivecircus/android-emulator-runner after the build job passes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'android-app/app/src/main/kotlin')
-rw-r--r--android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt16
1 files changed, 14 insertions, 2 deletions
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 a6c063b..aa35914 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
@@ -2,6 +2,8 @@ package org.terst.nav
import android.Manifest
import android.content.pm.PackageManager
+import android.graphics.Bitmap
+import android.graphics.Canvas
import android.graphics.BitmapFactory
import android.location.Location
import android.media.MediaPlayer
@@ -516,8 +518,18 @@ class MainActivity : AppCompatActivity() {
}
private fun setupTidalCurrentMapLayers(style: Style) {
- // Add tidal arrow icon
- style.addImage(TIDAL_ARROW_ICON_ID, BitmapFactory.decodeResource(resources, R.drawable.ic_tidal_arrow))
+ // Add tidal arrow icon (vector drawable — must rasterise manually; BitmapFactory returns null for VDs)
+ val tidalArrowDrawable = ContextCompat.getDrawable(this, R.drawable.ic_tidal_arrow) ?: return
+ val tidalArrowBitmap = Bitmap.createBitmap(
+ tidalArrowDrawable.intrinsicWidth.coerceAtLeast(24),
+ tidalArrowDrawable.intrinsicHeight.coerceAtLeast(24),
+ Bitmap.Config.ARGB_8888
+ )
+ Canvas(tidalArrowBitmap).also { canvas ->
+ tidalArrowDrawable.setBounds(0, 0, canvas.width, canvas.height)
+ tidalArrowDrawable.draw(canvas)
+ }
+ style.addImage(TIDAL_ARROW_ICON_ID, tidalArrowBitmap)
// Create source
tidalCurrentSource = GeoJsonSource(TIDAL_CURRENT_SOURCE_ID)