expo-gaode-map-navigation 1.1.5 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/README.md +213 -73
  2. package/android/build.gradle +10 -0
  3. package/android/src/main/cpp/CMakeLists.txt +24 -0
  4. package/android/src/main/cpp/cluster_jni.cpp +848 -0
  5. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapModule.kt +616 -92
  6. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapOfflineModule.kt +493 -0
  7. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapView.kt +230 -14
  8. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapViewModule.kt +37 -27
  9. package/android/src/main/java/expo/modules/gaodemap/map/MapPreloadManager.kt +494 -0
  10. package/android/src/main/java/expo/modules/gaodemap/map/companion/BitmapDescriptorCache.kt +30 -0
  11. package/android/src/main/java/expo/modules/gaodemap/map/companion/IconBitmapCache.kt +37 -0
  12. package/android/src/main/java/expo/modules/gaodemap/map/managers/UIManager.kt +76 -0
  13. package/android/src/main/java/expo/modules/gaodemap/map/modules/LocationManager.kt +15 -3
  14. package/android/src/main/java/expo/modules/gaodemap/map/modules/SDKInitializer.kt +4 -59
  15. package/android/src/main/java/expo/modules/gaodemap/map/overlays/CircleView.kt +9 -12
  16. package/android/src/main/java/expo/modules/gaodemap/map/overlays/CircleViewModule.kt +5 -6
  17. package/android/src/main/java/expo/modules/gaodemap/map/overlays/ClusterView.kt +539 -66
  18. package/android/src/main/java/expo/modules/gaodemap/map/overlays/ClusterViewModule.kt +17 -1
  19. package/android/src/main/java/expo/modules/gaodemap/map/overlays/HeatMapView.kt +165 -33
  20. package/android/src/main/java/expo/modules/gaodemap/map/overlays/HeatMapViewModule.kt +15 -3
  21. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerView.kt +1249 -672
  22. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerViewModule.kt +40 -17
  23. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MultiPointView.kt +177 -22
  24. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MultiPointViewModule.kt +11 -3
  25. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolygonView.kt +57 -14
  26. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolygonViewModule.kt +9 -5
  27. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolylineView.kt +90 -63
  28. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolylineViewModule.kt +7 -3
  29. package/android/src/main/java/expo/modules/gaodemap/map/services/LocationForegroundService.kt +3 -2
  30. package/android/src/main/java/expo/modules/gaodemap/map/utils/BitmapDescriptorCache.kt +20 -0
  31. package/android/src/main/java/expo/modules/gaodemap/map/utils/ClusterNative.kt +13 -0
  32. package/android/src/main/java/expo/modules/gaodemap/map/utils/ColorParser.kt +20 -0
  33. package/android/src/main/java/expo/modules/gaodemap/map/utils/GeometryUtils.kt +515 -0
  34. package/android/src/main/java/expo/modules/gaodemap/map/utils/LatLngParser.kt +91 -0
  35. package/android/src/main/java/expo/modules/gaodemap/map/utils/PermissionHelper.kt +248 -0
  36. package/build/ExpoGaodeMapNaviView.d.ts +7 -7
  37. package/build/ExpoGaodeMapNaviView.js +10 -11
  38. package/build/ExpoGaodeMapNavigationModule.d.ts +2 -1
  39. package/build/index.d.ts +35 -33
  40. package/build/index.js +70 -106
  41. package/build/map/ExpoGaodeMapModule.d.ts +2 -201
  42. package/build/map/ExpoGaodeMapModule.js +586 -18
  43. package/build/map/ExpoGaodeMapOfflineModule.d.ts +139 -0
  44. package/build/map/ExpoGaodeMapOfflineModule.js +8 -0
  45. package/build/map/ExpoGaodeMapView.js +66 -58
  46. package/build/map/components/FoldableMapView.d.ts +38 -0
  47. package/build/map/components/FoldableMapView.js +209 -0
  48. package/build/map/components/MapContext.d.ts +12 -0
  49. package/build/map/components/MapContext.js +54 -0
  50. package/build/map/components/MapUI.d.ts +18 -0
  51. package/build/map/components/MapUI.js +29 -0
  52. package/build/map/components/overlays/Circle.js +34 -3
  53. package/build/map/components/overlays/Cluster.d.ts +3 -1
  54. package/build/map/components/overlays/Cluster.js +31 -2
  55. package/build/map/components/overlays/HeatMap.d.ts +3 -1
  56. package/build/map/components/overlays/HeatMap.js +33 -3
  57. package/build/map/components/overlays/Marker.d.ts +1 -1
  58. package/build/map/components/overlays/Marker.js +37 -32
  59. package/build/map/components/overlays/MultiPoint.js +1 -1
  60. package/build/map/components/overlays/Polygon.js +30 -3
  61. package/build/map/components/overlays/Polyline.js +36 -3
  62. package/build/map/index.d.ts +25 -5
  63. package/build/map/index.js +59 -18
  64. package/build/map/types/common.types.d.ts +40 -0
  65. package/build/map/types/common.types.js +0 -4
  66. package/build/map/types/index.d.ts +3 -2
  67. package/build/map/types/map-view.types.d.ts +108 -3
  68. package/build/map/types/native-module.types.d.ts +363 -0
  69. package/build/map/types/native-module.types.js +5 -0
  70. package/build/map/types/offline.types.d.ts +132 -0
  71. package/build/map/types/offline.types.js +5 -0
  72. package/build/map/types/overlays.types.d.ts +137 -24
  73. package/build/map/utils/ErrorHandler.d.ts +110 -0
  74. package/build/map/utils/ErrorHandler.js +421 -0
  75. package/build/map/utils/GeoUtils.d.ts +20 -0
  76. package/build/map/utils/GeoUtils.js +76 -0
  77. package/build/map/utils/OfflineMapManager.d.ts +148 -0
  78. package/build/map/utils/OfflineMapManager.js +217 -0
  79. package/build/map/utils/PermissionUtils.d.ts +91 -0
  80. package/build/map/utils/PermissionUtils.js +255 -0
  81. package/build/map/utils/PlatformDetector.d.ts +102 -0
  82. package/build/map/utils/PlatformDetector.js +186 -0
  83. package/build/types/index.d.ts +1 -0
  84. package/build/types/index.js +1 -0
  85. package/build/types/native-module.types.d.ts +69 -0
  86. package/build/types/native-module.types.js +2 -0
  87. package/build/types/naviview.types.d.ts +1 -1
  88. package/expo-module.config.json +12 -10
  89. package/ios/ExpoGaodeMapNavigation.podspec +9 -0
  90. package/ios/map/ExpoGaodeMapModule.swift +485 -75
  91. package/ios/map/ExpoGaodeMapOfflineModule.swift +479 -0
  92. package/ios/map/ExpoGaodeMapView.swift +611 -62
  93. package/ios/map/ExpoGaodeMapViewModule.swift +48 -26
  94. package/ios/map/MapPreloadManager.swift +348 -0
  95. package/ios/map/cpp/ClusterEngine.cpp +110 -0
  96. package/ios/map/cpp/ClusterEngine.hpp +20 -0
  97. package/ios/map/cpp/ColorParser.cpp +135 -0
  98. package/ios/map/cpp/ColorParser.hpp +14 -0
  99. package/ios/map/cpp/GeometryEngine.cpp +574 -0
  100. package/ios/map/cpp/GeometryEngine.hpp +159 -0
  101. package/ios/map/cpp/QuadTree.cpp +92 -0
  102. package/ios/map/cpp/QuadTree.hpp +42 -0
  103. package/ios/map/cpp/README.md +55 -0
  104. package/ios/map/managers/UIManager.swift +72 -1
  105. package/ios/map/modules/LocationManager.swift +123 -166
  106. package/ios/map/overlays/CircleView.swift +16 -32
  107. package/ios/map/overlays/CircleViewModule.swift +12 -12
  108. package/ios/map/overlays/ClusterAnnotation.swift +32 -0
  109. package/ios/map/overlays/ClusterView.swift +331 -45
  110. package/ios/map/overlays/ClusterViewModule.swift +20 -6
  111. package/ios/map/overlays/HeatMapView.swift +135 -32
  112. package/ios/map/overlays/HeatMapViewModule.swift +20 -8
  113. package/ios/map/overlays/MarkerView.swift +613 -130
  114. package/ios/map/overlays/MarkerViewModule.swift +38 -18
  115. package/ios/map/overlays/MultiPointView.swift +168 -10
  116. package/ios/map/overlays/MultiPointViewModule.swift +27 -5
  117. package/ios/map/overlays/PolygonView.swift +62 -23
  118. package/ios/map/overlays/PolygonViewModule.swift +18 -12
  119. package/ios/map/overlays/PolylineView.swift +21 -13
  120. package/ios/map/overlays/PolylineViewModule.swift +18 -12
  121. package/ios/map/utils/ClusterNative.h +96 -0
  122. package/ios/map/utils/ClusterNative.mm +377 -0
  123. package/ios/map/utils/ColorParser.swift +12 -1
  124. package/ios/map/utils/CppBridging.mm +13 -0
  125. package/ios/map/utils/GeometryUtils.swift +34 -0
  126. package/ios/map/utils/LatLngParser.swift +87 -0
  127. package/ios/map/utils/PermissionManager.swift +135 -6
  128. package/package.json +3 -2
  129. package/shared/cpp/ClusterEngine.cpp +110 -0
  130. package/shared/cpp/ClusterEngine.hpp +20 -0
  131. package/shared/cpp/ColorParser.cpp +135 -0
  132. package/shared/cpp/ColorParser.hpp +14 -0
  133. package/shared/cpp/GeometryEngine.cpp +574 -0
  134. package/shared/cpp/GeometryEngine.hpp +159 -0
  135. package/shared/cpp/QuadTree.cpp +92 -0
  136. package/shared/cpp/QuadTree.hpp +42 -0
  137. package/shared/cpp/README.md +55 -0
  138. package/shared/cpp/tests/benchmark_js.js +41 -0
  139. package/shared/cpp/tests/run.sh +17 -0
  140. package/shared/cpp/tests/test_main.cpp +276 -0
  141. package/build/map/ExpoGaodeMap.types.d.ts +0 -41
  142. package/build/map/ExpoGaodeMap.types.js +0 -24
  143. package/build/map/utils/EventManager.d.ts +0 -10
  144. package/build/map/utils/EventManager.js +0 -26
  145. package/build/map/utils/ModuleLoader.d.ts +0 -73
  146. package/build/map/utils/ModuleLoader.js +0 -112
