kumar kundan
kumar kundan

Reputation: 2057

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:-

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.

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 .

Upvotes: 22

Views: 18097

Answers (7)

Siddhartha Mukherjee
Siddhartha Mukherjee

Reputation: 2943

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);
    }

Upvotes: 0

kumar kundan
kumar kundan

Reputation: 2057

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.

Upvotes: 6

Asad Riaz
Asad Riaz

Reputation: 1

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);
      });
 }

Upvotes: -1

Justin B
Justin B

Reputation: 29

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);
})

Upvotes: -1

wstudiokiwi
wstudiokiwi

Reputation: 900

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.

Upvotes: -2

Tummala Krishna Kishore
Tummala Krishna Kishore

Reputation: 8271

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" />

Upvotes: -1

Anil
Anil

Reputation: 996

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.

Upvotes: 2

Related Questions