@@ -86,10 +86,12 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
8686 LocationUpdateListener , LocationPermissionCallback {
8787 private var bottomSheetDetailsBehavior: BottomSheetBehavior <* >? = null
8888 private var broadcastReceiver: BroadcastReceiver ? = null
89+ private var locationProvidersBroadcastReceiver: BroadcastReceiver ? = null
8990 private var isNetworkErrorOccurred = false
9091 private var snackbar: Snackbar ? = null
9192 private var isDarkTheme = false
9293 private var isPermissionDenied = false
94+ private var locationServicesEnabledOnPause = false
9395 private var lastKnownLocation: LatLng ? = null // last location of user
9496 private var recenterToUserLocation = false // true is recenter is needed (ie. when current location is in visible map boundaries)
9597 private var clickedMarker: BaseMarker ? = null
@@ -103,6 +105,7 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
103105 private var prevLongitude = 0.0
104106 private var recentlyCameFromNearbyMap = false
105107 private var shouldPerformMapReadyActionsOnResume = false
108+ private var isWaitingForFirstLocation = false
106109 private var presenter: ExploreMapPresenter ? = null
107110 private var binding: FragmentExploreMapBinding ? = null
108111 var mediaList: MutableList <Media >? = null
@@ -179,6 +182,7 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
179182 Html .fromHtml(getString(R .string.map_attribution))
180183 }
181184 initNetworkBroadCastReceiver()
185+ initLocationProvidersBroadCastReceiver()
182186 locationPermissionsHelper = LocationPermissionsHelper (
183187 requireActivity(), locationManager,
184188 this
@@ -281,7 +285,37 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
281285 if (broadcastReceiver != null ) {
282286 requireActivity().registerReceiver(broadcastReceiver, intentFilter)
283287 }
288+ if (locationProvidersBroadcastReceiver != null ) {
289+ val locationProvidersFilter = IntentFilter (LocationManager .PROVIDERS_CHANGED_ACTION )
290+ requireActivity().registerReceiver(locationProvidersBroadcastReceiver, locationProvidersFilter)
291+ }
284292 setSearchThisAreaButtonVisibility(false )
293+
294+ // Check if location services were enabled while app was in Settings
295+ val hasPermission = locationPermissionsHelper?.checkLocationPermission(requireActivity()) == true
296+ val isLocationNowEnabled = locationPermissionsHelper?.isLocationAccessToAppsTurnedOn() == true
297+
298+ if (hasPermission && isLocationNowEnabled && ! locationServicesEnabledOnPause) {
299+ Timber .d(" Location services enabled while app was paused - refreshing map" )
300+ locationManager.registerLocationManager()
301+ drawMyLocationMarker()
302+
303+ val cachedLocation = locationManager.getLastLocation()
304+ if (cachedLocation != null ) {
305+ val targetP = GeoPoint (cachedLocation.latitude, cachedLocation.longitude)
306+ mapCenter = targetP
307+ binding?.mapView?.controller?.setCenter(targetP)
308+ recenterMarkerToPosition(targetP)
309+ moveCameraToPosition(targetP)
310+ populatePlaces(cachedLocation)
311+ } else {
312+ isWaitingForFirstLocation = true
313+ setProgressBarVisibility(true )
314+ }
315+ }
316+ // Update tracked state for next pause/resume cycle
317+ locationServicesEnabledOnPause = isLocationNowEnabled
318+
285319 if (shouldPerformMapReadyActionsOnResume) {
286320 shouldPerformMapReadyActionsOnResume = false
287321 performMapReadyActions()
@@ -290,8 +324,12 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
290324
291325 override fun onPause () {
292326 super .onPause()
327+ // Track location services state before pausing
328+ locationServicesEnabledOnPause = locationPermissionsHelper?.isLocationAccessToAppsTurnedOn() == true
329+
293330 // unregistering the broadcastReceiver, as it was causing an exception and a potential crash
294331 unregisterNetworkReceiver()
332+ unregisterLocationProvidersReceiver()
295333 locationManager.unregisterLocationManager()
296334 locationManager.removeLocationListener(this )
297335 }
@@ -311,10 +349,8 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
311349 locationPermissionsHelper!! .showLocationOffDialog(requireActivity(), R .string.location_off_dialog_text)
312350 }
313351 } else {
314- locationPermissionsHelper!! .requestForLocationAccess(
315- R .string.location_permission_title,
316- R .string.location_permission_rationale
317- )
352+ // Use activityResultLauncher for proper callback handling
353+ askForLocationPermission()
318354 }
319355 }
320356
@@ -339,6 +375,16 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
339375 */
340376 private fun unregisterNetworkReceiver () =
341377 activity?.unregisterReceiver(broadcastReceiver)
378+
379+ private fun unregisterLocationProvidersReceiver () {
380+ try {
381+ if (locationProvidersBroadcastReceiver != null ) {
382+ requireActivity().unregisterReceiver(locationProvidersBroadcastReceiver)
383+ }
384+ } catch (e: Exception ) {
385+ Timber .e(e, " Error unregistering location providers receiver" )
386+ }
387+ }
342388
343389 private fun startMapWithoutPermission () {
344390 lastKnownLocation = defaultLatLng
@@ -361,23 +407,29 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
361407 isPermissionDenied = true
362408 }
363409
364- lastKnownLocation = getLastLocation()
365-
366- if (lastKnownLocation == null ) {
367- lastKnownLocation = defaultLatLng
368- }
410+ lastKnownLocation = locationManager.getLastLocation()
369411
370412 // if we came from 'Show in Explore' in Nearby, load Nearby map center and zoom
371413 if (isCameFromNearbyMap) {
414+ val targetP = GeoPoint (prevLatitude, prevLongitude)
415+ mapCenter = targetP
372416 moveCameraToPosition(
373- GeoPoint (prevLatitude, prevLongitude) ,
417+ targetP ,
374418 prevZoom.coerceIn(1.0 , 22.0 ),
375419 1L
376420 )
377- } else {
378- moveCameraToPosition(
379- GeoPoint (lastKnownLocation!! .latitude, lastKnownLocation!! .longitude)
380- )
421+ recenterMarkerToPosition(targetP)
422+ } else if (lastKnownLocation != null ) {
423+ val targetP = GeoPoint (lastKnownLocation!! .latitude, lastKnownLocation!! .longitude)
424+ mapCenter = targetP
425+ moveCameraToPosition(targetP)
426+ recenterMarkerToPosition(targetP)
427+ } else if (! isWaitingForFirstLocation) {
428+ lastKnownLocation = defaultLatLng
429+ val targetP = GeoPoint (lastKnownLocation!! .latitude, lastKnownLocation!! .longitude)
430+ mapCenter = targetP
431+ moveCameraToPosition(targetP)
432+ recenterMarkerToPosition(targetP)
381433 }
382434 presenter!! .onMapReady(exploreMapController)
383435 }
@@ -484,6 +536,16 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
484536 ) {
485537 lastKnownLocation = latLng
486538 exploreMapController.currentLocation = lastKnownLocation
539+ if (isWaitingForFirstLocation && latLng != null ) {
540+ isWaitingForFirstLocation = false
541+ setProgressBarVisibility(false )
542+ val targetP = GeoPoint (latLng.latitude, latLng.longitude)
543+ mapCenter = targetP
544+ binding!! .mapView.controller.setCenter(targetP)
545+ recenterMarkerToPosition(targetP)
546+ moveCameraToPosition(targetP)
547+ }
548+
487549 presenter!! .updateMap(locationChangeType)
488550 }
489551
@@ -563,28 +625,28 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
563625 private fun locationPermissionGranted () {
564626 isPermissionDenied = false
565627 applicationKvStore.putBoolean(" doNotAskForLocationPermission" , false )
628+
629+ // Add listener and register location manager
630+ locationManager.addLocationListener(this )
631+ locationManager.registerLocationManager()
632+ drawMyLocationMarker()
633+
566634 lastKnownLocation = locationManager.getLastLocation()
567- val target = lastKnownLocation
635+
568636 if (lastKnownLocation != null ) {
569- val targetP = GeoPoint (target !! .latitude, target .longitude)
637+ val targetP = GeoPoint (lastKnownLocation !! .latitude, lastKnownLocation !! .longitude)
570638 mapCenter = targetP
571639 binding!! .mapView.controller.setCenter(targetP)
572640 recenterMarkerToPosition(targetP)
573641 moveCameraToPosition(targetP)
574- } else if (locationManager.isGPSProviderEnabled()
575- || locationManager.isNetworkProviderEnabled()
576- ) {
577- locationManager.requestLocationUpdatesFromProvider(LocationManager .NETWORK_PROVIDER )
578- locationManager.requestLocationUpdatesFromProvider(LocationManager .GPS_PROVIDER )
579- setProgressBarVisibility(true )
642+ populatePlaces(lastKnownLocation)
580643 } else {
581- locationPermissionsHelper!! .showLocationOffDialog(
582- requireActivity(),
583- R .string.ask_to_turn_location_on_text
584- )
644+ // No cached location - set flag to wait for first GPS fix
645+ isWaitingForFirstLocation = true
646+ setProgressBarVisibility(true )
647+ // Still need to populate with default location, will recenter when location arrives
648+ populatePlaces(getMapCenter())
585649 }
586- presenter!! .onMapReady(exploreMapController)
587- registerUnregisterLocationListener(false )
588650 }
589651
590652 fun registerUnregisterLocationListener (removeLocationListener : Boolean ) {
@@ -605,7 +667,11 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
605667 if (! locationPermissionsHelper!! .checkLocationPermission(requireActivity())) {
606668 askForLocationPermission()
607669 } else {
608- locationPermissionGranted()
670+ if (locationPermissionsHelper!! .isLocationAccessToAppsTurnedOn()) {
671+ locationPermissionGranted()
672+ } else {
673+ locationPermissionsHelper!! .showLocationOffDialog(requireActivity(), R .string.location_off_dialog_text)
674+ }
609675 }
610676 }
611677 if (curLatLng == null ) {
@@ -1113,6 +1179,44 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
11131179 }
11141180 }
11151181 }
1182+
1183+ /* *
1184+ * Broadcast receiver for location providers changes (when location services are turned on/off)
1185+ */
1186+ private fun initLocationProvidersBroadCastReceiver () {
1187+ locationProvidersBroadcastReceiver = object : BroadcastReceiver () {
1188+ override fun onReceive (context : Context ? , intent : Intent ? ) {
1189+ if (intent?.action == LocationManager .PROVIDERS_CHANGED_ACTION ) {
1190+ if (activity != null && isResumed) {
1191+ val hasPermission = locationPermissionsHelper?.checkLocationPermission(requireActivity()) == true
1192+ val isLocationEnabled = locationPermissionsHelper?.isLocationAccessToAppsTurnedOn() == true
1193+
1194+ // If location services just got turned on
1195+ if (hasPermission && isLocationEnabled && ! locationServicesEnabledOnPause) {
1196+ Timber .d(" Location services were turned on" )
1197+ locationManager.registerLocationManager()
1198+ locationManager.addLocationListener(this @ExploreMapFragment)
1199+ drawMyLocationMarker()
1200+
1201+ val cachedLocation = locationManager.getLastLocation()
1202+ if (cachedLocation != null ) {
1203+ val targetP = GeoPoint (cachedLocation.latitude, cachedLocation.longitude)
1204+ mapCenter = targetP
1205+ binding?.mapView?.controller?.setCenter(targetP)
1206+ recenterMarkerToPosition(targetP)
1207+ moveCameraToPosition(targetP)
1208+ populatePlaces(cachedLocation)
1209+ } else {
1210+ isWaitingForFirstLocation = true
1211+ setProgressBarVisibility(true )
1212+ }
1213+ }
1214+ locationServicesEnabledOnPause = isLocationEnabled
1215+ }
1216+ }
1217+ }
1218+ }
1219+ }
11161220
11171221 val isAttachedToActivity: Boolean
11181222 get() = isVisible && activity != null
@@ -1121,12 +1225,32 @@ class ExploreMapFragment : CommonsDaggerSupportFragment(), ExploreMapContract.Vi
11211225
11221226 override fun onLocationPermissionGranted () {
11231227 if (locationPermissionsHelper!! .isLocationAccessToAppsTurnedOn()) {
1228+ locationManager.addLocationListener(this )
1229+
11241230 locationManager.registerLocationManager()
11251231 drawMyLocationMarker()
1232+
1233+ // Check if we have a cached location
1234+ val cachedLocation = locationManager.getLastLocation()
1235+
1236+ if (cachedLocation != null ) {
1237+ // Center map immediately
1238+ val targetP = GeoPoint (cachedLocation.latitude, cachedLocation.longitude)
1239+ mapCenter = targetP
1240+ binding?.mapView?.controller?.setCenter(targetP)
1241+ recenterMarkerToPosition(targetP)
1242+ moveCameraToPosition(targetP)
1243+ populatePlaces(cachedLocation)
1244+ } else {
1245+ // No cached location - wait for first GPS fix
1246+ isWaitingForFirstLocation = true
1247+ setProgressBarVisibility(true )
1248+ // Still need to populate with default, but will recenter when location arrives
1249+ populatePlaces(getMapCenter())
1250+ }
11261251 } else {
11271252 locationPermissionsHelper!! .showLocationOffDialog(requireActivity(), R .string.location_off_dialog_text)
11281253 }
1129- onLocationChanged(LocationChangeType .PERMISSION_JUST_GRANTED , null )
11301254 }
11311255
11321256 fun onLocationChanged (locationChangeType : LocationChangeType , location : Location ? ) {
0 commit comments