React Native GPS Location Detection Challenge on Android & iOS

React Native GPS Location Detection Challenge on Android & iOS


I’m engaged on location detection utilizing GPS in a React Native app. Nonetheless, I’m encountering points on each Android and iOS:

  • Android: Works solely with actual location (ACCESS_FINE_LOCATION), not approximate (ACCESS_COARSE_LOCATION).
  • iOS: The app crashes with a crimson display screen (see screenshot beneath).

red screen on ios

I’m on the lookout for finest practices to deal with GPS location detection correctly for each Android & iOS, guaranteeing compatibility with each new and previous architectures.

Code Implementation

Right here’s the implementation for checking and requesting location permissions:

Checking Location Permission

export const checkLocationPermission = async () => {
   const permission = Platform.OS === 'ios'
      ? Permission.PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
      : Platform.Model >= 29 
         ? Permission.PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION
         : Permission.PERMISSIONS.ANDROID.ACCESS_COARSE_LOCATION;

   attempt {
      const end result = await Permission.examine(permission);
      
      swap (end result) {
         case Permission.RESULTS.UNAVAILABLE:
            console.log('Location characteristic isn't obtainable on this machine');
            return null;

         case Permission.RESULTS.DENIED:
            if (Platform.OS === 'android' && Platform.Model >= 29) {
               const fineResult = await Permission.request(Permission.PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION);
               if (fineResult === Permission.RESULTS.GRANTED) {
                  const coarseResult = await Permission.request(Permission.PERMISSIONS.ANDROID.ACCESS_COARSE_LOCATION);
                  return coarseResult === Permission.RESULTS.GRANTED ? coarseResult : null;
               }
               return null;
            }

            if (Platform.OS === 'ios') {
               const requestResult = await Permission.request(permission);
               if (requestResult === Permission.RESULTS.GRANTED && parseInt(Platform.Model) >= 14) {
                  await Permission.request(Permission.PERMISSIONS.IOS.LOCATION_ACCURACY);
               }
               return requestResult;
            }

            return await Permission.request(permission);

         case Permission.RESULTS.GRANTED:
            if (Platform.OS === 'ios' && parseInt(Platform.Model) >= 14) {
               await Permission.request(Permission.PERMISSIONS.IOS.LOCATION_ACCURACY);
            }
            return end result;

         case Permission.RESULTS.BLOCKED:
            console.log('Location permission is denied and never requestable anymore');
            return end result;

         default:
            return null;
      }
   } catch (error) {
      console.error('Error checking location permission:', error);
      return null;
   }
};

Requesting GPS Activation

   const onRequestTurnOnGPS = async () => {
      setLoadingGPS(true);
      attempt {
         const enabled = await getGPSStatus();
         if (enabled) {
            console.log("Enabled GPS");
            await dispatch(addUserLocationLog());
            setLoadingGPS(false);
         } else {
            console.log("Disabled GPS");
            setLoadingGPS(false);
            ToastInterface.showInfo(translate('message.loc_device_body'));
         }
      } catch (error) {
         setLoadingGPS(false);
         AppLog.sendLog({title: 'GPS request error', error});
         ToastInterface.showError(translate('message.loc_device_error'));
      }
   };

Logging Consumer Location


export const addUserLocationLog = () => async (dispatch, getState) => {
   return new Promise(async (resolve, reject) => {
      attempt {
         const permResult = await checkLocationPermission();
         if (permResult !== RESULTS.GRANTED) {
            await dispatch(updateUserLocation(null, true, true));
            resolve();
            return;
         }

         Geolocation.getCurrentPosition(
            async place => {
               await dispatch(updateUserLocation(place?.coords, true));
               resolve();
            },
            async error => {
               await dispatch(updateUserLocation(null, true, true));
               // AppLog.sendLog({title: 'get present place error', error});
               resolve();
            },
            {
               enableHighAccuracy: true,
               timeout: 15000,
               maximumAge: 10000,
            },
         );
      } catch (e) {
         AppLog.sendLog({title: 'addUserLocationLog error', error: e});
         resolve();
      }
   });
};

Questions & Anticipated Habits

  • Why does Android solely work with actual location (ACCESS_FINE_LOCATION) however not with approximate (ACCESS_COARSE_LOCATION)?
  • Why does iOS crash with a crimson display screen?
  • What are the perfect practices for guaranteeing compatibility throughout each iOS and Android (supporting each new & previous architectures)?

Any insights or suggestions can be tremendously appreciated!

Leave a Reply

Your email address will not be published. Required fields are marked *