react-native-google-maps-plus 0.1.0 → 1.0.0-dev.2

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 (197) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +156 -0
  3. package/RNGoogleMapsPlus.podspec +34 -0
  4. package/android/CMakeLists.txt +32 -0
  5. package/android/build.gradle +135 -0
  6. package/android/fix-prefab.gradle +51 -0
  7. package/android/gradle.properties +8 -0
  8. package/android/src/main/AndroidManifest.xml +2 -0
  9. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  10. package/android/src/main/java/com/rngooglemapsplus/Color.kt +65 -0
  11. package/android/src/main/java/com/rngooglemapsplus/GoogleMapsViewImpl.kt +847 -0
  12. package/android/src/main/java/com/rngooglemapsplus/LocationHandler.kt +205 -0
  13. package/android/src/main/java/com/rngooglemapsplus/MapCircle.kt +29 -0
  14. package/android/src/main/java/com/rngooglemapsplus/MapMarker.kt +146 -0
  15. package/android/src/main/java/com/rngooglemapsplus/MapPolygon.kt +38 -0
  16. package/android/src/main/java/com/rngooglemapsplus/MapPolyline.kt +61 -0
  17. package/android/src/main/java/com/rngooglemapsplus/PermissionHandler.kt +116 -0
  18. package/android/src/main/java/com/rngooglemapsplus/PlayServicesHandler.kt +25 -0
  19. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusModule.kt +22 -0
  20. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusPackage.kt +35 -0
  21. package/android/src/main/java/com/rngooglemapsplus/RNGoogleMapsPlusView.kt +364 -0
  22. package/ios/Color.swift +109 -0
  23. package/ios/GoogleMapViewImpl.swift +645 -0
  24. package/ios/LocationHandler.swift +205 -0
  25. package/ios/MapCircle.swift +43 -0
  26. package/ios/MapHelper.swift +18 -0
  27. package/ios/MapMarker.swift +200 -0
  28. package/ios/MapPolygon.swift +58 -0
  29. package/ios/MapPolyline.swift +85 -0
  30. package/ios/PermissionHandler.swift +73 -0
  31. package/ios/RNGoogleMapsPlusModule.swift +27 -0
  32. package/ios/RNGoogleMapsPlusView.swift +391 -0
  33. package/lib/module/RNGoogleMapsPlusModule.nitro.js +4 -0
  34. package/lib/module/RNGoogleMapsPlusModule.nitro.js.map +1 -0
  35. package/lib/module/RNGoogleMapsPlusView.nitro.js +4 -0
  36. package/lib/module/RNGoogleMapsPlusView.nitro.js.map +1 -0
  37. package/lib/module/index.js +8 -0
  38. package/lib/module/index.js.map +1 -0
  39. package/lib/module/package.json +1 -0
  40. package/lib/module/types.js +78 -0
  41. package/lib/module/types.js.map +1 -0
  42. package/lib/typescript/package.json +1 -0
  43. package/lib/typescript/src/RNGoogleMapsPlusModule.nitro.d.ts +12 -0
  44. package/lib/typescript/src/RNGoogleMapsPlusModule.nitro.d.ts.map +1 -0
  45. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts +39 -0
  46. package/lib/typescript/src/RNGoogleMapsPlusView.nitro.d.ts.map +1 -0
  47. package/lib/typescript/src/index.d.ts +7 -0
  48. package/lib/typescript/src/index.d.ts.map +1 -0
  49. package/lib/typescript/src/types.d.ts +131 -0
  50. package/lib/typescript/src/types.d.ts.map +1 -0
  51. package/nitro.json +28 -0
  52. package/nitrogen/generated/.gitattributes +1 -0
  53. package/nitrogen/generated/android/RNGoogleMapsPlus+autolinking.cmake +85 -0
  54. package/nitrogen/generated/android/RNGoogleMapsPlus+autolinking.gradle +27 -0
  55. package/nitrogen/generated/android/RNGoogleMapsPlusOnLoad.cpp +70 -0
  56. package/nitrogen/generated/android/RNGoogleMapsPlusOnLoad.hpp +25 -0
  57. package/nitrogen/generated/android/c++/JFunc_void_RNLatLng.hpp +76 -0
  58. package/nitrogen/generated/android/c++/JFunc_void_RNLocation.hpp +78 -0
  59. package/nitrogen/generated/android/c++/JFunc_void_RNLocationErrorCode.hpp +76 -0
  60. package/nitrogen/generated/android/c++/JFunc_void_RNMapErrorCode.hpp +76 -0
  61. package/nitrogen/generated/android/c++/JFunc_void_RNRegion_RNCamera_bool.hpp +81 -0
  62. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +74 -0
  63. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +75 -0
  64. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusModuleSpec.cpp +83 -0
  65. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusModuleSpec.hpp +67 -0
  66. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.cpp +589 -0
  67. package/nitrogen/generated/android/c++/JHybridRNGoogleMapsPlusViewSpec.hpp +118 -0
  68. package/nitrogen/generated/android/c++/JRNAndroidLocationPermissionResult.hpp +62 -0
  69. package/nitrogen/generated/android/c++/JRNCamera.hpp +67 -0
  70. package/nitrogen/generated/android/c++/JRNCircle.hpp +84 -0
  71. package/nitrogen/generated/android/c++/JRNIOSPermissionResult.hpp +59 -0
  72. package/nitrogen/generated/android/c++/JRNInitialProps.hpp +66 -0
  73. package/nitrogen/generated/android/c++/JRNLatLng.hpp +57 -0
  74. package/nitrogen/generated/android/c++/JRNLineCapType.hpp +62 -0
  75. package/nitrogen/generated/android/c++/JRNLineJoinType.hpp +62 -0
  76. package/nitrogen/generated/android/c++/JRNLocation.hpp +58 -0
  77. package/nitrogen/generated/android/c++/JRNLocationErrorCode.hpp +71 -0
  78. package/nitrogen/generated/android/c++/JRNLocationPermissionResult.hpp +61 -0
  79. package/nitrogen/generated/android/c++/JRNMapErrorCode.hpp +74 -0
  80. package/nitrogen/generated/android/c++/JRNMapPadding.hpp +65 -0
  81. package/nitrogen/generated/android/c++/JRNMapType.hpp +68 -0
  82. package/nitrogen/generated/android/c++/JRNMarker.hpp +82 -0
  83. package/nitrogen/generated/android/c++/JRNPolygon.hpp +98 -0
  84. package/nitrogen/generated/android/c++/JRNPolyline.hpp +106 -0
  85. package/nitrogen/generated/android/c++/JRNPosition.hpp +57 -0
  86. package/nitrogen/generated/android/c++/JRNRegion.hpp +62 -0
  87. package/nitrogen/generated/android/c++/JRNUserInterfaceStyle.hpp +62 -0
  88. package/nitrogen/generated/android/c++/views/JHybridRNGoogleMapsPlusViewStateUpdater.cpp +152 -0
  89. package/nitrogen/generated/android/c++/views/JHybridRNGoogleMapsPlusViewStateUpdater.hpp +49 -0
  90. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_RNLatLng.kt +81 -0
  91. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_RNLocation.kt +81 -0
  92. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_RNLocationErrorCode.kt +81 -0
  93. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_RNMapErrorCode.kt +81 -0
  94. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_RNRegion_RNCamera_bool.kt +81 -0
  95. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_bool.kt +81 -0
  96. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/Func_void_std__string.kt +81 -0
  97. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusModuleSpec.kt +64 -0
  98. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/HybridRNGoogleMapsPlusViewSpec.kt +317 -0
  99. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNAndroidLocationPermissionResult.kt +22 -0
  100. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNCamera.kt +38 -0
  101. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNCircle.kt +50 -0
  102. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNGoogleMapsPlusOnLoad.kt +35 -0
  103. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNIOSPermissionResult.kt +21 -0
  104. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNInitialProps.kt +35 -0
  105. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLatLng.kt +32 -0
  106. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLineCapType.kt +22 -0
  107. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLineJoinType.kt +22 -0
  108. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocation.kt +32 -0
  109. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocationErrorCode.kt +25 -0
  110. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNLocationPermissionResult.kt +32 -0
  111. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapErrorCode.kt +26 -0
  112. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapPadding.kt +38 -0
  113. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMapType.kt +24 -0
  114. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNMarker.kt +47 -0
  115. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPolygon.kt +47 -0
  116. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPolyline.kt +50 -0
  117. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNPosition.kt +32 -0
  118. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNRegion.kt +35 -0
  119. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/RNUserInterfaceStyle.kt +22 -0
  120. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/views/HybridRNGoogleMapsPlusViewManager.kt +56 -0
  121. package/nitrogen/generated/android/kotlin/com/margelo/nitro/rngooglemapsplus/views/HybridRNGoogleMapsPlusViewStateUpdater.kt +23 -0
  122. package/nitrogen/generated/ios/RNGoogleMapsPlus+autolinking.rb +60 -0
  123. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.cpp +121 -0
  124. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Bridge.hpp +792 -0
  125. package/nitrogen/generated/ios/RNGoogleMapsPlus-Swift-Cxx-Umbrella.hpp +113 -0
  126. package/nitrogen/generated/ios/RNGoogleMapsPlusAutolinking.mm +41 -0
  127. package/nitrogen/generated/ios/RNGoogleMapsPlusAutolinking.swift +40 -0
  128. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusModuleSpecSwift.cpp +11 -0
  129. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusModuleSpecSwift.hpp +102 -0
  130. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.cpp +11 -0
  131. package/nitrogen/generated/ios/c++/HybridRNGoogleMapsPlusViewSpecSwift.hpp +342 -0
  132. package/nitrogen/generated/ios/c++/views/HybridRNGoogleMapsPlusViewComponent.mm +216 -0
  133. package/nitrogen/generated/ios/swift/Func_void_RNLatLng.swift +47 -0
  134. package/nitrogen/generated/ios/swift/Func_void_RNLocation.swift +47 -0
  135. package/nitrogen/generated/ios/swift/Func_void_RNLocationErrorCode.swift +47 -0
  136. package/nitrogen/generated/ios/swift/Func_void_RNLocationPermissionResult.swift +47 -0
  137. package/nitrogen/generated/ios/swift/Func_void_RNMapErrorCode.swift +47 -0
  138. package/nitrogen/generated/ios/swift/Func_void_RNRegion_RNCamera_bool.swift +47 -0
  139. package/nitrogen/generated/ios/swift/Func_void_bool.swift +47 -0
  140. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
  141. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
  142. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusModuleSpec.swift +52 -0
  143. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusModuleSpec_cxx.swift +164 -0
  144. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec.swift +78 -0
  145. package/nitrogen/generated/ios/swift/HybridRNGoogleMapsPlusViewSpec_cxx.swift +881 -0
  146. package/nitrogen/generated/ios/swift/RNAndroidLocationPermissionResult.swift +44 -0
  147. package/nitrogen/generated/ios/swift/RNCamera.swift +123 -0
  148. package/nitrogen/generated/ios/swift/RNCircle.swift +198 -0
  149. package/nitrogen/generated/ios/swift/RNIOSPermissionResult.swift +40 -0
  150. package/nitrogen/generated/ios/swift/RNInitialProps.swift +107 -0
  151. package/nitrogen/generated/ios/swift/RNLatLng.swift +46 -0
  152. package/nitrogen/generated/ios/swift/RNLineCapType.swift +44 -0
  153. package/nitrogen/generated/ios/swift/RNLineJoinType.swift +44 -0
  154. package/nitrogen/generated/ios/swift/RNLocation.swift +46 -0
  155. package/nitrogen/generated/ios/swift/RNLocationErrorCode.swift +56 -0
  156. package/nitrogen/generated/ios/swift/RNLocationPermissionResult.swift +70 -0
  157. package/nitrogen/generated/ios/swift/RNMapErrorCode.swift +60 -0
  158. package/nitrogen/generated/ios/swift/RNMapPadding.swift +68 -0
  159. package/nitrogen/generated/ios/swift/RNMapType.swift +52 -0
  160. package/nitrogen/generated/ios/swift/RNMarker.swift +132 -0
  161. package/nitrogen/generated/ios/swift/RNPolygon.swift +187 -0
  162. package/nitrogen/generated/ios/swift/RNPolyline.swift +203 -0
  163. package/nitrogen/generated/ios/swift/RNPosition.swift +46 -0
  164. package/nitrogen/generated/ios/swift/RNRegion.swift +57 -0
  165. package/nitrogen/generated/ios/swift/RNUserInterfaceStyle.swift +44 -0
  166. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusModuleSpec.cpp +24 -0
  167. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusModuleSpec.hpp +67 -0
  168. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.cpp +76 -0
  169. package/nitrogen/generated/shared/c++/HybridRNGoogleMapsPlusViewSpec.hpp +164 -0
  170. package/nitrogen/generated/shared/c++/RNAndroidLocationPermissionResult.hpp +67 -0
  171. package/nitrogen/generated/shared/c++/RNCamera.hpp +81 -0
  172. package/nitrogen/generated/shared/c++/RNCircle.hpp +98 -0
  173. package/nitrogen/generated/shared/c++/RNIOSPermissionResult.hpp +65 -0
  174. package/nitrogen/generated/shared/c++/RNInitialProps.hpp +78 -0
  175. package/nitrogen/generated/shared/c++/RNLatLng.hpp +71 -0
  176. package/nitrogen/generated/shared/c++/RNLineCapType.hpp +80 -0
  177. package/nitrogen/generated/shared/c++/RNLineJoinType.hpp +80 -0
  178. package/nitrogen/generated/shared/c++/RNLocation.hpp +72 -0
  179. package/nitrogen/generated/shared/c++/RNLocationErrorCode.hpp +73 -0
  180. package/nitrogen/generated/shared/c++/RNLocationPermissionResult.hpp +76 -0
  181. package/nitrogen/generated/shared/c++/RNMapErrorCode.hpp +67 -0
  182. package/nitrogen/generated/shared/c++/RNMapPadding.hpp +79 -0
  183. package/nitrogen/generated/shared/c++/RNMapType.hpp +88 -0
  184. package/nitrogen/generated/shared/c++/RNMarker.hpp +97 -0
  185. package/nitrogen/generated/shared/c++/RNPolygon.hpp +95 -0
  186. package/nitrogen/generated/shared/c++/RNPolyline.hpp +105 -0
  187. package/nitrogen/generated/shared/c++/RNPosition.hpp +71 -0
  188. package/nitrogen/generated/shared/c++/RNRegion.hpp +76 -0
  189. package/nitrogen/generated/shared/c++/RNUserInterfaceStyle.hpp +80 -0
  190. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.cpp +375 -0
  191. package/nitrogen/generated/shared/c++/views/HybridRNGoogleMapsPlusViewComponent.hpp +147 -0
  192. package/nitrogen/generated/shared/json/RNGoogleMapsPlusViewConfig.json +34 -0
  193. package/package.json +24 -8
  194. package/src/RNGoogleMapsPlusModule.nitro.ts +13 -0
  195. package/src/RNGoogleMapsPlusView.nitro.ts +86 -0
  196. package/src/index.tsx +24 -0
  197. package/src/types.ts +195 -0
