From a90babf5406ae0a8dbca20c8c5687b6005c1abe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20W=C3=BCrl?= Date: Sat, 18 Jan 2025 00:53:17 +0100 Subject: [PATCH] fix double tap crash and show when out of data range for alert --- app/build.gradle | 4 +- .../android/alert/handler/AlertDataHandler.kt | 12 +++- .../android/data/MainDataHandler.kt | 4 +- .../android/data/beans/GridParameters.kt | 16 +++-- .../org/blitzortung/android/map/OwnMapView.kt | 6 +- .../android/data/GridParametersTest.kt | 61 +++++++++++++++++++ build.gradle | 4 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 8 files changed, 92 insertions(+), 17 deletions(-) create mode 100644 app/src/test/java/org/blitzortung/android/data/GridParametersTest.kt diff --git a/app/build.gradle b/app/build.gradle index 410105bd..e3af465d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { applicationId "org.blitzortung.android.app" minSdkVersion 21 targetSdkVersion 34 - versionCode 327 - versionName '2.3-beta1' + versionCode 328 + versionName '2.3-beta2' multiDexEnabled false testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/org/blitzortung/android/alert/handler/AlertDataHandler.kt b/app/src/main/java/org/blitzortung/android/alert/handler/AlertDataHandler.kt index 5e21f3c0..d98277c1 100644 --- a/app/src/main/java/org/blitzortung/android/alert/handler/AlertDataHandler.kt +++ b/app/src/main/java/org/blitzortung/android/alert/handler/AlertDataHandler.kt @@ -20,9 +20,11 @@ package org.blitzortung.android.alert.handler import android.content.res.Resources import android.location.Location +import android.util.Log import org.blitzortung.android.alert.AlertParameters import org.blitzortung.android.alert.AlertResult import org.blitzortung.android.alert.data.AlertSector +import org.blitzortung.android.app.Main.Companion.LOG_TAG import org.blitzortung.android.data.beans.GridElement import org.blitzortung.android.data.beans.GridParameters import org.blitzortung.android.data.beans.Strike @@ -39,7 +41,13 @@ open class AlertDataHandler @Inject internal constructor( fun checkStrikes( strikes: Strikes, location: Location, parameters: AlertParameters, referenceTime: Long = System.currentTimeMillis() - ): AlertResult { + ): AlertResult? { + val gridParameters: GridParameters? = strikes.gridParameters + if (gridParameters != null && !gridParameters.isGlobal && !gridParameters.contains(location.longitude, location.latitude, 0.2)) { + Log.v(LOG_TAG, "Location $location is not in grid ${gridParameters.longitudeInterval} + ${gridParameters.latitudeInterval}") + return null + } + val sectors = createSectors(parameters) val thresholdTime = referenceTime - parameters.alarmInterval @@ -54,7 +62,7 @@ open class AlertDataHandler @Inject internal constructor( checkStrike( alertSector, strike, - strikes.gridParameters, + gridParameters, parameters.measurementSystem, location, thresholdTime diff --git a/app/src/main/java/org/blitzortung/android/data/MainDataHandler.kt b/app/src/main/java/org/blitzortung/android/data/MainDataHandler.kt index 71919f15..87a97af3 100644 --- a/app/src/main/java/org/blitzortung/android/data/MainDataHandler.kt +++ b/app/src/main/java/org/blitzortung/android/data/MainDataHandler.kt @@ -473,9 +473,9 @@ class MainDataHandler @Inject constructor( } private fun addUpdateAfterAnimationListener(mapView: OwnMapView) { - val animator = mapView.animator()!! + val animator = mapView.animator() - if (!animator.listeners.contains(animatorListener)) { + if (animator != null && !animator.listeners.contains(animatorListener)) { animator.addListener(animatorListener) } } diff --git a/app/src/main/java/org/blitzortung/android/data/beans/GridParameters.kt b/app/src/main/java/org/blitzortung/android/data/beans/GridParameters.kt index a0e1ca9d..1f790abc 100644 --- a/app/src/main/java/org/blitzortung/android/data/beans/GridParameters.kt +++ b/app/src/main/java/org/blitzortung/android/data/beans/GridParameters.kt @@ -50,9 +50,11 @@ data class GridParameters( return latitudeStart - latitudeDelta * (offset + 0.5) } - private val rectLongitudeDelta: Double = longitudeDelta * longitudeBins + val longitudeInterval: Double = longitudeDelta * longitudeBins - private val rectLatitudeDelta: Double = latitudeDelta * latitudeBins + val latitudeInterval: Double = latitudeDelta * latitudeBins + + val isGlobal = longitudeInterval > 350 && latitudeInterval > 170 fun getRect(projection: Projection): RectF { var leftTop = Point() @@ -60,8 +62,8 @@ data class GridParameters( Coordsys.toMapCoords(longitudeStart, latitudeStart), leftTop ) var bottomRight = Point() - val longitudeEnd = longitudeStart + rectLongitudeDelta - val latitudeEnd = latitudeStart - rectLatitudeDelta + val longitudeEnd = longitudeStart + longitudeInterval + val latitudeEnd = latitudeStart - latitudeInterval bottomRight = projection.toPixels( Coordsys.toMapCoords( longitudeEnd, @@ -72,4 +74,10 @@ data class GridParameters( // Log.d(Main.LOG_TAG, "GridParameters.getRect() $longitudeStart - $longitudeEnd ($longitudeDelta, #$longitudeBins) $latitudeEnd - $latitudeStart ($latitudeDelta, #$latitudeBins)") return RectF(leftTop.x.toFloat(), leftTop.y.toFloat(), bottomRight.x.toFloat(), bottomRight.y.toFloat()) } + + fun contains(longitude: Double, latitude: Double, inset: Double = 0.0): Boolean { + val inLongitude = longitude in longitudeStart + inset..longitudeEnd - inset + val inLatitude = latitude in latitudeStart - latitudeDelta * latitudeBins + inset .. latitudeStart - inset + return inLongitude && inLatitude + } } diff --git a/app/src/main/java/org/blitzortung/android/map/OwnMapView.kt b/app/src/main/java/org/blitzortung/android/map/OwnMapView.kt index 3c30b924..11a376d3 100644 --- a/app/src/main/java/org/blitzortung/android/map/OwnMapView.kt +++ b/app/src/main/java/org/blitzortung/android/map/OwnMapView.kt @@ -29,11 +29,8 @@ import android.view.LayoutInflater import android.view.MotionEvent import android.view.View import androidx.appcompat.app.AlertDialog -import androidx.core.animation.doOnCancel -import androidx.core.animation.doOnEnd import androidx.core.view.GestureDetectorCompat import org.blitzortung.android.app.Main -import org.blitzortung.android.app.Main.Companion.LOG_TAG import org.blitzortung.android.app.R import org.blitzortung.android.app.view.PreferenceKey import org.blitzortung.android.location.LocationHandler @@ -113,7 +110,8 @@ class OwnMapView(context: Context) : MapView(context) { if (!isAnimating) return null animatorField.isAccessible = true - return animatorField.get(controller) as ValueAnimator + val value = animatorField.get(controller) + return value?.let { value as ValueAnimator } } companion object { diff --git a/app/src/test/java/org/blitzortung/android/data/GridParametersTest.kt b/app/src/test/java/org/blitzortung/android/data/GridParametersTest.kt new file mode 100644 index 00000000..60fdd731 --- /dev/null +++ b/app/src/test/java/org/blitzortung/android/data/GridParametersTest.kt @@ -0,0 +1,61 @@ +package org.blitzortung.android.data + +import org.assertj.core.api.Assertions.assertThat +import org.blitzortung.android.data.beans.GridParameters +import org.junit.Test + + +class GridParametersTest { + + private val parameters = GridParameters(10.0, 45.0, 0.2, 0.2, 20, 15) + + @Test + fun testRectCenter() { + assertThat(parameters.rectCenterLongitude).isEqualTo(12.0) + assertThat(parameters.rectCenterLatitude).isEqualTo(43.5) + } + + @Test + fun testElementCenter() { + assertThat(parameters.getCenterLongitude(0)).isEqualTo(10.1) + assertThat(parameters.getCenterLatitude(0)).isEqualTo(44.9) + + assertThat(parameters.getCenterLongitude(19)).isEqualTo(13.9) + assertThat(parameters.getCenterLatitude(19)).isEqualTo(41.1) + } + +// @Test +// fun testGetRect() { +// val screenRect = Rect(10, 20, 30, 40) +// val center = GeoPoint(42.5, 12.5) +// val projection = Projection(5.0, screenRect, center, 0.0, 0, 0.0, false, false, null, 0, 0) +// parameters.getRect(projection) +// } + + @Test + fun containsWithoutInset() { + assertThat(parameters.contains(10.0, 42.0)).isTrue + assertThat(parameters.contains(14.0, 42.0)).isTrue + assertThat(parameters.contains(14.0, 45.0)).isTrue + assertThat(parameters.contains(10.0, 45.0)).isTrue + assertThat(parameters.contains(12.0, 43.5)).isTrue + + assertThat(parameters.contains(9.9, 42.0)).isFalse + assertThat(parameters.contains(10.0, 41.9)).isFalse + assertThat(parameters.contains(14.1, 45.0)).isFalse + assertThat(parameters.contains(14.0, 45.1)).isFalse + } + + @Test + fun containsWithPositiveInset() { + assertThat(parameters.contains(10.5, 42.5, 0.5)).isTrue + assertThat(parameters.contains(13.5, 42.5, 0.5)).isTrue + assertThat(parameters.contains(13.5, 44.5, 0.5)).isTrue + assertThat(parameters.contains(10.5, 44.5, 0.5)).isTrue + + assertThat(parameters.contains(10.4, 42.5, 0.5)).isFalse + assertThat(parameters.contains(10.5, 42.4, 0.5)).isFalse + assertThat(parameters.contains(13.6, 44.5, 0.5)).isFalse + assertThat(parameters.contains(13.5, 44.6, 0.5)).isFalse + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 4260f9b1..b42bbb87 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id 'com.android.application' version '8.7.3' apply false - id 'com.android.library' version '8.7.3' apply false + id 'com.android.application' version '8.8.0' apply false + id 'com.android.library' version '8.8.0' apply false id 'org.jetbrains.kotlin.android' version '2.0.20' apply false id "org.sonarqube" version "5.1.0.4882" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 81a4301f..6b74f0f6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip