From a66e96f70b1d46961fc5a3f6324d0d960bc1337b Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Sun, 15 Mar 2026 07:39:39 +0000 Subject: fix: rasterise vector drawable for MapLibre; add startup smoke test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../app/src/main/kotlin/org/terst/nav/MainActivity.kt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'android-app/app/src/main') 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) -- cgit v1.2.3