diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
--- a/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/LinesDetailFragment.kt
@@ -28,6 +28,7 @@
 import android.view.View
 import android.view.ViewGroup
 import android.widget.*
+import androidx.activity.result.contract.ActivityResultContracts
 import androidx.appcompat.content.res.AppCompatResources
 import androidx.core.content.ContextCompat
 import androidx.core.content.res.ResourcesCompat
@@ -53,6 +54,8 @@
 import it.reyboz.bustorino.data.gtfs.TripAndPatternWithStops
 import it.reyboz.bustorino.map.*
 import it.reyboz.bustorino.map.CustomInfoWindow.TouchResponder
+import it.reyboz.bustorino.middleware.LocationUtils
+import it.reyboz.bustorino.util.Permissions
 import it.reyboz.bustorino.viewmodels.LinesViewModel
 import it.reyboz.bustorino.viewmodels.LivePositionsViewModel
 import kotlinx.coroutines.delay
@@ -88,9 +91,10 @@
     private lateinit var switchButton: ImageButton
 
     private var favoritesButton: ImageButton? = null
-    private lateinit var locationIcon: ImageButton
+    private var locationIcon: ImageButton? = null
     private var isLineInFavorite = false
     private var appContext: Context? = null
+    private var isLocationPermissionOK = false
     private val lineSharedPrefMonitor = SharedPreferences.OnSharedPreferenceChangeListener { pref, keychanged ->
         if(keychanged!=PreferencesHolder.PREF_FAVORITE_LINES || lineID.isEmpty()) return@OnSharedPreferenceChangeListener
         val newFavorites = pref.getStringSet(PreferencesHolder.PREF_FAVORITE_LINES, HashSet())
@@ -146,6 +150,24 @@
 
     private lateinit var stopsOverlay: FolderOverlay
     private lateinit var locationOverlay: LocationOverlay
+    private val locationOverlayResponder = object : LocationOverlay.OverlayCallbacks{
+        override fun onDisableFollowMyLocation() {
+            Log.d(DEBUG_TAG, "Follow location disabled")
+        }
+
+        override fun onEnableFollowMyLocation() {
+            Log.d(DEBUG_TAG, "Follow location enabled")
+        }
+    }
+    //location request responder
+    private val locationRequestResLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()){ res ->
+        //onActivityResult(res: map<String,Boolean>)
+        if(res[Permissions.LOCATION_PERMISSIONS[0]] ==true || res[Permissions.LOCATION_PERMISSIONS[1]] ==true)
+            locationIcon?.let { onPositionIconButtonClick(it) }
+        else{
+            context?.let { Toast.makeText(it,R.string.location_permission_not_granted, Toast.LENGTH_SHORT).show() }
+        }
+    }
     //fragment actions
     private lateinit var fragmentListener: CommonFragmentListener
 
@@ -209,7 +231,7 @@
             if(map.visibility == View.VISIBLE){
                 map.visibility = View.GONE
                 stopsRecyclerView.visibility = View.VISIBLE
-                locationIcon.visibility = View.GONE
+                locationIcon?.visibility = View.GONE
 
                 viewModel.setMapShowing(false)
                 liveBusViewModel.stopMatoUpdates()
@@ -219,7 +241,7 @@
             } else{
                 stopsRecyclerView.visibility = View.GONE
                 map.visibility = View.VISIBLE
-                locationIcon.visibility = View.VISIBLE
+                locationIcon?.visibility = View.VISIBLE
                 viewModel.setMapShowing(true)
 
                 //map.overlayManager.add(busPositionsOverlay)
@@ -232,21 +254,15 @@
                 switchButton.setImageDrawable(AppCompatResources.getDrawable(requireContext(), R.drawable.ic_list_30))
             }
         }
-        locationIcon.setOnClickListener {
-            if(locationOverlay.isMyLocationEnabled){
-                //switch off
-                locationOverlay.disableMyLocation()
-                locationIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.location_circlew_grey))
-                //show message
-                Toast.makeText(requireContext(),R.string.location_disabled,Toast.LENGTH_SHORT).show()
-            } else{
-                //switch on
-                locationOverlay.enableMyLocation()
-                locationIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.location_circlew_red))
-                //show message
-                Toast.makeText(requireContext(),R.string.location_enabled,Toast.LENGTH_SHORT).show()
-            }
+        locationIcon?.let {view ->
+            if(!LocationUtils.isLocationEnabled(requireContext()) || !Permissions.anyLocationPermissionsGranted(requireContext()))
+                setLocationIconEnabled(false)
+            //set click Listener
+            view.setOnClickListener(this::onPositionIconButtonClick)
         }
+        //set
+
+
         viewModel.setRouteIDQuery(lineID)
 
         val keySourcePositions = getString(R.string.pref_positions_source)
@@ -360,6 +376,48 @@
         return rootView
     }
 
+    private fun setLocationIconEnabled(setTrue: Boolean){
+        if(setTrue)
+            locationIcon?.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.location_circlew_red))
+        else
+            locationIcon?.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.location_circlew_grey))
+    }
+
+    /**
+     * Switch position icon from activ
+     */
+    private fun onPositionIconButtonClick(view: View){
+        if(locationOverlay.isMyLocationEnabled){
+            //switch off
+            locationOverlay.disableMyLocation()
+            //set image on respective button
+            setLocationIconEnabled(false)
+            if(context!=null) {
+                if (LocationUtils.isLocationEnabled(context)) {
+                    //show message
+                    Toast.makeText(context, R.string.location_disabled, Toast.LENGTH_SHORT).show()
+                }
+            }
+        } else{
+            //switch on
+            locationOverlay.enableMyLocation()
+            if(context!=null) {
+                if(!Permissions.anyLocationPermissionsGranted(context)) {
+                    locationRequestResLauncher.launch(Permissions.LOCATION_PERMISSIONS)
+                    Toast.makeText(context, R.string.enable_position_message_map, Toast.LENGTH_SHORT).show()
+                }
+                else if (LocationUtils.isLocationEnabled(context)) {
+                    //set image on button
+                    setLocationIconEnabled(true)
+                    //show message
+                    Toast.makeText(context, R.string.location_enabled, Toast.LENGTH_SHORT).show()
+                } else{
+                    Toast.makeText(context, R.string.map_location_disabled_device, Toast.LENGTH_SHORT).show()
+                }
+            }
+        }
+    }
+
     private fun initializeMap(rootView : View){
         val ctx = requireContext().applicationContext
         Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx))
@@ -368,16 +426,7 @@
         map.let {
             it.setTileSource(TileSourceFactory.MAPNIK)
 
-            locationOverlay = LocationOverlay.createLocationOverlay(true, it, requireContext(), object : LocationOverlay.OverlayCallbacks{
-                override fun onDisableFollowMyLocation() {
-                    Log.d(DEBUG_TAG, "Follow location disabled")
-                }
-
-                override fun onEnableFollowMyLocation() {
-                    Log.d(DEBUG_TAG, "Follow location enabled")
-                }
-
-            })
+            locationOverlay = LocationOverlay.createLocationOverlay(true, it, requireContext(), locationOverlayResponder)
             locationOverlay.disableFollowLocation()
 
             stopsOverlay = FolderOverlay()
@@ -409,9 +458,7 @@
                         mapViewModel.currentZoom.value!!,null,null)
                     //controller.setCenter(GeoPoint(mapViewModel.currentLat.value!!, mapViewModel.currentLong.value!!))
                     //controller.setZoom(mapViewModel.currentZoom.value!!)
-
                  */
-
                 }
             mapController.setZoom(zoom)
             mapController.setCenter(centerMap)
@@ -424,7 +471,6 @@
 
             zoomToCurrentPattern()
             firstInit = false
-
         }
 
 
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/MainScreenFragment.java
@@ -53,6 +53,7 @@
 import it.reyboz.bustorino.middleware.BarcodeScanUtils;
 import it.reyboz.bustorino.util.LocationCriteria;
 import it.reyboz.bustorino.util.Permissions;
+import org.jetbrains.annotations.NotNull;
 
 import static it.reyboz.bustorino.backend.utils.getBusStopIDFromUri;
 import static it.reyboz.bustorino.util.Permissions.LOCATION_PERMISSIONS;
@@ -92,11 +93,11 @@
      */
     private static final int SEARCH_BY_NAME = 0;
     private static final int SEARCH_BY_ID = 1;
