Phonegap - Android Geolocation is not accurate - android

I use cordova
// Platform: android
// 3.5.1
When I use Geolocation
var options = {enableHighAccuracy: true};
navigator.geolocation.getCurrentPosition(that.geoSuccess, that.geoError, options);
this.geoSuccess = function(position) {
console.log("geoSuccess :"+position.coords.latitude+", "+ position.coords.longitude)
that.mylocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
};
I get in the log:
31.4956033, 34.9326514
which is a 3.7 Kilometre from my actual location.
Any idea why? or how to fix?
on ios I get the following position:
31.518463052524, 34.90405467862522
which is my actual position, therefore the code is correct.
When I use google map (on the android device) my position is correct, therefore it's not hardware problem.
in my manifest I have:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />

I noticed this problem as well. However, when I polled my location for change using watchPosition, it fixed it for me. From what I can tell, the initial GPS fix is inaccurate. Given time it closes the distance.
Something like:
watchID = navigator.geolocation.watchPosition(onSuccess, onError, options);
function onSuccess(position) {
var myLatLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(myLatLng);
if(marker!=null)
marker.setMap(null);
marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: 'My Location'
});
}

You need to ask for high accuracy
var options = {enableHighAccuracy: true};
navigator.geolocation.getCurrentPosition(that.geoSuccess, that.geoError, options);
Geolocation options

Related

Ionic 2 / Ionic 3 : How to get current location of a device

