Kreeki
Kreeki

Reputation: 3732

Phonegap/Cordova geolocation not working on Android

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

Answers (14)

Ashutosh Singhai
Ashutosh Singhai

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
  1. The second way is to use the plugin called cordova-plugin-request-location-accuracy
    Install it
    $ cordova plugin add cordova-plugin-request-location-accuracy
    And use the following code

 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

Suhail Mumtaz Awan
Suhail Mumtaz Awan

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

Omar
Omar

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

Maxirus
Maxirus

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

Maurice
Maurice

Reputation: 570

adding the below permission in manifest file solved my issue

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Upvotes: 0

Yuri Giovani
Yuri Giovani

Reputation: 139

If the error code was 3, verify if the location in settings are enabled. This is work for me.

Upvotes: 0

peter_the_oak
peter_the_oak

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

romgar
romgar

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

WuZhonghua
WuZhonghua

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

henryfi
henryfi

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

ASP Force
ASP Force

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

Dipin Krishnan
Dipin Krishnan

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

fastr.de
fastr.de

Reputation: 1523

  • check your config.xml file(s).

delete this line

<preference name="permissions" value="none"/>
  • look into your AndroidManifest.xml

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

Sandeep vashisth
Sandeep vashisth

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

Related Questions