-    private static final int SEARCH_BY_ROUTE = 2; // TODO: implement this -- https://gitpull.it/T12
+    //private static final int SEARCH_BY_ROUTE = 2; // implement this -- DONE!
     private int searchMode;
     //private ImageButton addToFavorites;
     //// HIDDEN BUT IMPORTANT ELEMENTS ////
-    FragmentManager fragMan;
+    FragmentManager childFragMan;
     Handler mainHandler;
     private final Runnable refreshStop = new Runnable() {
         public void run() {
@@ -105,8 +106,8 @@
             ArrivalsFetcher[] arrivalsFetchers = new ArrivalsFetcher[fetcherList.size()];
             arrivalsFetchers = fetcherList.toArray(arrivalsFetchers);
 
-            if (fragMan.findFragmentById(R.id.resultFrame) instanceof ArrivalsFragment) {
-                ArrivalsFragment fragment = (ArrivalsFragment) fragMan.findFragmentById(R.id.resultFrame);
+            if (childFragMan.findFragmentById(R.id.resultFrame) instanceof ArrivalsFragment) {
+                ArrivalsFragment fragment = (ArrivalsFragment) childFragMan.findFragmentById(R.id.resultFrame);
                 if (fragment == null){
                     //we create a new fragment, which is WRONG
                     Log.e("BusTO-RefreshStop", "Asking for refresh when there is no fragment");
@@ -166,7 +167,7 @@
 
                     Log.d(DEBUG_TAG, "Permissions for location are: "+result);
                     if(Boolean.TRUE.equals(result.get(Manifest.permission.ACCESS_COARSE_LOCATION))
-                            && Boolean.TRUE.equals(result.get(Manifest.permission.ACCESS_FINE_LOCATION))){
+                            || Boolean.TRUE.equals(result.get(Manifest.permission.ACCESS_FINE_LOCATION))){
                         locationPermissionGranted = true;
                         Log.w(DEBUG_TAG, "Starting position");
                         if (mListener!= null && getContext()!=null){
@@ -178,7 +179,7 @@
                         //showNearbyStopsFragment();
                         Log.d(DEBUG_TAG, "We have location permission");
                         if(pendingNearbyStopsFragmentRequest){
-                            showNearbyFragmentIfNeeded(cr);
+                            showNearbyFragmentIfPossible();
                             pendingNearbyStopsFragmentRequest = false;
                         }
                     }
@@ -203,7 +204,7 @@
                 //pendingNearbyStopsRequest = false;
                 if (getContext()!= null && !isNearbyFragmentShown())
                     //mainHandler.post(new NearbyStopsRequester(getContext(), cr));
-                    showNearbyFragmentIfNeeded(cr);
+                    showNearbyFragmentIfPossible();
             }
         }
 
@@ -227,7 +228,7 @@
                             "we have no location permission");
                 pendingNearbyStopsFragmentRequest = true;
                 //mainHandler.post(new NearbyStopsRequester(getContext(), cr));
-                showNearbyFragmentIfNeeded(cr);
+                showNearbyFragmentIfPossible();
             }
         }
 
@@ -313,8 +314,8 @@
         searchButton.setOnClickListener(this::onSearchClick);
 
         // Fragment stuff
-        fragMan = getChildFragmentManager();
-        fragMan.addOnBackStackChangedListener(() -> Log.d("BusTO Main Fragment", "BACK STACK CHANGED"));
+        childFragMan = getChildFragmentManager();
+        childFragMan.addOnBackStackChangedListener(() -> Log.d("BusTO Main Fragment", "BACK STACK CHANGED"));
 
         fragmentHelper = new FragmentHelper(this, getChildFragmentManager(), getContext(), R.id.resultFrame);
         setSearchModeBusStopID();
@@ -430,7 +431,7 @@
                         pendingNearbyStopsFragmentRequest = true;
                     }
                     else {
-                        showNearbyFragmentIfNeeded(cr);
+                        showNearbyFragmentIfPossible();
                     }
                 } else {
                     //The Introductory Activity is about to be started, hence pause the request and show later
@@ -462,7 +463,7 @@
                 pendingNearbyStopsFragmentRequest = true;
             }
             else {
-                showNearbyFragmentIfNeeded(cr);
+                showNearbyFragmentIfPossible();
             }
             //deactivate flag
             pendingIntroRun = false;