None of the answers on stackoverflow worked for me. A lot of them are for Ionic 1 or those answers are deprecated or they are not working for android device.
I have seen a lot of solutions on stackoverflow about getting current location of device but non of them seems to be working for Android .
what i have tried:-
using geolocation.getCurrentPosition() , which is working for IOS and browser but not for Android.
using this.geolocation.watchPosition() , which is working for IOS and browser but not for Android.
using navigator.geolocation.getCurrentPosition(),which is working for IOS and browser but not for Android.
using fiddle solution provided by this question getCurrentPosition() and watchPosition() are deprecated on insecure origins
Anyway , all of these are deprecated by google due to :-
getCurrentPosition() and watchPosition() are deprecated on insecure
origins, and support will be removed in the future. You should
consider switching your application to a secure origin, such as HTTPS.
See goo.gl/rStTGz for more details.
what worked for me is (https://ionicframework.com/docs/native/background-geolocation/ ) & (https://www.joshmorony.com/adding-background-geolocation-to-an-ionic-2-application/ ) both of these are based on background-geolocation plugin but,it's taking almost 50-55 sec on Android device, again it's working fine for ios
The problem with joshmorony(https://www.joshmorony.com/adding-background-geolocation-to-an-ionic-2-application/ ) solution is foreground is not working for Android physical devices but working fine for browser and ios. Background tracking is working fine , which is taking almost 50 sec to give lat & lng for the first time.
Please help me with this. I want a way to get current location in minimum time. For your info, I am using google javascript map sdk / api .
I tried every solution provided by all of you and others also on internet. Finally i found a solution.You can try this plugin cordova-plugin-advanced-geolocation (https://github.com/Esri/cordova-plugin-advanced-geolocation ) from ESRI . But this plugin will work for Android not IOS. For ios you can go with same old approach . i.e - using this.geolocation.getCurrentPosition(...) or this.geolocation.watchPosition(..).
Add cordova-plugin-advanced-geolocation Plugin Like this :-
cordova plugin add https://github.com/esri/cordova-plugin-advanced-geolocation.git
then Add below line at the top of Class / Component
declare var AdvancedGeolocation:any; //at the top of class
Now add these lines inside relevant function of component ( P.S. - I have included code for both Android & IOS)
//**For Android**
if (this.platform.is('android')) {
this.platform.ready().then(() => {
AdvancedGeolocation.start((success) => {
//loading.dismiss();
// this.refreshCurrentUserLocation();
try {
var jsonObject = JSON.parse(success);
console.log("Provider " + JSON.stringify(jsonObject));
switch (jsonObject.provider) {
case "gps":
console.log("setting gps ====<<>>" + jsonObject.latitude);
this.currentLat = jsonObject.latitude;
this.currentLng = jsonObject.longitude;
break;
case "network":
console.log("setting network ====<<>>" + jsonObject.latitude);
this.currentLat = jsonObject.latitude;
this.currentLng = jsonObject.longitude;
break;
case "satellite":
//TODO
break;
case "cell_info":
//TODO
break;
case "cell_location":
//TODO
break;
case "signal_strength":
//TODO
break;
}
}
catch (exc) {
console.log("Invalid JSON: " + exc);
}
},
function (error) {
console.log("ERROR! " + JSON.stringify(error));
},
{
"minTime": 500, // Min time interval between updates (ms)
"minDistance": 1, // Min distance between updates (meters)
"noWarn": true, // Native location provider warnings
"providers": "all", // Return GPS, NETWORK and CELL locations
"useCache": true, // Return GPS and NETWORK cached locations
"satelliteData": false, // Return of GPS satellite info
"buffer": false, // Buffer location data
"bufferSize": 0, // Max elements in buffer
"signalStrength": false // Return cell signal strength data
});
});
} else {
// **For IOS**
let options = {
frequency: 1000,
enableHighAccuracy: false
};
this.watch = this.geolocation.watchPosition(options).filter((p: any) => p.code === undefined).subscribe((position: Geoposition) => {
// loading.dismiss();
console.log("current location at login" + JSON.stringify(position));
// Run update inside of Angular's zone
this.zone.run(() => {
this.currentLat = position.coords.latitude;
this.currentLng = position.coords.longitude;
});
});
}
EDIT : First installation is always going fine. But Sometimes you might get errors for no reason in subsequent installations. To make this error (any error with this plugin ) go away.Follow these steps :
1. Remove this plugin from your project (including config.xml and package.json).
2. Delete/Remove android platform.
3. Delete plugins folder.
4. Now reinstall this plugin again, following the steps above.
I have gone through the problem and find the solution.
the best way to get geolocation of the user is to use this plugin https://ionicframework.com/docs/native/geolocation/
do not forget to add this is app.moudle.ts as its a provider.
by simply adding this code in app component i was able to get location( do not forget to import and add in constructor)
this.geolocation.getCurrentPosition({ enableHighAccuracy: true }).then((resp) => {
console.log(resp);
}, Error => {
console.log(Error);
}).catch(Error => {
console.log(Error);
})
i only have the same error while i was using ionic cordova run
android --livereload that is insecure origin
but when i use ionic serve i can see the response in browser and also after
using ionic cordova run android
just to confirm response in android i check the chrome debugger.
It works for me
import { Geolocation } from '#ionic-native/geolocation/ngx';
import { NativeGeocoder, NativeGeocoderOptions, NativeGeocoderResult } from '#ionic-native/native-geocoder/ngx';
geoencoderOptions: NativeGeocoderOptions = {
useLocale: true,
maxResults: 5
};
constructor(
private geolocation: Geolocation,
private nativeGeocoder: NativeGeocoder
) {
getCurrentLocation() {
this.geolocation.getCurrentPosition()
.then((resp) => {
this.getGeoencoder(resp.coords.latitude, resp.coords.longitude);
}).catch((error) => {
console.log('Error getting location', error);
});
}
//geocoder method to fetch address from coordinates passed as arguments
getGeoencoder(latitude, longitude) {
this.nativeGeocoder.reverseGeocode(latitude, longitude, this.geoencoderOptions)
.then((result: NativeGeocoderResult[]) => {
const address = this.generateAddress(result[0]);
})
.catch((error: any) => {
// alert('Error getting location' + JSON.stringify(error));
});
}
//Return Comma saperated address
generateAddress(addressObj) {
let obj = [];
let address = "";
for (let key in addressObj) {
obj.push(addressObj[key]);
}
obj.reverse();
for (let val in obj) {
if (obj[val].length)
address += obj[val] + ', ';
}
return address.slice(0, -2);
}
you need to provide the permission for Android app as follows:
<feature name="Geolocation">
<param name="android-package" value="org.apache.cordova.GeoBroker" />
</feature>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
I ran into a similar problem. When I build from the terminal with the --prod flag, I no longer see this error since it is now requesting position over https.
Built without --prod flag
Built using the --prod flag
Edit: Sorry for the format, I hope that this makes a little more sense. I used the following function in a service that I could call from anywhere to get the latitude, longitude, accuracy, and timestamp. The key though is using the --prod flag in the terminal when building the app.
this.geolocation.getCurrentPosition().then(position => {
let locationObj = {
lat: position.coords.latitude,
lon: position.coords.longitude,
timestamp: position.timestamp,
accuracy: position.coords.accuracy
};
resolve(locationObj);
})
this method is working for bot android and browser
watchLocation() {
this.watchLocationUpdates = this.geolocation.watchPosition({ maximumAge: 60000, timeout: 25000, enableHighAccuracy: true })
.subscribe(resp => {
this.latitude = resp.coords.latitude;
this.longitude = resp.coords.longitude;
this.altitude = resp.coords.altitude;
this.accuracy = resp.coords.accuracy;
this.altAccuracy = resp.coords.altitudeAccuracy;
this.heading = resp.coords.heading;
this.speed = resp.coords.speed;
this.timestamp = new Date(resp.timestamp);
});
}
I found solution for me: use google api https://www.googleapis.com/geolocation/v1/geolocate?key={API_KEY}
If platform Android I use google api.

Map doesn't work on device

I spent a lot of time trying to figure this out.
I have a map on my application and this map loads the actual location once it is loaded.
For some reason on my viewer (using Ionic Viewer) it works on my local device and on my localhost, but When I test it on my iPhone directly from Xcode, the map don't load.
If I compile an .apk and test it on android, the map don't load either.
.controller('mapaCtrl', function($scope, $compile, $location) {
$scope.goPayment = function() {
$location.path('side-menu/history');
};
var myLatlng = new google.maps.LatLng(34.603711, -58.381585);
var mapOptions = {
center: myLatlng,
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
navigator.geolocation.getCurrentPosition(function(pos) {
map.setCenter(new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude));
var myLocation = new google.maps.Marker({
position: new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude),
map: map,
title: "My Location"
});
google.maps.event.addListener(myLocation, 'click', function() {
infowindow.open(map,myLocation);
});
});
var contentString = "<div><a ng-click='clickTest()'>Pagar Aqui!</a></div>";
var compiled = $compile(contentString)($scope);
var infowindow = new google.maps.InfoWindow({
content: compiled[0]
});
$scope.map = map;
$scope.clickTest = function() {
$location.path('side-menu/pay');
};
})
Any clue?
There may be several things affecting the proper functionality of your app, consider the following:
There could be an issue where the requests to google maps are blocked. Check out the whitelist plugin: https://stackoverflow.com/a/29896923/1956540
Try adding geoLocation permissions, here is an article I found that walks you through the whole thing: http://www.gajotres.net/using-cordova-geoloacation-api-with-google-maps-in-ionic-framework/
It is also important to wrap geolocation code into Ionic deviceready
event, execution will timeout without it:
ionic.Platform.ready(function() {
// Code goes here
}
I'm not sure it's necessary to have these anymore but I know for Android you could verify the permissions needed to exist in AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
There is probably some iOS equivalent that you can search for but I think installing the plugin should work on its own.
--

appcelerator titanium map error

I've been tasked with adding a map to my appcelerator project. I have tried the alloy way (since I'm using alloy in the project). That apparently doesn't work and its been suggested that I create the map in the controller. I have done that below and the call to the map is triggered by an onclick function attached to an icon on the primary window. This seems to work on iOS but causes the app to crash on Android (using a samsung note)
function openMap(){
alert(alertString);
//var map = Alloy.createController('map');
//$.map.show();
//add alert location here -- get the data from the push message that comes in
var payload = Ti.App.Properties.getString("latest_buddy_alert","empty");
if (payload != "empty"){
var messageDetails = parsePushMessage(payload);
}
opera = mapview.createAnnotation({
latitude: messageDetails['lat'], // 43.7000,
longitude: messageDetails['lng'], // 79.4000,
title: alert,
pincolor:Map.ANNOTATION_RED,
});
var winMap = Titanium.UI.createWindow({
title:'Buddy Location',
BackgroundColor:'#fff'
});
var mapview = Titanium.Map.createView({
mapType: Titanium.Map.STANDARD_TYPE,
region: {latitude:lat, longitude:lon, latitudeDelta:0.01, longitudeDelta:0.01},
animate:true,
regionFit:true,
userLocation:true
,annotations: [opera]
});
winMap.add(mapview);
winMap.open();
Titanium.Geolocation.getCurrentPosition(function(e) {
if (e.error) {
Ti.API.log('error: ' + JSON.stringify(e.error) );
return;
}
var region = {
latitude:e.coords.latitude,
longitude:e.coords.longitude,
animate:true,
latitudeDelta:0.04,
longitudeDelta:0.04
};
mapview.setLocation(region);
});
}
As mentioned above, this creates an error which crashes the app:
Location[1,1] undefined
uncaught syntaxerror: unexpected token u
source: undefined
This is totally unhelpful, since I don't use a token 'u' or variable 'u' anywhere in my code. I have used several variations on the code above, all giving the same error.
I have had some small success moving to a webview, which shows the map on apple, but not on android.
Any ideas?

Issue with Coordinates

Using Cord-ova to get device position I experience a weird behavior when trying to access position coordinates using the emulator (also deployed the code on my Galaxy S2 ... same issue).
document.addEventListener( "deviceready", onDeviceReady, false);
function onDeviceReady () {
if (navigator.geolocation) {
var options = { timeout: 10000, enableHighAccuracy: true, maximumAge: Infinity };
navigator.geolocation.getCurrentPosition(locationOnSuccess, locationOnSuccess, options);
} else {
alert("Geoloc does not exists");
}
}
var locationOnSuccess = function (pos){
alert('Latitude: ' + pos.coords.latitude);
}
navigator.geolocation exists as it fires the alert
This says latitude undefined and error I get is
11-13 08:44:05.296: D/CordovaLog(1861): file:///android_asset/www/index.html: Line 55 : Uncaught TypeError: Cannot read property 'latitude' of undefined
11-13 08:44:05.296: E/Web Console(1861): Uncaught TypeError: Cannot read property 'latitude' of undefined at file:///android_asset/www/index.html:55
I'm struggling for 1 day now and cannot find anybody having same issue, probably getting blind at looking for too long?
Anybody to help?
Many thanks, S.
Make sure you have enabled this:
(in app/res/xml/config.xml)
<feature name="Geolocation">
<param name="android-package" value="org.apache.cordova.GeoBroker" />
</feature>
(in app/AndroidManifest.xml)
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
also check if your device supports Geolocation
In PhoneGap's documentation the statement to get location updates is defined like the one below.
navigator.geolocation.getCurrentPosition(onSuccess, onError);
So there are success and error cases. But you are calling the same method for both of the cases. So in the case that you don't have geo locations you cannot get the latitude and longitude values. That could cause the error. Instead of showing the error case in else statement, define an error function that shows this in the error case.
First of all change it to locationOnError
navigator.geolocation.getCurrentPosition(locationOnSuccess, locationOnError, options);
navigator.geolocation.watchPosition(coordinates);
function coordinates(p) {
if (lastTrackedLat == null) {
lastTrackedLat = p.coords.latitude;
}
if (lastTrackedLng == null) {
lastTrackedLng = p.coords.longitude;
}
var lastTrackedLatlng = new google.maps.LatLng(lastTrackedLat,lastTrackedLng);
var lat = p.coords.latitude;
var lng = p.coords.longitude;
var Latlng=new google.maps.LatLng(lat,lng);
}

GPS doesnt' work (Android web application)

I'm writing web application for mobile phones and I need to use geolocation.
I wrote: (javascript)
function GeoLocationStart(){
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(onSuccess,onError);
}
else{
alert("Functionality not available");
}
}
function onSuccess(position) {
var initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
map.setCenter(initialLocation);
var userMarker = new google.maps.Marker({
position: initialLocation,
map: map,
title: "You're here",
icon: face
});
userMarker.setMap(map);
var userhtml = "It's you!";
var UserInfoWindow = new google.maps.InfoWindow({content: userhtml});
google.maps.event.addListener(userMarker, 'click', function() {
UserInfoWindow.open(map, userMarker);
});
};
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
It works fine but without GPS.
Though I set in Android manifest file permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
app doesn't start even searching sattelites. (Of course I checked GPS on my phone, it works in other applications)
How to switch GPS on?
Thanks
I found a solution.
After location had found using wireless network, GPS stopped to work because the goal has been achieved - location is defined!
To continue searching position I wrote
var watchID = navigator.geolocation.watchPosition(onSuccess, onError, { frequency: 3000 });
so GPS launched.

Categories

Resources