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).
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)?