@@ -474,8 +475,21 @@
         } //don't request permission
         // if we have a pending stopID request, do it
         Log.d(DEBUG_TAG, "Pending stop ID for arrivals: "+pendingStopID);
-        //this is the second time we are attaching this fragment
+        //this is the second time we are attaching this fragment ->
         Log.d(DEBUG_TAG, "Waiting for new stop request: "+ suppressArrivalsReload);
+        //TODO: if we come back to this from another fragment, and the user has given again the permission
+        // for the Location, we should show the Nearby Stops
+        if(!suppressArrivalsReload && pendingStopID==null){
+            //none of the following cases are true
+            // check if we are showing any fragment
+            final Fragment fragment = getChildFragmentManager().findFragmentById(R.id.resultFrame);
+            if(fragment==null || swipeRefreshLayout.getVisibility() != View.VISIBLE){
+                //we are not showing anything
+                if(Permissions.anyLocationPermissionsGranted(getContext())){
+                    showNearbyFragmentIfPossible();
+                }
+            }
+        }
         if (suppressArrivalsReload){
             // we have to suppress the reloading of the (possible) ArrivalsFragment
             Fragment fragment = getChildFragmentManager().findFragmentById(R.id.resultFrame);
@@ -603,7 +617,7 @@
     }
     protected boolean isNearbyFragmentShown(){
         Fragment fragment = getChildFragmentManager().findFragmentByTag(NearbyStopsFragment.FRAGMENT_TAG);
-        return (fragment!= null && fragment.isVisible());
+        return (fragment!= null && fragment.isResumed());
     }
 
     /**
@@ -650,14 +664,14 @@
 
     private void actuallyShowNearbyStopsFragment(){
         swipeRefreshLayout.setVisibility(View.VISIBLE);
-        final Fragment existingFrag = fragMan.findFragmentById(R.id.resultFrame);
+        final Fragment existingFrag = childFragMan.findFragmentById(R.id.resultFrame);
         // fragment;
         if (!(existingFrag instanceof NearbyStopsFragment)){
             Log.d(DEBUG_TAG, "actually showing Nearby Stops Fragment");
             //there is no fragment showing
             final NearbyStopsFragment fragment = NearbyStopsFragment.newInstance(NearbyStopsFragment.FragType.STOPS);
 
-            FragmentTransaction ft = fragMan.beginTransaction();
+            FragmentTransaction ft = childFragMan.beginTransaction();
 
             ft.replace(R.id.resultFrame, fragment, NearbyStopsFragment.FRAGMENT_TAG);
             if (getActivity()!=null && !getActivity().isFinishing())
@@ -777,28 +791,23 @@
         requestPermissionLauncher.launch(LOCATION_PERMISSIONS);
     }
 
-    private void showNearbyFragmentIfNeeded(Criteria cr){
-        if(isNearbyFragmentShown()) {
+    private void showNearbyFragmentIfPossible() {
+        if (isNearbyFragmentShown()) {
             //nothing to do
-            Log.w(DEBUG_TAG, "launched nearby fragment request but we already are showing");
+            Log.w(DEBUG_TAG, "Asked to show nearby fragment but we already are showing it");
             return;
         }
-        if(getContext()==null){
+        if (getContext() == null) {
             Log.e(DEBUG_TAG, "Wanting to show nearby fragment but context is null");
             return;
         }
 
-        AppLocationManager appLocationManager = AppLocationManager.getInstance(getContext());
-        final boolean haveProviders = appLocationManager.anyLocationProviderMatchesCriteria(cr);
-        if (haveProviders
-                && fragmentHelper.getLastSuccessfullySearchedBusStop() == null
-                && !fragMan.isDestroyed()) {
+        if (fragmentHelper.getLastSuccessfullySearchedBusStop() == null
+                && !childFragMan.isDestroyed()) {
             //Go ahead with the request
 
             actuallyShowNearbyStopsFragment();
             pendingNearbyStopsFragmentRequest = false;
-        } else if(!haveProviders){
-            Log.e(DEBUG_TAG, "NO PROVIDERS FOR POSITION");
         }
     }
     /////////// LOCATION METHODS //////////
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/NearbyStopsFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
@@ -17,14 +17,19 @@
  */
 package it.reyboz.bustorino.fragments;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 
 import android.content.SharedPreferences;
 import android.location.Location;
