Hi guys I need some help on how to get the coordinates of the user when you enable the
followUserLocation
on
MapView
. Is there a way on how to do this or are there any possible alternatives to this?
I already did something like this:
import {DeviceEventEmitter} from 'react-native';
import RNALocation from 'react-native-android-location';
import MapView from 'react-native-maps';
componentDidMount() {
DeviceEventEmitter.addListener('updateLocation', function(e: Event) {
console.log(e);
this.setState({lng: e.Longitude, lat: e.Latitude });
}.bind(this));
RNALocation.getLocation();
}
Already used React Native Geolocation https://facebook.github.io/react-native/docs/geolocation.html
but nothing seems to work. It only gives me the initial location of the user and it does not give me some updates when there are changes on user location.
I even used setInterval to keep on calling the API so it can give me new updates on the user location but the coordinates still does not change.
I used fake GPS to move my location or mock my location . . please help thanks a lot.
You can use navigator.geolocation.watchPosition (https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/watchPosition)
const options = options = {
enableHighAccuracy: false,
timeout: 5000,
maximumAge: 0
};
navigator.geolocation.watchPosition((lastPosition) => {
this.setState({lng: lastPosition.coords.longitude, lat: lastPosition.coords.latitude });
}, (error) => {
console.log('Error', error)
}, options);
Anyways, I got it all sorted out. Since there is no way I can listen to user location using the GPS of the mobile device. What I did was I used the code from React Native geolocation
navigator.geolocation.getCurrentPosition(
(position) => {
var initialPosition = JSON.stringify(position);
this.setState({initialPosition});
},
(error) => alert(JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
Loop through it every 1 second and then update the coordinate states (lat and long) if there is a change in coordinates. So far it works smoothly. :)
Related
I am using the native camera (iOS/Android) calling as following:
async function takePhoto() {
const photo = await ImagePicker.launchCameraAsync(cameraOptions);
if (photo.cancelled) {
return '';
}
return photo.uri;
}
Since upgraded from Expo 39 to 42 it is broken (see screenshots)
Portrait
Landscape
It seems to me, that it is beeing opened as Modal. I don't know where to change this.
Expected behaviour:
Display of camera in fullscreen as native camera under iOS
Update: 20210730: Meanwhile it has been opend as a bug/issue:
https://github.com/expo/expo/issues/13614
Any ideas, suggestions - especially in terms of a workaround?
Thanks a lot.
I've done a massive upgrade from EXPO SDK 37 to EXPO SDK 42. Had to change alot of things around camera, location and permissions.
I do not experience this behavior when using the following (I cannot see your import statements or your package versions but this is what I've implemented and experience no issue)
// Import statements...
import * as ImagePicker from 'expo-image-picker';
import * as FileSystem from 'expo-file-system';
import { Camera } from 'expo-camera';
// Code within Component
const takePicture = async () => {
// You MUST ask for permissions first.
const permissions = {
[Camera]: await Camera.requestPermissionsAsync()
};
// If denied let the user know its required.
if (permissions[Camera].status !== 'granted') {
return Promise.reject(new Error('Camera Permission Required'));
}
// Then let them launch the camera and perform any other task
await ImagePicker.launchCameraAsync({
allowsEditing: false
})
.then(({ uri }) => imageProcesser(uri))
.then(res => onImageAdded(res))
.catch((e) => console.log(e));
};
// These are my concerning package versions
"expo-camera": "^11.2.2"
"expo-file-system": "~11.1.3",
"expo-image-picker": "~10.2.2",
"expo": "^42.0.3"
I am building an app using React Native and photo upload is one of its key functions. Here is what I am trying to do:
When the user clicks on the button to open the camera roll, tell whether the user allowed camera access or not.
If the user didn't allow, show an alert to ask the user to turn on the permission from settings to ensure proper experience on the app.
Where should I look at to start tackling this? I am new to programming in general and not familiar at all with native code. I know this is a high-level question so some high-level guidance will be appreciated. Thanks!
You can start at looking at react-native-permissions module. It allows you to ask for any kind of permissions that a mobile app can require, and also the dialogs are handled natively so you dont have to worry about building the alerts yourself.
https://github.com/zoontek/react-native-permissions
Here's an example on how to handle image selection with permissions
import ImagePicker, {
ImagePickerOptions,
ImagePickerResponse,
} from 'react-native-image-picker';
import { openSettings } from 'react-native-permissions';
import { alertWrapper } from './alert';
export const selectPicture = (options: ImagePickerOptions) => {
const pickerPromise = new Promise<ImagePickerResponse>((resolve) => {
try {
ImagePicker.showImagePicker(options, (response: ImagePickerResponse) => {
if (response.didCancel) {
return;
}
if (response.error) {
if (response.error.includes('permissions')) {
alertWrapper('Error', response.error, [
{ text: 'Open Settings', onPress: () => openSettings() },
]);
}
return;
}
resolve(response);
});
} catch (e) {
throw e;
}
});
return pickerPromise;
};
I am currently learning react-native and I am working on a an application that uses Geolocation to find and update my current location and I am following a tutorial for that and in the tutorial I had to use a property with the timeout and maximumAge options.
navigator.geolocation.getCurrentPosition((pozitie)=>{
var lat = parseFloat(position.coords.latitude)
var long = parseFloat(position.coords.longitude)
// create an object with the current position taken from the geolocation chip
var initialLocation = {
latitude = lat,
longitude = long,
// Delta is the viewing angle on the location of the user
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA
}
// Now we are seting initial position to the initial location
this.setState({initialPositionOnTheMap: initialLocation})
// we set the marker to the initial location and then the display follows the marker
// by using the initialLocaiton object that will receive the users current location
this.setState({positionOfTheMarker: initialLocation})
},
// make a function call if an error happens
// we make an allert that parses the error message
(error) => alert(JSON.stringify(error)),
// propertie
{enableHighAccuracy: true, timeout: 2000, maximumAge: 1000})
but it didn't explain what does timeout and maximumAge mean, why do we use them.
I know that these options are used in two methods provided by react-native: getCurrentPosition(Invokes a callback with the latest location) and watchPosition(Invokes a callback whenever the location has changed) but I don't understand what are they doing exactly.
I have asked the creator of the tutorial, and he responded:
Timeout: is a positive value that indicates the maximum time the device is allowed to return a position.
MaximumAge: is a positive value indicating the maximum age in milliseconds of a possible cached position that is acceptable to return. In other words, how old can cached locations be before I should start getting the current location to return.
I've been playing around with React Native, getting custom locations to work and setting the "NSLocationWhenInUseUsageDescription" key. The error, when running on the ios simulator, is this:
{
"code": 2,
"message": "Unable to retrieve location.",
"PERMISSION_DENIED": 1,
"POSITION_UNAVAILABLE": 2,
"TIMEOUT": 3
}
This is what I have, pretty much straight from the Geolocation example page https://facebook.github.io/react-native/docs/geolocation.html
/* eslint no-console: 0 */
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var {
StyleSheet,
Text,
View,
} = ReactNative;
export default class GeolocationExample extends React.Component {
state = {
initialPosition: 'unknown'
};
componentDidMount() {
navigator.geolocation.getCurrentPosition(
(position) => {
var initialPosition = JSON.stringify(position);
this.setState({initialPosition});
},
(error) => alert(JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
}
render() {
return (
<View>
<Text>
<Text style={styles.title}>Initial position: </Text>
{this.state.initialPosition}
</Text>
</View>
);
}
}
var styles = StyleSheet.create({
title: {
fontWeight: '500',
},
});
Any help would be appreciated!
You need to set the location in the Simulator. There is an option for that in simulator menus as described in this question: Set the location in iPhone Simulator
In Simulator navigator, Choose Debug, at bottom choose Location, next choose Apple, then CMD+R to reload and it worked.
As Santosh suggested, you need to set the location in the iOS Simulator: Debug > Location.
Keep in my mind that from time to time, you will get the "PERMISSION_DENIED " error even tho you set the location in the simulator. If this is happening, you need to select a different predefined location and then the error goes away.
Adding an update to Santosh's answer, please note that in my current version of simulator (11.4) the option to set location is found in:
Features -> Location
(Posting this as a new answer since I am not allowed to comment yet).
I was testing on a real device and it was giving the same error.
I just restarted my device and it started working. Anyone who is still facing the issue can give it a try.
So, for those who are still looking for the answer in Physical device
if you're using
import Geolocation from '#react-native-community/geolocation';
then
Geolocation.getCurrentPosition(
info => {console.log(info)},error=>{console.log(error)}});
if you don't handle the error it will throw error or make your app crash.
Now it's iOS Simulator: Features > Location.
Platform: iOS6/OSx Lion.
I'm trying to puzzle out the way Phonegap/Cordova work with navigator.geolocation.watchPosition.
The docs says that the option "maximumAge" is the one that ask the system for retrieve the position.
So with these options:
{ maximumAge: 3000, timeout: 5000, enableHighAccuracy: true }
I espect the position request will be fired every 3 seconds?
And no matter what maximumAge I put the success is fired every 1 second...
Anyone can explain please?
Thanks Bye
Rob
I am currently working around this issue by using getCurrentPosition with a setInterval. I'm not sure what the consequences may be, but this seems to give me the most control and appears to be the most consistent method across platforms.
// call this once
setupWatch(3000);
// sets up the interval at the specified frequency
function setupWatch(freq) {
// global var here so it can be cleared on logout (or whenever).
activeWatch = setInterval(watchLocation, freq);
}
// this is what gets called on the interval.
function watchLocation() {
var gcp = navigator.geolocation.getCurrentPosition(
updateUserLoc, onLocationError, {
enableHighAccuracy: true
});
// console.log(gcp);
}
// do something with the results
function updateUserLoc(position) {
var location = {
lat : position.coords.latitude,
lng : position.coords.longitude
};
console.log(location.lat);
console.log(location.lng);
}
// stop watching
function logout() {
clearInterval(activeWatch);
}