@@ -0,0 +1,205 @@
1
+ package com.rngooglemapsplus
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.content.Intent
5
+ import android.location.Location
6
+ import android.os.Build
7
+ import android.os.Looper
8
+ import android.provider.Settings
9
+ import com.facebook.react.bridge.ReactContext
10
+ import com.facebook.react.bridge.UiThreadUtil
11
+ import com.google.android.gms.common.ConnectionResult
12
+ import com.google.android.gms.common.GoogleApiAvailability
13
+ import com.google.android.gms.common.api.ApiException
14
+ import com.google.android.gms.common.api.CommonStatusCodes
15
+ import com.google.android.gms.common.api.ResolvableApiException
16
+ import com.google.android.gms.location.FusedLocationProviderClient
17
+ import com.google.android.gms.location.LocationCallback
18
+ import com.google.android.gms.location.LocationRequest
19
+ import com.google.android.gms.location.LocationResult
20
+ import com.google.android.gms.location.LocationServices
21
+ import com.google.android.gms.location.LocationSettingsRequest
22
+ import com.google.android.gms.location.LocationSettingsStatusCodes
23
+ import com.google.android.gms.location.Priority
24
+ import com.google.android.gms.tasks.OnSuccessListener
25
+
26
+ private const val REQ_LOCATION_SETTINGS = 2001
27
+
28
+ class LocationHandler(
29
+ val context: ReactContext,
30
+ ) {
31
+ private val fusedLocationClientProviderClient: FusedLocationProviderClient =
32
+ LocationServices.getFusedLocationProviderClient(context)
33
+ private var locationRequest: LocationRequest? = null
34
+ private var locationCallback: LocationCallback? = null
35
+ private var priority = Priority.PRIORITY_HIGH_ACCURACY
36
+ private var interval: Long = 5000
37
+ private var minUpdateInterval: Long = 5000
38
+ var onUpdate: ((Location) -> Unit)? = null
39
+ var onError: ((RNLocationErrorCode) -> Unit)? = null
40
+
41
+ init {
42
+ buildLocationRequest()
43
+ }
44
+
45
+ fun showLocationDialog() {
46
+ UiThreadUtil.runOnUiThread {
47
+ val activity = context.currentActivity ?: run { return@runOnUiThread }
48
+
49
+ val lr =
50
+ if (Build.VERSION.SDK_INT >= 31) {
51
+ LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 10_000L).build()
52
+ } else {
53
+ @Suppress("DEPRECATION")
54
+ LocationRequest.create().apply { priority = Priority.PRIORITY_HIGH_ACCURACY }
55
+ }
56
+
57
+ val req =
58
+ LocationSettingsRequest
59
+ .Builder()
60
+ .addLocationRequest(lr)
61
+ .setAlwaysShow(true)
62
+ .build()
63
+
64
+ val settingsClient = LocationServices.getSettingsClient(activity)
65
+ settingsClient
66
+ .checkLocationSettings(req)
67
+ .addOnSuccessListener {
68
+ }.addOnFailureListener { ex ->
69
+ if (ex is ResolvableApiException) {
70
+ try {
71
+ ex.startResolutionForResult(activity, REQ_LOCATION_SETTINGS)
72
+ } catch (_: Exception) {
73
+ onError?.invoke(RNLocationErrorCode.SETTINGS_NOT_SATISFIED)
74
+ }
75
+ } else {
76
+ onError?.invoke(RNLocationErrorCode.SETTINGS_NOT_SATISFIED)
77
+ openLocationSettings()
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ fun openLocationSettings() {
84
+ UiThreadUtil.runOnUiThread {
85
+ val intent =
86
+ Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
87
+ context.currentActivity?.startActivity(intent)
88
+ }
89
+ }
90
+
91
+ @Suppress("deprecation")
92
+ private fun buildLocationRequest() {
93
+ locationRequest =
94
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
95
+ LocationRequest
96
+ .Builder(priority, interval)
97
+ .setMinUpdateIntervalMillis(minUpdateInterval)
98
+ .build()
99
+ } else {
100
+ LocationRequest
101
+ .create()
102
+ .setPriority(priority)
103
+ .setInterval(interval)
104
+ .setFastestInterval(minUpdateInterval)
105
+ }
106
+ restartLocationUpdates()
107
+ }
108
+
109
+ fun setPriority(priority: Int) {
110
+ this.priority = priority
111
+ buildLocationRequest()
112
+ }
113
+
114
+ fun setInterval(interval: Int) {
115
+ this.interval = interval.toLong()
116
+ buildLocationRequest()
117
+ }
118
+
119
+ fun setFastestInterval(fastestInterval: Int) {
120
+ this.minUpdateInterval = fastestInterval.toLong()
121
+ buildLocationRequest()
122
+ }
123
+
124
+ private fun restartLocationUpdates() {
125
+ stop()
126
+ // 4) Google Play Services checken – früh zurückmelden
127
+ val playServicesStatus =
128
+ GoogleApiAvailability
129
+ .getInstance()
130
+ .isGooglePlayServicesAvailable(context)
131
+ if (playServicesStatus != ConnectionResult.SUCCESS) {
132
+ onError?.invoke(RNLocationErrorCode.PLAY_SERVICE_NOT_AVAILABLE)
133
+ return
134
+ }
135
+ start()
136
+ }
137
+
138
+ @SuppressLint("MissingPermission")
139
+ fun start() {
140
+ try {
141
+ fusedLocationClientProviderClient.lastLocation
142
+ .addOnSuccessListener(
143
+ OnSuccessListener { location ->
144
+ if (location != null) {
145
+ onUpdate?.invoke(location)
146
+ }
147
+ },
148
+ ).addOnFailureListener { e ->
149
+ val error = mapThrowableToCode(e)
150
+ onError?.invoke(error)
151
+ }
152
+ locationCallback =
153
+ object : LocationCallback() {
154
+ override fun onLocationResult(locationResult: LocationResult) {
155
+ val location = locationResult.lastLocation
156
+ if (location != null) {
157
+ onUpdate?.invoke(location)
158
+ } else {
159
+ onError?.invoke(RNLocationErrorCode.POSITION_UNAVAILABLE)
160
+ }
161
+ }
162
+ }
163
+ fusedLocationClientProviderClient
164
+ .requestLocationUpdates(
165
+ locationRequest!!,
166
+ locationCallback!!,
167
+ Looper.getMainLooper(),
168
+ ).addOnFailureListener { e ->
169
+ val error = mapThrowableToCode(e)
170
+ onError?.invoke(error)
171
+ }
172
+ } catch (se: SecurityException) {
173
+ onError?.invoke(RNLocationErrorCode.PERMISSION_DENIED)
174
+ } catch (ex: Exception) {
175
+ val error = mapThrowableToCode(ex)
176
+ onError?.invoke(error)
177
+ }
178
+ }
179
+
180
+ private fun mapThrowableToCode(t: Throwable): RNLocationErrorCode {
181
+ if (t is SecurityException) return RNLocationErrorCode.PERMISSION_DENIED
182
+ if (t.message?.contains("GoogleApi", ignoreCase = true) == true) {
183
+ val gms = GoogleApiAvailability.getInstance()
184
+ val status = gms.isGooglePlayServicesAvailable(context)
185
+ if (status != ConnectionResult.SUCCESS) return RNLocationErrorCode.PLAY_SERVICE_NOT_AVAILABLE
186
+ }
187
+ if (t is ApiException) {
188
+ when (t.statusCode) {
189
+ CommonStatusCodes.NETWORK_ERROR -> return RNLocationErrorCode.POSITION_UNAVAILABLE
190
+ LocationSettingsStatusCodes.RESOLUTION_REQUIRED,
191
+ LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE,
192
+ -> return RNLocationErrorCode.SETTINGS_NOT_SATISFIED
193
+ }
194
+ return RNLocationErrorCode.INTERNAL_ERROR
195
+ }
196
+ return RNLocationErrorCode.INTERNAL_ERROR
197
+ }
198
+
199
+ fun stop() {
200
+ if (locationCallback != null) {
201
+ fusedLocationClientProviderClient.removeLocationUpdates(locationCallback!!)
202
+ locationCallback = null
203
+ }
204
+ }
205
+ }
@@ -0,0 +1,29 @@
1
+ package com.rngooglemapsplus
2
+
3
+ import com.facebook.react.uimanager.PixelUtil.dpToPx
4
+ import com.google.android.gms.maps.model.CircleOptions
5
+ import com.google.android.gms.maps.model.LatLng
6
+
7
+ class MapCircleOptions {
8
+ fun buildCircleOptions(circle: RNCircle): CircleOptions =
9
+ CircleOptions().apply {
10
+ center(LatLng(circle.center.latitude, circle.center.longitude))
11
+ circle.radius?.let { radius(it) }
12
+ circle.strokeWidth?.let { strokeWidth(it.dpToPx()) }
13
+ circle.strokeColor?.let { strokeColor(it.toColor()) }
14
+ circle.fillColor?.let { fillColor(it.toColor()) }
15
+ circle.pressable?.let { clickable(it) }
16
+ circle.zIndex?.let { zIndex(it.toFloat()) }
17
+ }
18
+ }
19
+
20
+ fun RNCircle.circleEquals(b: RNCircle): Boolean {
21
+ if (zIndex != b.zIndex) return false
22
+ if (pressable != b.pressable) return false
23
+ if (center != b.center) return false
24
+ if (radius != b.radius) return false
25
+ if (strokeWidth != b.strokeWidth) return false
26
+ if (strokeColor != b.strokeColor) return false
27
+ if (fillColor != b.fillColor) return false
28
+ return true
29
+ }
@@ -0,0 +1,146 @@
1
+ package com.rngooglemapsplus
2
+
3
+ import android.graphics.Bitmap
4
+ import android.graphics.Canvas
5
+ import android.util.LruCache
6
+ import androidx.core.graphics.createBitmap
7
+ import com.caverock.androidsvg.SVG
8
+ import com.facebook.react.uimanager.PixelUtil.dpToPx
9
+ import com.google.android.gms.maps.model.BitmapDescriptor
10
+ import com.google.android.gms.maps.model.BitmapDescriptorFactory
11
+ import com.google.android.gms.maps.model.LatLng
12
+ import com.google.android.gms.maps.model.MarkerOptions
13
+ import kotlinx.coroutines.CoroutineScope
14
+ import kotlinx.coroutines.Dispatchers
15
+ import kotlinx.coroutines.Job
16
+ import kotlinx.coroutines.SupervisorJob
17
+ import kotlinx.coroutines.ensureActive
18
+ import kotlinx.coroutines.launch
19
+ import kotlinx.coroutines.withContext
20
+ import kotlin.coroutines.coroutineContext
21
+
22
+ class MarkerOptions(
23
+ private val scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default),
24
+ ) {
25
+ private val iconCache =
26
+ object : LruCache<Int, BitmapDescriptor>(512) {
27
+ override fun sizeOf(
28
+ key: Int,
29
+ value: BitmapDescriptor,
30
+ ): Int = 1
31
+ }
32
+
33
+ private val jobsById = mutableMapOf<String, Job>()
34
+
35
+ fun build(
36
+ m: RNMarker,
37
+ icon: BitmapDescriptor,
38
+ ): MarkerOptions =
39
+ MarkerOptions().apply {
40
+ position(LatLng(m.coordinate.latitude, m.coordinate.longitude))
41
+ anchor((m.anchor?.x ?: 0.5).toFloat(), (m.anchor?.y ?: 0.5).toFloat())
42
+ icon(icon)
43
+ m.zIndex?.let { zIndex(it.toFloat()) }
44
+ }
45
+
46
+ fun buildIconAsync(
47
+ id: String,
48
+ m: RNMarker,
49
+ onReady: (BitmapDescriptor) -> Unit,
50
+ ) {
51
+ jobsById[id]?.cancel()
52
+
53
+ val key = m.styleHash()
54
+ iconCache.get(key)?.let { cached ->
55
+ onReady(cached)
56
+ return
57
+ }
58
+
59
+ val job =
60
+ scope.launch {
61
+ try {
62
+ ensureActive()
63
+ val bmp = renderBitmap(m)
64
+ if (bmp != null) {
65
+ ensureActive()
66
+ val desc = BitmapDescriptorFactory.fromBitmap(bmp)
67
+ iconCache.put(key, desc)
68
+ bmp.recycle()
69
+ withContext(Dispatchers.Main) {
70
+ ensureActive()
71
+ onReady(desc)
72
+ }
73
+ }
74
+ } catch (_: OutOfMemoryError) {
75
+ iconCache.evictAll()
76
+ } catch (_: Throwable) {
77
+ } finally {
78
+ jobsById.remove(id)
79
+ }
80
+ }
81
+
82
+ jobsById[id] = job
83
+ }
84
+
85
+ fun cancelIconJob(id: String) {
86
+ jobsById[id]?.cancel()
87
+ jobsById.remove(id)
88
+ }
89
+
90
+ fun cancelAllJobs() {
91
+ val ids = jobsById.keys.toList()
92
+ ids.forEach { id ->
93
+ jobsById[id]?.cancel()
94
+ }
95
+ jobsById.clear()
96
+ iconCache.evictAll()
97
+ }
98
+
99
+ private suspend fun renderBitmap(m: RNMarker): Bitmap? {
100
+ var bmp: Bitmap? = null
101
+ try {
102
+ coroutineContext.ensureActive()
103
+ val svg = SVG.getFromString(m.iconSvg)
104
+
105
+ coroutineContext.ensureActive()
106
+ svg.setDocumentWidth(m.width.dpToPx())
107
+ svg.setDocumentHeight(m.height.dpToPx())
108
+
109
+ coroutineContext.ensureActive()
110
+ bmp =
111
+ createBitmap(m.width.dpToPx().toInt(), m.height.dpToPx().toInt(), Bitmap.Config.ARGB_8888)
112
+
113
+ coroutineContext.ensureActive()
114
+ val canvas = Canvas(bmp)
115
+ svg.renderToCanvas(canvas)
116
+
117
+ coroutineContext.ensureActive()
118
+ return bmp
119
+ } catch (t: Throwable) {
120
+ try {
121
+ bmp?.recycle()
122
+ } catch (_: Throwable) {
123
+ }
124
+ throw t
125
+ }
126
+ }
127
+ }
128
+
129
+ fun RNMarker.markerEquals(b: RNMarker): Boolean =
130
+ id == b.id &&
131
+ zIndex == b.zIndex &&
132
+ coordinate == b.coordinate &&
133
+ anchor == b.anchor &&
134
+ markerStyleEquals(b)
135
+
136
+ fun RNMarker.markerStyleEquals(b: RNMarker): Boolean =
137
+ width == b.width &&
138
+ height == b.height &&
139
+ iconSvg == b.iconSvg
140
+
141
+ fun RNMarker.styleHash(): Int =
142
+ arrayOf<Any?>(
143
+ width,
144
+ height,
145
+ iconSvg,
146
+ ).contentHashCode()
@@ -0,0 +1,38 @@
1
+ package com.rngooglemapsplus
2
+
3
+ import com.facebook.react.uimanager.PixelUtil.dpToPx
4
+ import com.google.android.gms.maps.model.PolygonOptions
5
+
6
+ class MapPolygonOptions {
7
+ fun buildPolygonOptions(poly: RNPolygon): PolygonOptions =
8
+ PolygonOptions().apply {
9
+ poly.coordinates.forEach { pt ->
10
+ add(
11
+ com.google.android.gms.maps.model
12
+ .LatLng(pt.latitude, pt.longitude),
13
+ )
14
+ }
15
+ poly.fillColor?.let { fillColor(it.toColor()) }
16
+ poly.strokeColor?.let { strokeColor(it.toColor()) }
17
+ poly.strokeWidth?.let { strokeWidth(it.dpToPx()) }
18
+ poly.pressable?.let { clickable(it) }
19
+ poly.zIndex?.let { zIndex(it.toFloat()) }
20
+ }
21
+ }
22
+
23
+ fun RNPolygon.polygonEquals(b: RNPolygon): Boolean {
24
+ if (zIndex != b.zIndex) return false
25
+ if (pressable != b.pressable) return false
26
+ if (strokeWidth != b.strokeWidth) return false
27
+ if (fillColor != b.fillColor) return false
28
+ if (strokeColor != b.strokeColor) return false
29
+ val ac = coordinates
30
+ val bc = b.coordinates
31
+ if (ac.size != bc.size) return false
32
+ for (i in ac.indices) {
33
+ val p = ac[i]
34
+ val q = bc[i]
35
+ if (p.latitude != q.latitude || p.longitude != q.longitude) return false
36
+ }
37
+ return true
38
+ }
@@ -0,0 +1,61 @@
1
+ package com.rngooglemapsplus
2
+
3
+ import com.facebook.react.uimanager.PixelUtil.dpToPx
4
+ import com.google.android.gms.maps.model.ButtCap
5
+ import com.google.android.gms.maps.model.Cap
6
+ import com.google.android.gms.maps.model.JointType
7
+ import com.google.android.gms.maps.model.PolylineOptions
8
+ import com.google.android.gms.maps.model.RoundCap
9
+ import com.google.android.gms.maps.model.SquareCap
10
+
11
+ class MapPolylineOptions {
12
+ fun buildPolylineOptions(pl: RNPolyline): PolylineOptions =
13
+ PolylineOptions().apply {
14
+ pl.coordinates.forEach { pt ->
15
+ add(
16
+ com.google.android.gms.maps.model
17
+ .LatLng(pt.latitude, pt.longitude),
18
+ )
19
+ }
20
+ pl.width?.let { width(it.dpToPx()) }
21
+ pl.lineCap?.let { startCap(mapLineCap(it)) }
22
+ pl.lineCap?.let { endCap(mapLineCap(it)) }
23
+ pl.lineJoin?.let { jointType(mapLineJoin(it)) }
24
+ pl.color?.let { color(it.toColor()) }
25
+ pl.pressable?.let { clickable(it) }
26
+ pl.zIndex?.let { zIndex(it.toFloat()) }
27
+ }
28
+
29
+ fun mapLineCap(type: RNLineCapType?): Cap =
30
+ when (type) {
31
+ RNLineCapType.ROUND -> RoundCap()
32
+ RNLineCapType.SQUARE -> SquareCap()
33
+ else -> ButtCap()
34
+ }
35
+
36
+ fun mapLineJoin(type: RNLineJoinType?): Int =
37
+ when (type) {
38
+ RNLineJoinType.ROUND -> JointType.ROUND
39
+ RNLineJoinType.BEVEL -> JointType.BEVEL
40
+ RNLineJoinType.MITER -> JointType.DEFAULT
41
+ null -> JointType.DEFAULT
42
+ }
43
+ }
44
+
45
+ fun RNPolyline.polylineEquals(b: RNPolyline): Boolean {
46
+ if (zIndex != b.zIndex) return false
47
+ if (pressable != b.pressable) return false
48
+ if ((width ?: 0.0) != (b.width ?: 0.0)) return false
49
+ if (lineCap != b.lineCap) return false
50
+ if (lineJoin != b.lineJoin) return false
51
+ if (color != b.color) return false
52
+ val ac = coordinates
53
+ val bc = b.coordinates
54
+ if (ac.size != bc.size) return false
55
+ for (i in ac.indices) {
56
+ val p = ac[i]
57
+ val q = bc[i]
58
+ if (p.latitude != q.latitude || p.longitude != q.longitude) return false
59
+ }
60
+ return true
61
+ }
@@ -0,0 +1,116 @@
1
+ package com.rngooglemapsplus
2
+
3
+ import android.Manifest
4
+ import android.content.pm.PackageManager
5
+ import androidx.core.content.ContextCompat
6
+ import com.facebook.react.bridge.ReactContext
7
+ import com.facebook.react.bridge.UiThreadUtil
8
+ import com.facebook.react.modules.core.PermissionAwareActivity
9
+ import com.facebook.react.modules.core.PermissionListener
10
+ import com.margelo.nitro.core.Promise
11
+
12
+ private const val REQ_LOCATION = 1001
13
+
14
+ class PermissionHandler(
15
+ private val context: ReactContext,
16
+ ) {
17
+ fun requestLocationPermission(): Promise<RNLocationPermissionResult> {
18
+ val promise = Promise<RNLocationPermissionResult>()
19
+
20
+ val perms =
21
+ arrayOf(
22
+ Manifest.permission.ACCESS_COARSE_LOCATION,
23
+ Manifest.permission.ACCESS_FINE_LOCATION,
24
+ )
25
+
26
+ val alreadyGranted =
27
+ ContextCompat.checkSelfPermission(
28
+ context,
29
+ Manifest.permission.ACCESS_COARSE_LOCATION,
30
+ ) == PackageManager.PERMISSION_GRANTED
31
+ if (alreadyGranted) {
32
+ promise.resolve(RNLocationPermissionResult(RNAndroidLocationPermissionResult.GRANTED, null))
33
+ return promise
34
+ }
35
+
36
+ UiThreadUtil.runOnUiThread {
37
+ val hostActivity = context.currentActivity
38
+ if (hostActivity !is PermissionAwareActivity) {
39
+ promise.resolve(RNLocationPermissionResult(RNAndroidLocationPermissionResult.DENIED, null))
40
+ return@runOnUiThread
41
+ }
42
+
43
+ hostActivity.requestPermissions(
44
+ perms,
45
+ REQ_LOCATION,
46
+ object : PermissionListener {
47
+ override fun onRequestPermissionsResult(
48
+ requestCode: Int,
49
+ permissions: Array<String>,
50
+ grantResults: IntArray,
51
+ ): Boolean {
52
+ if (requestCode != REQ_LOCATION) return false
53
+
54
+ var coarseGranted = false
55
+ var fineGranted = false
56
+
57
+ for (i in permissions.indices) {
58
+ val p = permissions[i]
59
+ val r = grantResults.getOrNull(i) ?: continue
60
+ if (p == Manifest.permission.ACCESS_COARSE_LOCATION && r == PackageManager.PERMISSION_GRANTED) {
61
+ coarseGranted = true
62
+ }
63
+ if (p == Manifest.permission.ACCESS_FINE_LOCATION && r == PackageManager.PERMISSION_GRANTED) {
64
+ fineGranted = true
65
+ }
66
+ }
67
+
68
+ val hostActivity =
69
+ context.currentActivity ?: run {
70
+ promise.resolve(
71
+ RNLocationPermissionResult(
72
+ RNAndroidLocationPermissionResult.DENIED,
73
+ null,
74
+ ),
75
+ )
76
+ return true
77
+ }
78
+
79
+ val granted = coarseGranted || fineGranted
80
+ if (granted) {
81
+ promise.resolve(
82
+ RNLocationPermissionResult(
83
+ RNAndroidLocationPermissionResult.GRANTED,
84
+ null,
85
+ ),
86
+ )
87
+ } else {
88
+ val neverAskAgain =
89
+ !hostActivity.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION)
90
+
91
+ if (neverAskAgain) {
92
+ promise.resolve(
93
+ RNLocationPermissionResult(
94
+ RNAndroidLocationPermissionResult.NEVER_ASK_AGAIN,
95
+ null,
96
+ ),
97
+ )
98
+ } else {
99
+ promise.resolve(
100
+ RNLocationPermissionResult(
101
+ RNAndroidLocationPermissionResult.DENIED,
102
+ null,
103
+ ),
104
+ )
105
+ }
106
+ }
107
+
108
+ return true
109
+ }
110
+ },
111
+ )
112
+ }
113
+
114
+ return promise
115
+ }
116
+ }
@@ -0,0 +1,25 @@
1
+ package com.rngooglemapsplus
2
+
3
+ import com.facebook.react.bridge.ReactContext
4
+ import com.google.android.gms.common.ConnectionResult
5
+ import com.google.android.gms.common.GoogleApiAvailability
6
+
7
+ class PlayServicesHandler(
8
+ val context: ReactContext,
9
+ ) {
10
+ fun playServicesAvailability(): Int {
11
+ val availability = GoogleApiAvailability.getInstance()
12
+ return availability.isGooglePlayServicesAvailable(context)
13
+ }
14
+
15
+ fun isPlayServicesAvailable(): Boolean {
16
+ val availability = playServicesAvailability()
17
+ return when (availability) {
18
+ ConnectionResult.SERVICE_MISSING,
19
+ ConnectionResult.SERVICE_INVALID,
20
+ -> false
21
+
22
+ else -> true
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,22 @@
1
+ package com.rngooglemapsplus
2
+
3
+ import com.margelo.nitro.core.Promise
4
+
5
+ class RNGoogleMapsPlusModule : HybridRNGoogleMapsPlusModuleSpec() {
6
+ val context = RNGoogleMapsPlusPackage.AppContextHolder.context
7
+ private val locationHandler: LocationHandler = LocationHandler(context)
8
+ private val permissionHandler: PermissionHandler = PermissionHandler(context)
9
+ private val playServicesHandler: PlayServicesHandler = PlayServicesHandler(context)
10
+
11
+ override fun showLocationDialog() {
12
+ locationHandler.showLocationDialog()
13
+ }
14
+
15
+ override fun openLocationSettings() {
16
+ locationHandler.openLocationSettings()
17
+ }
18
+
19
+ override fun requestLocationPermission(): Promise<RNLocationPermissionResult> = permissionHandler.requestLocationPermission()
20
+
21
+ override fun isGooglePlayServicesAvailable(): Boolean = playServicesHandler.isPlayServicesAvailable()
22
+ }
@@ -0,0 +1,35 @@
1
+ package com.rngooglemapsplus
2
+
3
+ import com.facebook.react.BaseReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.model.ReactModuleInfoProvider
7
+ import com.facebook.react.uimanager.ViewManager
8
+ import com.rngooglemapsplus.RNGoogleMapsPlusPackage.AppContextHolder.context
9
+ import com.rngooglemapsplus.views.HybridRNGoogleMapsPlusViewManager
10
+
11
+ class RNGoogleMapsPlusPackage : BaseReactPackage() {
12
+ override fun getModule(
13
+ name: String,
14
+ reactContext: ReactApplicationContext,
15
+ ): NativeModule? = null
16
+
17
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider = ReactModuleInfoProvider { HashMap() }
18
+
19
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
20
+ context = reactContext
21
+ return listOf(
22
+ HybridRNGoogleMapsPlusViewManager(),
23
+ )
24
+ }
25
+
26
+ object AppContextHolder {
27
+ lateinit var context: ReactApplicationContext
28
+ }
29
+
30
+ companion object {
31
+ init {
32
+ RNGoogleMapsPlusOnLoad.initializeNative()
33
+ }
34
+ }
35
+ }