Ionic 2 / Ionic 3:如何获取设备的当前位置

时间:2017-09-07 11:00:55

标签: android ionic-framework google-maps-api-3 ionic2 ionic3

请勿将此问题标记为重复, stackoverflow 上的答案均不适合我。其中很多是 Ionic 1 或者这些答案已被弃用或者它们不适用于Android设备。

我已经在 stackoverflow 上看到了很多关于获取设备当前位置的解决方案,但其中没有解决方案似乎适用于Android。

我的尝试: -

  • 使用geolocation.getCurrentPosition(),适用于 IOS 浏览器,但不适用于 Android

  • 使用this.geolocation.watchPosition(),适用于 IOS 浏览器,但不适用于 Android

  • 使用navigator.geolocation.getCurrentPosition(),适用于 IOS 浏览器,但不适用于 Android

  • 使用此问题提供的小提琴解决方案getCurrentPosition() and watchPosition() are deprecated on insecure origins

无论如何,谷歌所有这些都是已弃用,原因是: -

  在不安全的情况下,不推荐使用

getCurrentPosition()和watchPosition()   起源和支持将在未来被删除。你应该   考虑将您的应用程序切换到安全的来源,例如HTTPS。   有关详细信息,请参阅goo.gl/rStTGz。

joshmorony https://www.joshmorony.com/adding-background-geolocation-to-an-ionic-2-application/)解决方案的问题是前景不适用于Android物理设备,但适用于浏览器和ios。背景跟踪工作正常,这将花费将近50秒来给予lat&这是第一次。

请帮我解决这个问题。我想要一种在最短时间内获得当前位置的方法。对于您的信息,我使用谷歌 javascript 地图sdk / api。

6 个答案:

答案 0 :(得分:3)

我尝试了所有人和其他人在互联网上提供的解决方案。最后我找到了一个解决方案。您可以从 ESRI 中尝试此插件 cordova-plugin-advanced-geolocation https://github.com/Esri/cordova-plugin-advanced-geolocation)。但此插件适用于 Android 而不是 IOS 。对于ios,您可以使用相同的旧方法。即 - 使用this.geolocation.getCurrentPosition(...)this.geolocation.watchPosition(..)

添加插件像这样: -

cordova plugin add https://github.com/esri/cordova-plugin-advanced-geolocation.git

然后

declare var AdvancedGeolocation:any; //位于课程顶部

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

          });
        }

编辑:首次安装总是很顺利。但有时您可能会在后续安装中无缘无故地收到错误。要使此错误(此插件出现任何错误)消失。请执行以下步骤:

1。从项目中删除此插件(包括config.xmlpackage.json)。

2. 删除/删除android平台。

3. 删除plugins文件夹。

4. 现在,请按照上述步骤重新安装此插件。

答案 1 :(得分:2)

我已经解决了问题并找到了解决方案。

获取用户地理位置的最佳方法是使用此插件https://ionicframework.com/docs/native/geolocation/

不要忘记添加这个app.moudle.ts作为其提供者。

只需在app组件中添加此代码即可获取位置(不要忘记导入并添加构造函数

 this.geolocation.getCurrentPosition({ enableHighAccuracy: true }).then((resp) => {
      console.log(resp);
    }, Error => {
      console.log(Error);
    }).catch(Error => {
      console.log(Error);
    })
  

我在使用离子cordova运行时只有相同的错误   android --livereload ,这是一个不安全的起源

     

但是当我使用离子服务时,我可以在浏览器中看到响应,之后也可以看到   使用离子cordova运行android

只是为了确认android中的响应我检查了chrome调试器。

答案 2 :(得分:0)

我遇到了类似的问题。当我使用--prod标志从终端构建时,我不再看到此错误,因为它现在通过https请求位置。

Built without --prod flag

Built using the --prod flag

编辑:抱歉格式,我希望这更有意义。我在一个服务中使用了以下功能,我可以从任何地方调用以获取纬度,经度,准确度和时间戳。关键是在构建应用程序时在终端中使用--prod标志。

this.geolocation.getCurrentPosition().then(position => {
     let locationObj = {
            lat: position.coords.latitude,
            lon: position.coords.longitude,
            timestamp: position.timestamp,
            accuracy: position.coords.accuracy
     };
resolve(locationObj);
})

答案 3 :(得分:0)

此方法适用于机器人android和浏览器

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

答案 4 :(得分:-1)

您需要提供Android应用的权限,如下所示:

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

答案 5 :(得分:-2)

我为我找到了解决方案:使用google api https://www.googleapis.com/geolocation/v1/geolocate?key={API_KEY} 如果平台Android我使用google api。