+import android.location.LocationManager;
 import android.os.Bundle;
 
+import androidx.activity.result.ActivityResultLauncher;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.core.location.LocationListenerCompat;
+import androidx.core.location.LocationManagerCompat;
 import androidx.fragment.app.Fragment;
 import androidx.lifecycle.Observer;
 import androidx.lifecycle.ViewModelProvider;
@@ -50,6 +55,7 @@
 import it.reyboz.bustorino.adapters.SquareStopAdapter;
 import it.reyboz.bustorino.middleware.AutoFitGridLayoutManager;
 import it.reyboz.bustorino.util.LocationCriteria;
+import it.reyboz.bustorino.util.Permissions;
 import it.reyboz.bustorino.util.StopSorterByDistance;
 import it.reyboz.bustorino.viewmodels.NearbyStopsViewModel;
 import org.jetbrains.annotations.NotNull;
@@ -73,6 +79,7 @@
             }
         }
     }
+    private enum LocationShowingStatus {SEARCHING, FIRST_FIX, DISABLED, NO_PERMISSION}
 
     private FragmentListenerMain mListener;
     private FragmentLocationListener fragmentLocationListener;
@@ -84,9 +91,6 @@
 
     public final static String FRAGMENT_TAG="NearbyStopsFrag";
 
-    //data Bundle
-    private final String BUNDLE_LOCATION =  "location";
-    private final int LOADER_ID = 0;
     private RecyclerView gridRecyclerView;
 
     private SquareStopAdapter dataAdapter;
@@ -106,7 +110,7 @@
     private Integer MAX_DISTANCE = -3;
     private int MIN_NUM_STOPS = -1;
     private int TIME_INTERVAL_REQUESTS = -1;
-    private AppLocationManager locManager;
+    private LocationManager locManager;
 
     //These are useful for the case of nearby arrivals
     private NearbyArrivalsDownloader arrivalsManager = null;
@@ -117,6 +121,8 @@
     private ArrayList<Stop> currentNearbyStops = new ArrayList<>();
     private NearbyArrivalsDownloader nearbyArrivalsDownloader;
 