@@ -1,5 +1,6 @@
1
1
  package expo.modules.gaodemap.map.overlays
2
2
 
3
+ import android.annotation.SuppressLint
3
4
  import android.content.Context
4
5
  import android.graphics.Color
5
6
  import com.amap.api.maps.AMap
@@ -7,8 +8,10 @@ import com.amap.api.maps.model.BitmapDescriptorFactory
7
8
  import com.amap.api.maps.model.LatLng
8
9
  import com.amap.api.maps.model.Polyline
9
10
  import com.amap.api.maps.model.PolylineOptions
10
-
11
+
12
+ import expo.modules.gaodemap.map.utils.LatLngParser
11
13
  import expo.modules.gaodemap.map.utils.ColorParser
14
+ import expo.modules.gaodemap.map.utils.GeometryUtils
12
15
  import expo.modules.kotlin.AppContext
13
16
  import expo.modules.kotlin.viewevent.EventDispatcher
14
17
  import expo.modules.kotlin.views.ExpoView
@@ -26,6 +29,7 @@ class PolylineView(context: Context, appContext: AppContext) : ExpoView(context,
26
29
  private var isDotted: Boolean = false
27
30
  private var isGeodesic: Boolean = false
28
31
  private var textureUrl: String? = null
32
+ private var simplificationTolerance: Double = 0.0
29
33
 
30
34
  /**
31
35
  * 设置地图实例
@@ -38,19 +42,13 @@ class PolylineView(context: Context, appContext: AppContext) : ExpoView(context,
38
42
  }
39
43
 
40
44
  }
41
-
45
+
46
+
42
47
  /**
43
48
  * 设置折线点集合
44
49
  */
45
- fun setPoints(pointsList: List<Map<String, Double>>) {
46
- points = pointsList.mapNotNull { point ->
47
- val lat = point["latitude"]
48
- val lng = point["longitude"]
49
- // 坐标验证
50
- if (lat != null && lng != null && lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180) {
51
- LatLng(lat, lng)
52
- } else null
53
- }
50
+ fun setPoints(pointsList: List<Any>?) {
51
+ points = LatLngParser.parseLatLngList(pointsList)
54
52
  polyline?.let {
55
53
  it.points = points
56
54
  } ?: createOrUpdatePolyline()
@@ -71,7 +69,7 @@ class PolylineView(context: Context, appContext: AppContext) : ExpoView(context,
71
69
  /**
72
70
  * 设置线条颜色
73
71
  */
74
- fun setStrokeColor(color: Any) {
72
+ fun setStrokeColor(color: String?) {
75
73
  strokeColor = ColorParser.parseColor(color)
76
74
  polyline?.let {
77
75
  it.color = strokeColor
@@ -82,8 +80,12 @@ class PolylineView(context: Context, appContext: AppContext) : ExpoView(context,
82
80
  * 设置是否虚线
83
81
  */
84
82
  fun setDotted(dotted: Boolean) {
85
- isDotted = dotted
86
- createOrUpdatePolyline()
83
+ try {
84
+ isDotted = dotted
85
+ createOrUpdatePolyline()
86
+ } catch (e: Throwable) {
87
+ android.util.Log.e("PolylineView", "setDotted failed", e)
88
+ }
87
89
  }
88
90
 
89
91
  /**
@@ -110,6 +112,7 @@ class PolylineView(context: Context, appContext: AppContext) : ExpoView(context,
110
112
  /**
111
113
  * 设置透明度
112
114
  */
115
+ @Suppress("unused")
113
116
  fun setOpacity(opacity: Float) {
114
117
  polyline?.let { line ->
115
118
  val currentColor = line.color
@@ -125,70 +128,94 @@ class PolylineView(context: Context, appContext: AppContext) : ExpoView(context,
125
128
  textureUrl = url
126
129
  createOrUpdatePolyline()
127
130
  }
131
+
132
+ fun setSimplificationTolerance(tolerance: Double) {
133
+ simplificationTolerance = tolerance
134
+ if (points.isNotEmpty()) {
135
+ createOrUpdatePolyline()
136
+ }
137
+ }
128
138
 
129
139
  /**
130
140
  * 创建或更新折线
131
141
  */
142
+ @SuppressLint("DiscouragedApi")
132
143
  private fun createOrUpdatePolyline() {
133
144
  aMap?.let { map ->
134
- // 移除旧折线
135
- polyline?.remove()
136
- polyline = null
137
-
138
- if (points.isNotEmpty()) {
139
- val options = PolylineOptions()
140
- .addAll(points)
141
- .width(strokeWidth)
142
- .color(strokeColor)
143
- .geodesic(isGeodesic)
144
-
145
-
146
- // 设置虚线样式
147
- if (isDotted) {
148
- options.dottedLineType = PolylineOptions.DOTTEDLINE_TYPE_SQUARE
149
- }
145
+ try {
146
+ // 移除旧折线
147
+ polyline?.remove()
148
+ polyline = null
150
149
 
151
- // 设置纹理
152
- textureUrl?.let { url ->
150
+ if (points.isNotEmpty()) {
151
+ val displayPoints = if (simplificationTolerance > 0) {
152
+ GeometryUtils.simplifyPolyline(points, simplificationTolerance)
153
+ } else {
154
+ points
155
+ }
156
+
157
+ val options = PolylineOptions()
158
+ .addAll(displayPoints)
159
+ .width(strokeWidth)
160
+ .color(strokeColor)
161
+ .geodesic(isGeodesic)
162
+
163
+
164
+ // 设置虚线样式
153
165
  try {
154
- when {
155
- url.startsWith("http://") || url.startsWith("https://") -> {
156
- // 网络图片异步加载
157
- Thread {
158
- try {
159
- val connection = URL(url).openConnection()
160
- val inputStream = connection.getInputStream()
161
- val bitmap = android.graphics.BitmapFactory.decodeStream(inputStream)
162
- inputStream.close()
163
- post {
164
- polyline?.setCustomTexture(BitmapDescriptorFactory.fromBitmap(bitmap))
166
+ options.isDottedLine = isDotted
167
+ if (isDotted) {
168
+ options.dottedLineType = PolylineOptions.DOTTEDLINE_TYPE_SQUARE
169
+ }
170
+ } catch (e: Throwable) {
171
+ // 忽略虚线设置错误,防止崩溃
172
+ android.util.Log.e("PolylineView", "设置虚线失败", e)
173
+ }
174
+
175
+ // 设置纹理
176
+ textureUrl?.let { url ->
177
+ try {
178
+ when {
179
+ url.startsWith("http://") || url.startsWith("https://") -> {
180
+ // 网络图片异步加载
181
+ Thread {
182
+ try {
183
+ val connection = URL(url).openConnection()
184
+ val inputStream = connection.getInputStream()
185
+ val bitmap = android.graphics.BitmapFactory.decodeStream(inputStream)
186
+ inputStream.close()
187
+ post {
188
+ polyline?.setCustomTexture(BitmapDescriptorFactory.fromBitmap(bitmap))
189
+ }
190
+ } catch (e: Exception) {
191
+ e.printStackTrace()
165
192
  }
166
- } catch (e: Exception) {
167
- e.printStackTrace()
193
+ }.start()
194
+ }
195
+ url.startsWith("file://") -> {
196
+ val path = url.substring(7)
197
+ val bitmap = android.graphics.BitmapFactory.decodeFile(path)
198
+ bitmap?.let { options.setCustomTexture(BitmapDescriptorFactory.fromBitmap(it)) }
199
+ }
200
+ else -> {
201
+ val resId = context.resources.getIdentifier(url, "drawable", context.packageName)
202
+ if (resId != 0) {
203
+ val bitmap = android.graphics.BitmapFactory.decodeResource(context.resources, resId)
204
+ options.setCustomTexture(BitmapDescriptorFactory.fromBitmap(bitmap))
205
+ }else{
206
+
168
207
  }
169
- }.start()
170
- }
171
- url.startsWith("file://") -> {
172
- val path = url.substring(7)
173
- val bitmap = android.graphics.BitmapFactory.decodeFile(path)
174
- bitmap?.let { options.setCustomTexture(BitmapDescriptorFactory.fromBitmap(it)) }
175
- }
176
- else -> {
177
- val resId = context.resources.getIdentifier(url, "drawable", context.packageName)
178
- if (resId != 0) {
179
- val bitmap = android.graphics.BitmapFactory.decodeResource(context.resources, resId)
180
- options.setCustomTexture(BitmapDescriptorFactory.fromBitmap(bitmap))
181
- }else{
182
-
183
208
  }
184
209
  }
210
+ } catch (e: Exception) {
211
+ e.printStackTrace()
185
212
  }
186
- } catch (e: Exception) {
187
- e.printStackTrace()
188
213
  }
214
+
215
+ polyline = map.addPolyline(options)
189
216
  }
190
-
191
- polyline = map.addPolyline(options)
217
+ } catch (e: Throwable) {
218
+ android.util.Log.e("PolylineView", "Error creating/updating polyline", e)
192
219
  }
193
220
  }
194
221
  }
@@ -8,12 +8,12 @@ import expo.modules.kotlin.modules.ModuleDefinition
8
8
  */
9
9
  class PolylineViewModule : Module() {
10
10
  override fun definition() = ModuleDefinition {
11
- Name("NaviPolylineView")
11
+ Name("PolylineView")
12
12
 
13
13
  View(PolylineView::class) {
14
14
  Events("onPolylinePress")
15
15
 
16
- Prop<List<Map<String, Double>>>("points") { view: PolylineView, points ->
16
+ Prop<List<Any>?>("points") { view: PolylineView, points ->
17
17
  view.setPoints(points)
18
18
  }
19
19
 
@@ -21,7 +21,7 @@ class PolylineViewModule : Module() {
21
21
  view.setStrokeWidth(width)
22
22
  }
23
23
 
24
- Prop<Any>("strokeColor") { view: PolylineView, color ->
24
+ Prop<String?>("strokeColor") { view: PolylineView, color ->
25
25
  view.setStrokeColor(color)
26
26
  }
27
27
 
@@ -44,6 +44,10 @@ class PolylineViewModule : Module() {
44
44
  Prop<Boolean>("gradient") { view: PolylineView, gradient ->
45
45
  view.setGradient(gradient)
46
46
  }
47
+
48
+ Prop<Double>("simplificationTolerance") { view: PolylineView, tolerance ->
49
+ view.setSimplificationTolerance(tolerance)
50
+ }
47
51
  }
48
52
  }
49
53
  }
@@ -1,6 +1,6 @@
1
1
  package expo.modules.gaodemap.map.services
2
2
 
3
- import android.R
3
+ import android.annotation.SuppressLint
4
4
  import android.app.Notification
5
5
  import android.app.NotificationChannel
6
6
  import android.app.NotificationManager
@@ -37,6 +37,7 @@ class LocationForegroundService : Service() {
37
37
  }
38
38
  }
39
39
 
40
+ @SuppressLint("ForegroundServiceType")
40
41
  override fun onCreate() {
41
42
  super.onCreate()
42
43
  createNotificationChannel()
@@ -69,7 +70,7 @@ class LocationForegroundService : Service() {
69
70
  val builder = NotificationCompat.Builder(this, CHANNEL_ID)
70
71
  .setContentTitle("定位服务运行中")
71
72
  .setContentText("正在后台获取位置信息")
72
- .setSmallIcon(R.drawable.ic_menu_mylocation)
73
+ .setSmallIcon(android.R.drawable.ic_menu_mylocation)
73
74
  .setPriority(NotificationCompat.PRIORITY_LOW)
74
75
  .setOngoing(true)
75
76
 
@@ -0,0 +1,20 @@
1
+ package expo.modules.gaodemap.map.utils
2
+
3
+ import com.amap.api.maps.model.BitmapDescriptor
4
+ import java.util.concurrent.ConcurrentHashMap
5
+
6
+ object BitmapDescriptorCache {
7
+ private val cache = ConcurrentHashMap<String, BitmapDescriptor>()
8
+
9
+ fun get(key: String): BitmapDescriptor? {
10
+ return cache[key]
11
+ }
12
+
13
+ fun put(key: String, descriptor: BitmapDescriptor) {
14
+ cache[key] = descriptor
15
+ }
16
+
17
+ fun clear() {
18
+ cache.clear()
19
+ }
20
+ }
@@ -0,0 +1,13 @@
1
+ package expo.modules.gaodemap.map.utils
2
+
3
+ object ClusterNative {
4
+ init {
5
+ System.loadLibrary("gaodecluster_nav")
6
+ }
7
+
8
+ external fun clusterPoints(
9
+ latitudes: DoubleArray,
10
+ longitudes: DoubleArray,
11
+ radiusMeters: Double
12
+ ): IntArray
13
+ }
@@ -4,6 +4,16 @@ import android.graphics.Color
4
4
  import androidx.core.graphics.toColorInt
5
5
 
6
6
  object ColorParser {
7
+ init {
8
+ try {
9
+ System.loadLibrary("gaodecluster_nav")
10
+ } catch (_: Throwable) {
11
+ // Ignore if already loaded
12
+ }
13
+ }
14
+
15
+ private external fun nativeParseColor(colorString: String): Int
16
+
7
17
  /**
8
18
  * 解析颜色值
9
19
  * 支持格式:
@@ -21,6 +31,16 @@ object ColorParser {
21
31
  }
22
32
 
23
33
  private fun parseColorString(color: String): Int {
34
+ // Try native parser first
35
+ try {
36
+ val nativeColor = nativeParseColor(color)
37
+ if (nativeColor != 0) {
38
+ return nativeColor
39
+ }
40
+ } catch (_: Throwable) {
41
+ // Fallback to Kotlin implementation
42
+ }
43
+
24
44
  return try {
25
45
  when {
26
46
  color.startsWith("#") -> color.toColorInt()