Reputation: 3732
I'm having a trouble to get Geolocation working on Android in both emulator (even when I geo fix
over telnet) and on device. Works on iOS, WP8 and in the browser.
When I ask device for location using the following code, I always get an error (in my case custom Retrieving your position failed for unknown reason.
with null
both error code and error message).
Related code:
successHandler = (position) ->
resolve App.Location.create
lat: position.coords.latitude
lng: position.coords.longitude
errorHandler = (error) ->
error = switch error.code
when 1
App.LocationError.create
message: 'You haven\'t shared your location.'
when 2
App.LocationError.create
message: 'Couldn\'t detect your current location.'
when 3
App.LocationError.create
message: 'Retrieving your position timeouted.'
else
App.LocationError.create
message: 'Retrieving your position failed for unknown reason. Error code: ' + error.code + '. Error message: ' + error.message
reject(error)
options =
maximumAge: Infinity # I also tried with 0
timeout: 60000
enableHighAccuracy: true
navigator.geolocation.getCurrentPosition(successHandler, errorHandler, options)
platforms/android/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" />
www/config.xml (just in case)
<feature name="Geolocation">
<param name="android-package" value="org.apache.cordova.GeoBroker" />
</feature>
Using Cordova 3.1.0. Testing on Android 4.2. Plugin installed. Cordova.js included in index.html (other plugins like InAppBrowser are working fine).
$ cordova plugins ls
[ 'org.apache.cordova.console',
'org.apache.cordova.device',
'org.apache.cordova.dialogs',
'org.apache.cordova.geolocation',
'org.apache.cordova.inappbrowser',
'org.apache.cordova.vibration' ]
I'm clueless. Am I missing something?
Upvotes: 20
Views: 42205
Reputation: 29
After a lot of search, I finally found a way using which you can get user's location
The actual problem is that, when you call the method
navigator.geolocation.getCurrentPosition(successHandler, errorHandler, options)
if the device's location service is not turned on, the geolocation doen't work at all, even if it has the permission to access the location. What we need is the location service turned on There are couple of ways you can achieve this
The first one is
1. Use cordova.plugins.diagnostic.switchToLocationSettings()
and get the location turned on manually before you call getCurrentPosition()
function
For achieving this, install a plugin called cordova.plugins.diagnostic by using one of the following ways, based on your os or the framwork
$ cordova plugin add cordova.plugins.diagnostic
$ cordova plugin add cordova.plugins.diagnostic --variable ANDROID_SUPPORT_VERSION=27.+
$ phonegap plugin add cordova.plugins.diagnostic
$ ionic cordova plugin add cordova.plugins.diagnostic
$ cordova plugin add cordova-plugin-request-location-accuracy
cordova.plugins.locationAccuracy.canRequest(function(canRequest){
if(canRequest){
cordova.plugins.locationAccuracy.request(function(){
console.log("Successfully made request to invoke native Location Services dialog");
navigator.geolocation.getCurrentPosition(onSuccess, errorHandler, options)
var onSuccess = function(position) {
alert('Latitude: ' + position.coords.latitude + '\n' +
'Longitude: ' + position.coords.longitude + '\n' +
'Altitude: ' + position.coords.altitude + '\n' +
'Accuracy: ' + position.coords.accuracy + '\n' +
'Altitude Accuracy: ' + position.coords.altitudeAccuracy + '\n' +
'Heading: ' + position.coords.heading + '\n' +
'Speed: ' + position.coords.speed + '\n' +
'Timestamp: ' + position.timestamp + '\n');
};
// onError Callback receives a PositionError object
//
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
}, function(){
console.error("Failed to invoke native Location Services dialog");
});
}else{
// request location permission and try again
}
});
Upvotes: 2
Reputation: 3483
There are issues with cordova-plugin-geolocation latest verions. Try below version
<plugin name="cordova-plugin-geolocation" spec="2.4.3" />
Upvotes: 0
Reputation: 141
Had the same issue with https://github.com/apache/cordova-plugin-geolocation. Solved it by changing this configuration
{ enableHighAccuracy: true }
on getCurrentPosition() and turning 'on' the gps for genymotion.
Upvotes: -1
Reputation: 61
Using Phonegap and Genymotion, the successHandler was never being called when I tried to getCurrentPosition. Adding the options:
{enableHighAccuracy: true, timeout: 2*1000, maximumAge: 0}
fixed this for me.
Upvotes: 6
Reputation: 570
adding the below permission in manifest file solved my issue
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Upvotes: 0
Reputation: 139
If the error code was 3, verify if the location in settings are enabled. This is work for me.
Upvotes: 0
Reputation: 3710
In this thread are a lot of good answers, thx to everybody. I would like to add my solution in case sb encounters the same.
When I launched my Cordova 3.5 app on my Nexus, the GPS service didn't start after this line:
navigator.geolocation.watchPosition(...);
Instead, I got this message:
07-02 14:31:09.932: D/PluginManager(27767): exec() call to unknown plugin: Geolocation
I was confused because there was no Java Geolocation.java
file at all despite of a correct installation of the plugin.
When it got clear by the answer of Natsu that the Cordova team decided to invoke the native browser object, I commented out the Geolocation plugin in the cordova_plugins.js
:
...
{
"file": "plugins/org.apache.cordova.geolocation/www/Position.js",
"id": "org.apache.cordova.geolocation.Position",
"clobbers": [
"Position"
]
}
/*----
,
{
"file": "plugins/org.apache.cordova.geolocation/www/geolocation.js",
"id": "org.apache.cordova.geolocation.geolocation",
"clobbers": [
"navigator.geolocation"
]
}
----*/
,
{
"file": "plugins/org.apache.cordova.splashscreen/www/splashscreen.js",
"id": "org.apache.cordova.splashscreen.SplashScreen",
"clobbers": [
"navigator.splashscreen"
]
},
...
The rest of the plugin installation remained unchanged. Like this, the original Chrome object doesn't get clobbered and everything works fine.
I am now a bit unsure why the plugin installer adds the JSON entry although it will lead to malfunction. I guess it's just a little design weakness that can't be corrected right now (...or I should dig much deeper into plugin installation).
EDIT: Not to forget to uncomment the metadata:
// "org.apache.cordova.geolocation": "0.3.8",
...
Upvotes: 0
Reputation: 116
According to https://issues.apache.org/jira/browse/CB-5977, Android plugin support has been removed. Yi Ming Kuan said "The reason we went with CB-5977 is that the webview on newer Android versions will get GPS locks more quickly than the native API, hence its removal. Adding the plugin on Android just adds the necessary permissions to use HTML5 Geolocation in your app."
Upvotes: 3
Reputation: 431
I have the same problem with you, but finally I have solved it.
The reason to occur this problem is we always to use browser's navigator.geolocation.getCurrentPosition function to locate the postion,so we must let app use cordova native implementation instead of html5.
Upvotes: 0
Reputation: 69
My solution was to use the native HTML5 geolocation support for android/samsung if it existed:
// BEFORE the deviceready event has fired:
// Check if HTML5 location support exists
app.geolocation = false;
if(navigator.geolocation) {
app.geolocation = navigator.geolocation;
}
// AFTER the deviceready event:
if(app.geolocation) {
var locationService = app.geolocation; // native HTML5 geolocation
}
else {
var locationService = navigator.geolocation; // cordova geolocation plugin
}
locationService.getCurrentPosition(
function(pos) {
},
function(error) {
},
{enableHighAccuracy: true, timeout: 15000}
);
For all the samsung devices that I tested with, enableHighAccuracy had to be 'true' for this to work. With non-samsung devices such as the Nexus 7, enableHighAccuracy could be set to 'false' as well.
Upvotes: 6
Reputation: 161
Try options this way to see if it works for you as it has for me:
var options = { enableHighAccuracy: true };
navigator.geolocation.getCurrentPosition(onSuccess, onError, options);
Upvotes: 15
Reputation: 1280
Try this,
Delete the geolocation plugin
cordova plugin rm org.apache.cordova.geolocation
However, ensure that AndroidManifest.xml and config.xml properties remains as such
(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" />
And for iOS in config.xml
<feature name="Geolocation">
<param name="ios-package" value="CDVLocation" />
</feature>
Then, build the application using CLI and run the application on device/emulator. You would find that you now get Error code as well as the message onError for getlocation.
MORE INFO: Even after doing the above steps you might get the timeout message consistently even after you setting {timeout:10000}
. The solution for this is quite funny, just switch off your device and turn it on and run the application again. You should be surprised to see that working, just like me!
Upvotes: 6
Reputation: 1523
delete this line
<preference name="permissions" value="none"/>
check that all <uses-permission...>
lines and the <uses-sdk...>
line are located before the <application...>
tag.
after that uninstall the application manually on the phone and install it again.
hope that helps.
lg
fastrde
Upvotes: 2
Reputation: 1098
I think your are adding plugin manually. use the command:(strictly if you are using CLI build)
phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation.git
Upvotes: 1