+    private LocationShowingStatus showingStatus = LocationShowingStatus.NO_PERMISSION;
+
     private final NearbyArrivalsDownloader.ArrivalsListener arrivalsListener = new NearbyArrivalsDownloader.ArrivalsListener() {
         @Override
         public void setProgress(int completedRequests, int pendingRequests) {
@@ -172,7 +178,7 @@
         if (getArguments() != null) {
             setFragmentType(FragType.fromNum(getArguments().getInt(FRAGMENT_TYPE_KEY)));
         }
-        locManager = AppLocationManager.getInstance(getContext());
+        locManager = (LocationManager) requireContext().getSystemService(Context.LOCATION_SERVICE);
         fragmentLocationListener = new FragmentLocationListener();
         if (getContext()!=null) {
             globalSharedPref = getContext().getSharedPreferences(getString(R.string.mainSharedPreferences), Context.MODE_PRIVATE);
@@ -205,19 +211,23 @@
         switchButton.setOnClickListener(v -> switchFragmentType());
         Log.d(DEBUG_TAG, "onCreateView");
 
+        final Context appContext =requireContext().getApplicationContext();
         DatabaseUpdate.watchUpdateWorkStatus(getContext(), this, new Observer<List<WorkInfo>>() {
+            @SuppressLint("MissingPermission")
             @Override
             public void onChanged(List<WorkInfo> workInfos) {
                 if(workInfos.isEmpty()) return;
 
                 WorkInfo wi = workInfos.get(0);
-                if (wi.getState() == WorkInfo.State.RUNNING && locManager.isRequesterRegistered(fragmentLocationListener)) {
-                    locManager.removeLocationRequestFor(fragmentLocationListener);
+                if (wi.getState() == WorkInfo.State.RUNNING && fragmentLocationListener.isRegistered) {
+                    locManager.removeUpdates(fragmentLocationListener);
+                    fragmentLocationListener.isRegistered = true;
                     dbUpdateRunning = true;
                 } else{
                     //start the request
-                    if(!locManager.isRequesterRegistered(fragmentLocationListener))
-                        locManager.addLocationRequestFor(fragmentLocationListener);
+                    if(!fragmentLocationListener.isRegistered){
+                        requestLocationUpdates();
+                    }
                     dbUpdateRunning = false;
                 }
             }
@@ -237,9 +247,27 @@
                 showStopsInViews(currentNearbyStops, lastPosition);
             }
         });
+        if(Permissions.anyLocationPermissionsGranted(appContext)){
+            setShowingStatus(LocationShowingStatus.SEARCHING);
+        } else {
+            setShowingStatus(LocationShowingStatus.NO_PERMISSION);
+
+        }
         return root;
     }
 
+    //because linter is stupid and cannot look inside *anyLocationPermissionGranted*
+    @SuppressLint("MissingPermission")
+    private boolean requestLocationUpdates(){
+        if(Permissions.anyLocationPermissionsGranted(requireContext())) {
+            locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+                    3000, 10.0f, fragmentLocationListener
+            );
+            fragmentLocationListener.isRegistered = true;
+            return true;
+        } else return false;
+    }
+
 
 
     /**
@@ -257,6 +285,40 @@
 
         }
     }
+    private void setShowingStatus(@NonNull LocationShowingStatus newStatus){
+        if(newStatus == showingStatus){
+            Log.d(DEBUG_TAG, "Asked to set new displaying status but it's the same");
+            return;
+        }
+        switch (newStatus){
+            case FIRST_FIX:
+                circlingProgressBar.setVisibility(View.GONE);
+                loadingTextView.setVisibility(View.GONE);
+                gridRecyclerView.setVisibility(View.VISIBLE);
+                messageTextView.setVisibility(View.GONE);
+                break;
+            case NO_PERMISSION:
+                circlingProgressBar.setVisibility(View.GONE);
+                loadingTextView.setVisibility(View.GONE);
+                messageTextView.setText(R.string.enable_position_message_nearby);
+                messageTextView.setVisibility(View.VISIBLE);
+                break;
+            case DISABLED:
+                if (showingStatus== LocationShowingStatus.SEARCHING){
+                    circlingProgressBar.setVisibility(View.GONE);
+                    loadingTextView.setVisibility(View.GONE);
+                }
+                messageTextView.setText(R.string.enableGpsText);
+                messageTextView.setVisibility(View.VISIBLE);
+                break;
+            case SEARCHING:
+                circlingProgressBar.setVisibility(View.VISIBLE);
+                loadingTextView.setVisibility(View.VISIBLE);
+                gridRecyclerView.setVisibility(View.GONE);
+                messageTextView.setVisibility(View.GONE);
+        }
+        showingStatus = newStatus;
+    }
 
 
     @Override
@@ -270,6 +332,8 @@
         }
         Log.d(DEBUG_TAG, "OnAttach called");
         viewModel =  new ViewModelProvider(this).get(NearbyStopsViewModel.class);
+
+
     }
 
     @Override
@@ -277,7 +341,8 @@
         super.onPause();
 
         gridRecyclerView.setAdapter(null);
-        locManager.removeLocationRequestFor(fragmentLocationListener);
+        locManager.removeUpdates(fragmentLocationListener);
+        fragmentLocationListener.isRegistered = false;
         Log.d(DEBUG_TAG,"On paused called");
     }
 
@@ -285,8 +350,9 @@
     public void onResume() {
         super.onResume();
         try{
-            if(!dbUpdateRunning && !locManager.isRequesterRegistered(fragmentLocationListener))
-                    locManager.addLocationRequestFor(fragmentLocationListener);
+            if(!dbUpdateRunning && !fragmentLocationListener.isRegistered) {
+                requestLocationUpdates();
+            }
         } catch (SecurityException ex){
             //ignored
             //try another location provider
@@ -519,12 +585,10 @@
     /**
      * Local locationListener, to use for the GPS
      */
-    class FragmentLocationListener implements AppLocationManager.LocationRequester{
+    class FragmentLocationListener implements LocationListenerCompat {
 
-        private int oldLocStatus = -2;
-        private LocationCriteria cr;
         private long lastUpdateTime = -1;
-
+        public boolean isRegistered = false;
 
         @Override
         public void onLocationChanged(Location location) {
@@ -548,6 +612,27 @@
             Log.d("BusTO:NearPositListen","can start request for stops: "+ !dbUpdateRunning);
         }
 
+        @Override
+        public void onProviderEnabled(@NonNull String provider) {
+            Log.d(DEBUG_TAG, "Location provider "+provider+" enabled");
+            if(provider.equals(LocationManager.GPS_PROVIDER)){
+                setShowingStatus(LocationShowingStatus.SEARCHING);
+            }
+        }
+
+        @Override
+        public void onProviderDisabled(@NonNull String provider) {
+            Log.d(DEBUG_TAG, "Location provider "+provider+" disabled");
+            if(provider.equals(LocationManager.GPS_PROVIDER)) {
+               setShowingStatus(LocationShowingStatus.DISABLED);
+            }
+        }
+
+        @Override
+        public void onStatusChanged(@NonNull @NotNull String provider, int status, @Nullable @org.jetbrains.annotations.Nullable Bundle extras) {
+            LocationListenerCompat.super.onStatusChanged(provider, status, extras);
+        }
+        /*
         @Override
         public void onLocationStatusChanged(int status) {
             switch(status){
@@ -587,5 +672,7 @@
         public void onLocationDisabled() {
 
         }
+
+         */
     }
 }
diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/ScreenBaseFragment.java b/app/src/main/java/it/reyboz/bustorino/fragments/ScreenBaseFragment.java
--- a/app/src/main/java/it/reyboz/bustorino/fragments/ScreenBaseFragment.java
+++ b/app/src/main/java/it/reyboz/bustorino/fragments/ScreenBaseFragment.java
@@ -1,17 +1,22 @@
 package it.reyboz.bustorino.fragments;
 
+import android.Manifest;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.view.View;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.Toast;
 
+import androidx.activity.result.ActivityResultCallback;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContracts;
 import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
 
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
 import it.reyboz.bustorino.BuildConfig;
 
+import java.util.Map;
+
 import static android.content.Context.MODE_PRIVATE;
 
 public abstract class ScreenBaseFragment extends Fragment {
@@ -62,4 +67,24 @@
         editor.putBoolean(optionName, value);
         editor.apply();
     }
+    public ActivityResultLauncher<String[]> getPositionRequestLauncher(LocationRequestListener listener){
+        return registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<>() {
+            @Override
+            public void onActivityResult(Map<String, Boolean> result) {
+                if (result == null) return;
+
+                if (result.get(Manifest.permission.ACCESS_COARSE_LOCATION) == null ||
+                        result.get(Manifest.permission.ACCESS_FINE_LOCATION) == null)
+                    return;
+                final boolean coarseGranted = Boolean.TRUE.equals(result.get(Manifest.permission.ACCESS_COARSE_LOCATION));
+                final boolean fineGranted = Boolean.TRUE.equals(result.get(Manifest.permission.ACCESS_FINE_LOCATION));
+
+                listener.onPermissionResult(coarseGranted, fineGranted);
+            }
+        });
+    }
+
+    public interface LocationRequestListener{
+        void onPermissionResult(boolean isCoarseGranted, boolean isFineGranted);
+    }
 }
