I am in the process of building a mobile application that relies heavily on the user's current location. Until recently, I could easily enter custom coordinates into my simulator Debug -> Location and have my app reflect that change. I recently upgraded to react-native 0.41.1 and my app can no longer register the change in location.
My stack:
react: 15.4.2
react-native: 0.41.1
xcode: 8.2.1
mac os sierra
ios 10.2
My code:
componentDidMount() {
//this._getUserLocation();
navigator.geolocation.getCurrentPosition(
(position) => {
var initialPosition = JSON.stringify(position);
console.log(initialPosition);
},
(error) => alert(JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
}
I have all the correct location permissions in my info.plist, and I have tried numerous ways of removing, re-adding, removing from location services in settings and reallowing the permission, etc. But I continue to get the same results.
My app will load whatever the Debug -> Location is set to on boot, and then not register any change I make to simulate a new location.
example:
On boot it loads:
{"coords": {"speed":0,"longitude":-122.0312186,"latitude":37.33233141,"accuracy":5,"he ading":-1,"altitude":0,"altitudeAccuracy":-1},"timestamp":1488260204384.006}
That's Apple HQ. I then go to Debug -> Location and change to custom coordinates, reload my app, and I get the same output. This used to not be the case. I can try any new coordinates and it's always the same. Though sometimes, if I change the coordinates and reboot, it will load with the new coordinates, and then the problem repeats itself.
Changing the maximumAge value has no effect.
Any help at all would be greatly appreciated. I've been at this issue for a few weeks now and totally stuck.
Thanks in advance.
Related
I am creating a fitness application in react-native 0.66.1. To manage my pages, I use react-navigation 6.
My cover page, HomeScreen, allows to load user data before actually entering the application :
import { useFocusEffect } from '#react-navigation/native'
const HomeScreen = ({ navigation }) => {
useFocusEffect(
useCallback(() => {
// load user data and app configuration in context
navigation.navigate('AppScreen')
}, [])
)
return (
<View>
<ActivityIndicator />
<Image ... logo />
</View>
)
}
On one of my pages (StartGymScreen), I have a countdown using the react-native library react-native-countdown-circle-timer.
Everything works fine but sometimes when I put the app in the background and come back to it, it fully recharges via HomeScreen. My countdown is therefore lost (I have to come back to StartGymScreen and restart it).
I think (but I'm not sure) that this is a normal situation and that "Android" sometimes turns off apps to conserve battery power.
But I have a few questions :
I did not find anything on the react-native documentation, what explains this ?
Is it possible to prevent this? Sometimes the application restarts after 1 minute of background. Sometimes 2, sometimes 3 ... it's very random.
I sometimes use another fitness app (Hercules) which also has a countdown timer but not this problem, how does it do ?
As you said, this is normal behavior and not related to your application. The android os will handle these jobs for your applications.
There are some settings in the phone to limit your application from running in the background. But it's not the ideal way to manage this issue.
All your needs are to keep running your application in the background.
So, there are some solutions like using headless Js. read more on RN documentation. You can create an unstoppable service for your application. You can use this article to do it.
Also, there is a solution with using react-native-background-actions package.
Im doing an "Uber like" app, and using a websocket to keep an eye on the driver (to get his location). Within 1~10 minutes (it varies) and on background, the connection dies, i'm guessing it's not the websocket, the onclose event doesn't even return anything. It's like something is force closing the app or something alike. Anyone has any clue on what is happening? I'm using Expo.
The websocket function is this one: (i'm using reconnecting-websocket)
connect = () => {
var URL = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXxx';
var token = 'XXXXXXXXXXXXXXXXXXXXXXX';
var ws = new ReconnectingWebSocket(URL,token, { debug: true, reconnectInterval: 3000 });
ws.onopen = () => {
console.log('Entered!');
}
ws.onclose = () => {
console.log('Left!')
}
}
The "Entered!" is printed, the "Left!" isn't.
Operating system is killing your app after some period in the background. You can use Headless JS (Android only) to run some background tasks periodically (can't keep websocket connection active though) or things like react-native-background-task or react-native-background-fetch that work on both iOS and Android but are not able to run tasks more frequently than once per 15 minutes. To my knowledge, the only way to achieve what you want is to write separate native modules for Android and iOS suited for your needs (and that's still not guaranteed to work, as operating systems nowadays are eager to kill any battery draining background apps). Consider enforcing foreground mode for your app
For an expo app that is not ejected and runs in the background, my goal is to do a location tracking periodically or when location changes.
I am sticking with Expo's base APIs including its Location, TaskManager API.
Location tracking only works for a first couple of times before it completely stops.
Following what was written in the Documentation here: https://docs.expo.io/versions/v32.0.0/sdk/location/, I was able to make an app that tracks location with the API: Location.startLocationUpdatesAsync of Expo. I had also defined a "Expo.TaskManager" and this should log a new location every time a new location is detected.
However, if the app runs in the background for more than a few seconds, geolocation service tracking no longer works. No further logging will not be written in the console.
Define Task:
TaskManager.defineTask(PUSH_LOCATION_IN_BACKGROUND, ({ data, error }) => {
if (error) {
return;
}
if (data) {
const { locations } = data;
console.log('locations are ', locations)
}
});
Start (register) the task:
await Location.startLocationUpdatesAsync('PUSH_LOCATION_IN_BACKGROUND', {
accuracy: Location.Accuracy.Balanced,
distanceInterval:3,
});
I expect that every time I change the location of my device (by either moving to a new location of faking my GPS data), I would receive a logging of the new location if the app runs in the background. However, as soon as the app enters the background, it only logs the data for a couple of times before it completely stops.
I would expect that the app will run stably in the background and if possible, avoid being killed by the OS even if the resource consumption in the device is already high.
And as someone who is not experienced in Android developemnt, do I need to set up an undismissable (user cannot dismiss it nor remove it by clicking on it) notification in order to keep the background task of the app alive? Can I do it with an unejected Expo app.
Issue Description::
I am working on react native tracking application. Basically users check in from a certain place and they need to reach at the destination. Using this application we are finding out the path they are following. I need to get a geocodes from users check in location to destination to track the path he is following.
Now it builds a clean path in case of Android device, but having an issue with ios. For ios it takes a huge variation inside code.
I have tested this by traveling to same place using both devices(ios and android). For Android it's generates a exact latitude longitude values, but for ios there is a huge variation. Why this is happening. I have followed the official doc of react native for geolocation setup.
You can check this link:: https://facebook.github.io/react-native/docs/geolocation.html#ios
We are using react native geolocation service package, GitHub link
This is happening when I have updated react native version to 0.58
Code::
this.watchId = Geolocation.watchPosition((response) => {
this.currentWatchLocationTimeout = this.currentWatchLocationTimeout + WATCH_LOCATION_TIMEOUT;
currentPosition.lat = this.convertToDecimalPoints(response.coords.latitude);
currentPosition.lng = this.convertToDecimalPoints(response.coords.longitude);
//... additional code
}, (error) => {
this.onGeolocationErrorOccurCallback(error);
}, {
enableHighAccuracy: true,
distanceFilter: 5,
showLocationDialog: true
});
Additional Information ::
React Native: 0.58
react-native-geolocation-service: 2.0.0
platform: ios(only)
Best solution that works for me is changes inside react native geolocation files. You need to replace some lines of code. Go inside react native package,
react-native/Libraries/Geolocation/RCTLocationObserver.m
Then replace this line::
#define RCT_DEFAULT_LOCATION_ACCURACY kCLLocationAccuracyHundredMeters
with this::
#define RCT_DEFAULT_LOCATION_ACCURACY 0.0
After this replace this line::
.accuracy = [RCTConvert BOOL:options[#"enableHighAccuracy"]] ? kCLLocationAccuracyBest : RCT_DEFAULT_LOCATION_ACCURACY,
with this one::
.accuracy = RCT_DEFAULT_LOCATION_ACCURACY,
You need to directly search for these lines on above mentioned path.
I found this inside git commits, you can also check this link:: link
I'd like to use two geo location watchers in my app. One with useSignificantChangesand one with high accuracy.
The "lowres" watcher would provide my Redux store with approximate locations all the time, whereas the "highres" watcher would be enabled when the user is working in a live view.
Here are the options for the low res watcher
const options = {
enableHighAccuracy: false,
useSignificantChanges: true,
distanceFilter: 500,
};
And the high res watcher:
const options = {
enableHighAccuracy: true,
timeout: 60e3,
maximumAge: 10e3,
};
I have played around with the settings, but I can't see any difference in the output. Both watchers emits the exact same positions at the same time. I'm using the iOS simulator for the moment.
Questions:
I should be able to have several watcher, shouldn't I? What would be the point with the returned watchId otherwise?
Is this a problem only in the simulator?
Have I misunderstood or goofed?
Edit, the actual question is:
Why do I get high frequent accurate gps positions even in "significant changes" mode. This mode is supposed to save battery if I have understood correctly.
Thanks!
The useSignificantChanges option is fairly new and only recently implemented, so you need to make sure that:
You are using a version of React Native that supports it. Based on merge dates, looks to be v0.47+
You are testing on an iOS version that can use it. The Github issue states that this is a new feature that impacts iOS 11, so I presume that you would need at least that version to see any differences.