Check geolocation availability in cordova applications - android

I am working on a cordova based app with some extra functionality, using geolocation.
So, one of the first steps during startup is to to check if geolocation is enabled on the device. The check is using navigator.geolocation.getCurrentPosition and wait for one of the callbacks.
But I just found out, that this JS code doesn't work as expected on all devices (tested on 2 Androids):
function checkPositionAvailability(){
// tested both -> same result
// var options = {maximumAge: 0, timeout: 10000, enableHighAccuracy:true};
var options = {maximumAge: 0, timeout: 10000, enableHighAccuracy:false};
navigator.geolocation.getCurrentPosition(
function(position){
console.log('got a position:');
// ok, geolocation is available
},
function(error){
console.log('got an error:');
console.log('code : ' + error.code);
console.log('message: ' + error.message);
console.log('error.PERMISSION_DENIED = ' + error.PERMISSION_DENIED);
console.log('error.POSITION_UNAVAILABLE = ' + error.POSITION_UNAVAILABLE);
console.log('error.TIMEOUT = ' + error.TIMEOUT);
console.log('error.UNKNOWN_ERROR = ' + error.UNKNOWN_ERROR);
if (error.code == error.PERMISSION_DENIED) {
// -> notify user that geolocation could be enabled
}
},
options);
}
checkPositionAvailability();
the expected behaviour when geolocation is disabled is: the error callback should be called immediately with a POSITION_UNAVAILABLE or PERMISSION_DENIED error code.
This was working on a ancient Huawei 8850 with Android 2.3.5. But not on my brand new Moto G with Android 4.4.4.
On the Moto G I have to wait the full 10 seconds, before I get an TIMEOUT error.
Is this a bug? And if yes, who is responsible: Cordova, the WebView, or Android?
Is there any workaround using cordova? Or do I have to add some java code or a plugin?
Another question is: what about other platforms - will the code above work or not?
It seems, that there IS a way to detect geolocation availability with Android / Java.
When running the GPS Status App on the Moto G I will be notified immediately about a deactivated GPS.
Here's the output of my two devices, running my cordova app:
Huawei:
got an error:
code : 2
message: The last location provider was disabled
error.PERMISSION_DENIED = 1
error.POSITION_UNAVAILABLE = 2
error.TIMEOUT = 3
error.UNKNOWN_ERROR = undefined
Moto G:
got an error:
code : 3
message: Timeout expired
error.PERMISSION_DENIED = 1
error.POSITION_UNAVAILABLE = 2
error.TIMEOUT = 3
error.UNKNOWN_ERROR = undefined
Cordova version is 3.5.0-0.2.7

Related

Phonegap compass plugin not working