diff --git a/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt b/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt
--- a/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt
+++ b/app/src/main/java/it/reyboz/bustorino/middleware/AppLocationManager.kt
@@ -24,6 +24,7 @@
 import android.os.Bundle
 import android.util.Log
 import androidx.core.content.ContextCompat
+import androidx.core.location.LocationListenerCompat
 import it.reyboz.bustorino.util.LocationCriteria
 import it.reyboz.bustorino.util.Permissions
 import java.lang.ref.WeakReference
@@ -31,6 +32,8 @@
 
 /**
  * Singleton class used to access location. Possibly extended with other location sources.
+ *
+ * 2024: This is far too much. We need to simplify the whole mechanism (no more singleton)
  */
 class AppLocationManager private constructor(context: Context) : LocationListener {
     private val appContext: Context
@@ -259,9 +262,9 @@
         private const val DEBUG_TAG = "BUSTO LocAdapter"
         private var instance: AppLocationManager? = null
         @JvmStatic
-        fun getInstance(con: Context): AppLocationManager? {
+        fun getInstance(con: Context): AppLocationManager {
             if (instance == null) instance = AppLocationManager(con)
-            return instance
+            return instance!!
         }
 
         fun checkLocationPermission(context: Context?): Boolean {
diff --git a/app/src/main/java/it/reyboz/bustorino/middleware/LocationUtils.java b/app/src/main/java/it/reyboz/bustorino/middleware/LocationUtils.java
new file mode 100644
--- /dev/null
+++ b/app/src/main/java/it/reyboz/bustorino/middleware/LocationUtils.java
@@ -0,0 +1,28 @@
+package it.reyboz.bustorino.middleware;
+
+import android.content.Context;
+import android.location.LocationManager;
+import android.os.Build;
+import android.provider.Settings;
+import androidx.core.content.ContextCompat;
+
+public class LocationUtils {
+
+    public static LocationManager getSystemLocationManager(Context context){
+        return ContextCompat.getSystemService(context, LocationManager.class);
+    }
+
+    //thanks to https://stackoverflow.com/questions/10311834/how-to-check-if-location-services-are-enabled
+    public static Boolean isLocationEnabled(Context context) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+            // This is a new method provided in API 28
+            LocationManager lm = getSystemLocationManager(context);
+            return lm.isLocationEnabled();
+        } else {
+            // This was deprecated in API 28
+            int mode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE,
+                    Settings.Secure.LOCATION_MODE_OFF);
+            return (mode != Settings.Secure.LOCATION_MODE_OFF);
+        }
+    }
+}
diff --git a/app/src/main/java/it/reyboz/bustorino/util/Permissions.java b/app/src/main/java/it/reyboz/bustorino/util/Permissions.java
--- a/app/src/main/java/it/reyboz/bustorino/util/Permissions.java
+++ b/app/src/main/java/it/reyboz/bustorino/util/Permissions.java
@@ -41,7 +41,7 @@
         for (String s : providers) {
             Log.d(DEBUG_TAG, "Provider " + s);
         }
