Description of the problem:
I have two methods in my component for getting geolocation, one with capacitor, one with html5/js. The method with html5/js returns a new location each time I call it, the capacitor one does not, it either returns no location or the same location each time. There seems to be a correlation, if I get the location with html5 or even switch to another app that gets location, then the capacitor location will update, but subsequent calls will return the same coordinates/accuracy over an over, even if I move.
Affected platform
OS of the development machine
Other information:
Ionic/Angular 4.0.1
Testing on device with 'ionic build', 'npx cap sync android' and 'npx cap open android' debugging via android studio on samsung galaxy s7.
Capacitor version:
1.0.0-beta.17
node version:
v10.15.0,
npm version:
6.4.1
Steps to reproduce:
async getCurrentPosition() {
const { Geolocation } = Plugins;
Geolocation.getCurrentPosition({timeout: 30000, enableHighAccuracy: true}).then(position => {
this.position = position;
}, error => console.log(error));
}
getCurrentPostionNavigator() {
navigator.geolocation.getCurrentPosition((position) => {
this.navPosition = position;
}, err => {
console.error(err);
this.navPositionErr = `${err.code} ${err.message}`;
}, { timeout: 30000, enableHighAccuracy: true });
}
<ion-card>
<ion-card-header>Capacitor Location</ion-card-header>
<ion-card-content>
<ion-button (click)="getCurrentPosition()">Get Position</ion-button>
<div *ngIf="position">
Lat: {{position.coords.latitude}}<br />
Lng: {{position.coords.longitude}}<br />
Accuracy: {{position.coords.accuracy}}
</div>
<span *ngIf="positionErr">{{positionErr}}</span>
</ion-card-content>
</ion-card>
<ion-card>
<ion-card-header>HTML5 Location</ion-card-header>
<ion-card-content>
<ion-button (click)="getCurrentPostionNavigator()">Get Position</ion-button>
<div *ngIf="navPosition">
Lat: {{navPosition.coords.latitude}}<br />
Lng: {{navPosition.coords.longitude}}<br />
Accuracy: {{navPosition.coords.accuracy}}
</div>
<span *ngIf="navPositionErr">{{navPositionErr}}</span>
</ion-card-content>
</ion-card>
That's by design of the Android SDK API we use, it returns last known location without trying to get one. If you want to get real location better use watchPosition.
There is a PR to use Fused Location Provider https://github.com/ionic-team/capacitor/pull/964
@jcesarmobile Thanks for the suggestion, I've given watchposition a go It works on web, but on android and ios it's not giving me a result on the first attempt, only after I call the function another time do I get coordinates back. I see the gps symbol appear, but no result. It's like the callback doesn't actually get assigned until the 2nd attempt.
async getCurrentPosition() {
const { Geolocation } = Plugins;
let watch = Geolocation.watchPosition({timeout: 30000, enableHighAccuracy: true}, result => {
if (result && result.coords) {
this.position = result;
Geolocation.clearWatch({id: watch});
watch = null;
}
});
}
edit:
Ah, seem related to the result not triggering angular change detection, this seems to work:
getCurrentPosition() {
const { Geolocation } = Plugins;
if (this.positionWatchId) {
Geolocation.clearWatch({id: this.positionWatchId});
this.positionWatchId = null;
}
this.positionWatchId = Geolocation.watchPosition({timeout: 30000, enableHighAccuracy: true}, result => {
this.position = result;
this.changeDetector.detectChanges();
Geolocation.clearWatch({id: this.positionWatchId});
this.positionWatchId = null;
});
}
did you find fixes @coffeymatt ?
@rlaurente It looks like it's been fixed in that pull request but I've not tried it out yet, am currently using a watch instead.
@rlaurente @coffeymatt I tried the latest version of Capacitor and it's still not working with getCurrentPosition(), which is something that is meant to be that way when I understand @jcesarmobile 's answer correctly. For me this feels very weird though and something like this should definitely be mentioned in the documentation, shouldn't it? It took me a long time to recognize this issue and the only thing that helped was opening Google Maps on the phone and then I get the latest current position, which is probably the same value that Google Maps calculated when it became focused.
Also having issues with this but testing in Android Simulator, I dont see any mention of it but just to check does this work in a simulator ?
@coffeymatt Is your example code working on a real Android device? I tried it multiple times now and watchPosition() is simply not working on Android for me. I also did set the timeout to 10000, but it never stops loading. Are you sure that this number is miliseconds? The documentation is unfortunately not saying anything about the dimensional unit.
@REPTILEHAUS Since this isn't working on Android at all for me I guess the simulator should show the exact same behavior.
@jcesarmobile I am very sorry to ask, but if on Android getCurrentPosition() isn't returning the current position, watchPosition() isn't working at all and "Fused Location Provider" is planned for 2.0... is there any other option to solve this issue right now? Thank you very much for your feedback, really appreciate that.
@derWebdesigner Have you find a way to get the current Position with the Watch action on Android?
I have the same issue. On my desktop, the watchPosition generates position data, but not on my Android device.
@ChariereFiedler Unfortunately not yet. getCurrentPosition() is somehow getting the geo position, but not the current one and only the last requested one by Google Maps for example, no matter which options I choose.
Most helpful comment
@coffeymatt Is your example code working on a real Android device? I tried it multiple times now and watchPosition() is simply not working on Android for me. I also did set the timeout to 10000, but it never stops loading. Are you sure that this number is miliseconds? The documentation is unfortunately not saying anything about the dimensional unit.
@REPTILEHAUS Since this isn't working on Android at all for me I guess the simulator should show the exact same behavior.
@jcesarmobile I am very sorry to ask, but if on Android getCurrentPosition() isn't returning the current position, watchPosition() isn't working at all and "Fused Location Provider" is planned for 2.0... is there any other option to solve this issue right now? Thank you very much for your feedback, really appreciate that.