I am trying to get a compass function working on my app with no success. Judging by the errors I am inclined to think that the plugin is not being added or the device is not ready. But as far as I can tell I have done both things. I am using phonegap build, so the only code I use to include it is:
<gap:plugin name="org.apache.cordova.device-orientation" version="0.3.9" />
Which as far as I know is all that is required. When I click on the plugins tab in the phonegap build page for my app it shows up as being there.
watchDirection = null;
//Phonegap is ready
var whenDeviceReady = function(){
console.log("deviceready");
console.log(navigator.compass);
var findMyDirection = function(){
console.log("find my heading fired");
watchDirection = navigator.compass.watchHeading(
//onSuccess
function(heading){
console.log(heading);
var magnetDirection = heading.magneticHeading;
$("#movingCompass").css("transform", "rotate(" + magnetDirection + "deg)");
},
//onError
function(error){
console.log('code: ' + error.code +' message: ' + error.message);
},
//Update Frequency
{ frequency: 1000});
}
findMyDirection();
}
//Wait for phonegap to load
document.addEventListener("deviceready", whenDeviceReady, false);
The above code works as expected with the exception of the compass object. The console.log(navigator.compass); returns as undefined. And there is an error on the line which includes watchDirection = navigator.compass.watchHeading( saying Uncaught TypeError: Cannot read property 'watchHeading' of undefined.
It gets listed in the phonegap build list of installed plugins, and I already have the geolocation working with the same code format I have posted above.
#Marty.H, I have working demos here: http://codesnippets.altervista.org/examples/phonegap/demos/PUBLIC.Apps.html Go to the lower half of the page and try pre-built app, Phonegap-Compass-Test. If it works, the top half of the page has the links to github where you can get the source code. --Jesse

navigator.geolocation.getCurrentPosition always getting timeout in Android until GPS/Location is OFF

app.controller('dashboard', function($scope){
$scope.getPosition = function(position){
$scope.acc = position.coords;
$scope.lat = position.coords.latitude;
$scope.lng = position.coords.longitude;
$scope.$apply();
};
$scope.getPositionErr = function(error){
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
};
navigator.geolocation.getCurrentPosition($scope.getPosition, $scope.getPositionErr, {maximumAge: 0, timeout: 6000, enableHighAccuracy:false});
});
I am using Angular JS and Cordova for an Android app.
This code is working fine on desktop but not on Nexus 4 with Lollipop.
Also controller code is executing after deviceready as per requirement from Cordova
I have tried
Setting HighAccuracy to false
Removing geolocation plugin so that it uses default location from Wifi
Device reboot
Clearing browser cache
Airplane mode on/off
Wifi on/off
Mobile data on/off
But I am unable to get lat, long and geolocation always gets timeout.
It only works when I enabled Location/GPS from setting. After enabling it code is working as expected.
navigator.geolocation.getCurrentPosition is only for GPS when option "enableHighAccuracy" is set as 'true'(default). That's why you are not able to get current location via mobile device. About "it is working on desktop", I believe you must have opened GPS setting in your browser.
Usually I used code below t o get position no matter GPS is open or not.
var positionOption = { timeout: 500, enableHighAccuracy: true };
var gpsSunccuss = function(currentPosition) {
//use gps position
};
var gpsFailed = function() {
//use some 3rd party position solution(get position by your device ip)
getPositionBy3rdParty();
};
navigator.geolocation.getCurrentPosition(gpsSunccuss, gpsFailed, positionOption);
On the other hand, you could set enableHighAccuracy as 'false'.
I had identical issue and this fixed it for me
{enableHighAccuracy:false,maximumAge:Infinity, timeout:60000}
I think setting maximumAge to Infinity only works because in that case it just gives you back the previous location when the timeout occurs. I wouldn't consider that working.
you can try this.
{enableHighAccuracy:true, Infinity:Infinity, timeout:2000}

Phonegap Detect Device GPS Status

After hours of search I finally decided to post a question here.
I am using cordova/phonegap version 3 library and trying to build an app based on geolocation.
What I need to do is to check if the user has their GPS enabled before they can do something else but this doesn't seems to be possible as far as i can see.
The code I am using is:
function onDeviceReady() {
// Throw an error if no update is received every 30 seconds
var options = {maximumAge: 0, timeout: 10000, enableHighAccuracy: true};
watchID = navigator.geolocation.watchPosition(onSuccess, onGeoError, options);
}
function onSuccess(position) {
//DO WHATEVER
}
function onGeoError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
I expect an error to be thrown with error.POSITION_UNAVAILABLE message but no matter what I do TIMEOUT error (error.TIMEOUT) gets thrown every single time. I even put the device in flight mode with everything (gps, etc) turned off and still got TIMEOUT error.
Can anyone please suggest a better way to achieve this.
The problem with my application was that I didn't run the build command (cordova prepare) after installing the plugin. Backup your www folder before running 'cordova build' command as this will replace www folder with default content

PhoneGap Geolocation get always a timeout on special devices

I use cordova 2.9.0 with PhoneGap Build. I have written an app where a user can check-in on special location to a special time.
My problem is that when I install de app on various devices I sometimes get always a timout (this occurs only on Android devices). When I restart the device the geolocation works and I get the gps-data. Now I'd like to know if there is another way to resolve this problem.
My code for geolocation in the deviceReady function is:
var geo = cordova.require('cordova/plugin/geolocation');
var optionsGeo = {maximumAge: 0, timeout: 30000, enableHighAccuracy: false};
var watchID = geo.watchPosition(onSuccessGeo, errorGeo, optionsGeo);
function onSuccessGeo(position) {
lat = (position.coords.latitude).toFixed(6);
lon = (position.coords.longitude).toFixed(6);
accuracy = (position.coords.accuracy).toFixed(0);
console.log("Lat " + lat + " Lon " + lon + " & " + accuracy + "m");
}
function errorGeo(error) {
console.log("Geo-Fehler! Code: " + error.code + " Nachricht: " + error.message);
}
I have tried with different timeoutvalues and with enabled HighAccuracy - but nothing helps.
Thanks.
I was also facing this issue, mainly with Samsung android devices. What I found out is that:
If you do not have a SIM card installed in the device, then there will be no gps coordinates (that's only applicable to some devices).
Please make sure that you have <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> set in your android manifest.
You should set enableHighAccuracy:true please see below my settings:
var options = {maximumAge: 0, timeout: 10000, enableHighAccuracy:true};
navigator.geolocation.getCurrentPosition(onSuccess, onError, options);
enableHighAccuracy provides a hint that the application would like to receive the best possible results. By default, the device will attempt to retrieve a Position using network-based methods. Setting this property to true tells the framework to use more accurate methods, such as satellite positioning.
In some cases, developers use geolocation.watchPosition to get more accurate gps results. Can you also try that?
I hope it helps!
I know this question is old but I encountered the same problem today using Cordova 3.5.0 with the geolocation plugin (org.apache.cordova.geolocation 0.3.8).
I solved it by enabling the GPS "HighAccuracy"-mode on the device (android). (Settings -> Location access -> Mode).
The app-user gets a hint that he needs to enable this option in order to use the app...

phonegap geolocation always fail on timeout

I'm using sencha-touch 2.0 and phonegap 2.0.0 in my app to retrieve user's location.
When runing on my locahost, everything works just fine. However, when loading the .apk to my android 15 api's device (using eclipse and the adt plugin), every call to getCurrentLocation or watchPosition never returns...
here is my code:
geoOn: function(){
var geoReady = navigator.geolocation || undefined;
var onSuccess = function(position){
Top5.app.alert('Geolocation success '+String(position.coords.latitude) + ' ' + String(position.coords.longitude),'Geolocation');
var scope = Ext.getCmp('nestedList');
scope.updateDistance(position.coords);
};
var onFailure = function(error){Top5.app.alert('Geolocation failed: '+String(error.code) + ' '+String(error.message),'Geolocation');};
if (geoReady) {
this.watchId = navigator.geolocation.watchPosition(onSuccess ,onFailure,{timeout:6000,maximumAge: 3000,enableHighAccuracy: true});
}
else{
Ext.device.Geolocation.watchPosition({
frequency: 3000, // Update every 3 seconds
callback: function(position) {
this.updateDistance(position.coords);
},
failure: function() {
console.log('Geolocation Failure!');
},
scope:this
});
}
},
geoGet: function(){
var geoReady = navigator.geolocation || undefined;
if (geoReady) {
var onSuccess = function(position){
Top5.app.alert('Geolocation successful!!!');
var scope = Ext.getCmp('nestedList');
scope.updateDistance(position.coords);
};
var onFailure = function(error){Top5.app.alert('Geolocation failed: '+String(error.code) + ' '+String(error.message),'Geolocation');};
navigator.geolocation.getCurrentPosition(onSuccess,onFailure);
}
else{}
},
geoOff:function(){
var geoReady = navigator.geolocation || undefined;
if (geoReady) {
navigator.geolocation.clearWatch(this.watchId);
this.watchId = null;
}
else{
Ext.device.Geolocation.clearWatch();
}
},
updateDistance:function(coords){
Top5.app.alert('updateDist','');
var scope = Ext.getCmp('nestedList');
var lat = coords.latitude,lon = coords.longitude;
var store = scope.getStore();
var i,record;
for(i = 0; i < store.data.all.length; i++)
{
record = store.data.all[i];
if(record.data.locationX){
record.set('distance',Top5.app.getDistance(record.data.locationX,record.data.locationY,lat,lon).toFixed(3));
}
}
}
UPDATE: So I walked out of my building and it worked... I need to go outside more often.
However, when I'm disabling the gps, I thought geoLocation will find my location using wifi connection - but it failes (I'm setting enableHighAccuracy: false). Why is that?
UPDATE: Let me rephrase my question:
Does navigator.geolocation.watchPosition suppose to work both with GPS signal and wifi/g3 signals? How can I detect user location using internet connection only? currently, my code is working only with GPS, and when that option disabled or signal is blocked, geolocation isn't working.
I know that maybe it is too late, but today i struggled with the same issue! The solution turned out to be very simple!
SOLUTION: Reboot the device.
That's all.
The problem is, that you never know when i user will get this kind of bug, so if your application relies heavily on geolocation i recommend you set a timeout in location options navigator.geolocation.getCurrentPosition(geoSuccess, geoError, {timeout: 15000}) and alert user about the problem and possible solution.
P.S.
Keep in mind, that Geolocation can timeout for example if mobile data is turned off too, so reboot won't always fix it. On iPhone it uses cellular data to get your position, but on Android, it looks like the phone does not have access to cellular data unless 3G is turned on
It could sound stupid, but, did you activate the "Use Networks" option?
Go to Settings -> Location and security -> Use networks; and active it. I have passed all the afternoon watching the problem and it was that.
I restarted and restarted. I reset my phone to factory settings.
But nothing worked.
Until I set enablHighAccuracy from true to false.
And... Tada.... it works.
So :
var options;
options = {
maximumAge: 30000,
timeout: 5000,
enableHighAccuracy: false
};
This used to work fine using PhoneGap 2.6.0. I needed to make this change since I'm now using Phonegap 3.3 - tested on a Wiko Cink+ phone.
Try removing the Phonegap plugin geolocation plugin from your project. You won't need to make any changes to your JavaScript code as your device will fall back on the standard HTML5 navigator.geolocation functionality which has the same method signature.
Assuming you're using PhoneGap 3.3, you just need to run:
cordova plugin rm org.apache.cordova.geolocation
If you are running on an emulator, it may be because the device does not have a geolocation set. Try setting the location by running the following, assuming your android emulator is on port 5554:
telnet localhost 5554
geo fix -0.001 51.5
Restart your phone or Go to google map and check if gps is working over there.
I got it working.
I had this happen to a working app after updating PhoneGap to version 3.6.3 from 3.5. After trying many other suggestions Arthur's answer worked. 15 seconds seemed too long to me so I used {timeout: 2000}. I'm guessing the new version is slower as my code worked fine before the update on the same devices. Thought I'd post as well as upvote him as everything I found in Google was about initial setup and mostly irrelevant to my situation.
You just need to add enableHighAccuracy: true, maximumAge: 60000 and then reboot your device.
From my trial and error analysis, its most likely:
1. The version of android you're using. On Lollipop and lower you may need to go to the phones location settings and enable high accuracy settings (using gps, wlan and mobile networks to get location). I had to do this on a kitkat phone.
2. As others have mentioned, you can try changing the settings of getCurrentPosition by either enabling/disabling highaccuracy and adding a timeout.
3.If you're using ngCordova, make sure you installed it right and the location functions are actually being called. Use console to verify
Try This Solution:
window.setInterval(checkPosition, 5000);
function checkPosition() {
function onSuccess(position) {
document.getElementById('result1').innerHTML = position.coords.latitude;
document.getElementById('result2').innerHTML = position.coords.longitude;
}
// onError Callback receives a PositionError object
//
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
navigator.geolocation.getCurrentPosition(onSuccess, onError);
}
I've managed to work it out.... However , I have no idea what actually solved it. All I've done is to change one of my model's structure. Can anyone see the connection to geolocation?

Categories

Resources