-        return providers.size() > 0;
+        return !providers.isEmpty();
     }
     public static boolean isPermissionGranted(Context con,String permission){
         return ContextCompat.checkSelfPermission(con, permission) == PackageManager.PERMISSION_GRANTED;
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -151,6 +151,7 @@
     <string name="enable_position">Attiva o disattiva posizione</string>
     <string name="location_enabled">Posizione attivata</string>
     <string name="location_disabled">Posizione disattivata</string>
+    <string name="map_location_disabled_device">La posizione รจ disabilitata sul dispositivo</string>
 
     <!--
     Arrival times sources
@@ -265,6 +266,8 @@
 
     <string name="grant_location_permission">Abilita accesso alla posizione</string>
     <string name="location_permission_granted">Accesso alla posizione abilitato</string>
+    <string name="location_permission_not_granted">Accesso alla posizione non consentito dall\'utente</string>
+
     <string name="grant_notification_permission">Abilita notifiche</string>
     <string name="notification_permission_granted">Notifiche abilitate</string>
 
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -149,8 +149,9 @@
     <string name="settings_group_database">Database management</string>
     <string name="settings_reset_database">Launch manual database update</string>
 
-    <string name="enable_position_message_map">Allow access to position to show it on the map</string>
-    <string name="enableGpsText">Please enable GPS</string>
+    <string name="enable_position_message_map">Allow access to location to show it on the map</string>
+    <string name="enable_position_message_nearby">Allow access to location to show stops nearby</string>
+    <string name="enableGpsText">Please enable location on the device</string>
     <string name="database_update_msg_inapp">Database update in progress&#8230;</string>
     <string name="database_update_msg_notif">Updating the database</string>
     <string name="database_update_req">Force database update</string>
@@ -172,6 +173,7 @@
     <string name="enable_position">Enable or disable location</string>
     <string name="location_enabled">Location enabled</string>
     <string name="location_disabled">Location disabled</string>
+    <string name="map_location_disabled_device">Location is disabled on device</string>
 
     <!--
     Arrival times sources
@@ -295,6 +297,7 @@
     </string>
     <string name="grant_location_permission">Grant location permission</string>
     <string name="location_permission_granted">Location permission granted</string>
+    <string name="location_permission_not_granted">Location permission has not been granted</string>
 
     <string name="close_tutorial">OK, close the tutorial</string>
     <string name="close_tutorial_short">Close the tutorial</string>