我正在尝试创建一个函数,该函数发送本地通知,并在用户的设备进入地理围栏时将某个值更新为字符串“true”或“false” . 我正在使用提供商进行定位服务 . 该服务中的相关代码:

import { Injectable } from '@angular/core';
import { Geolocation } from '@ionic-native/geolocation';
import { AngularFireDatabase, AngularFireList, AngularFireObject } from 'angularfire2/database';
import { AngularFireAuth } from 'angularfire2/auth'
import { Observable } from 'rxjs/Observable';
import * as d3 from "d3-polygon"
import { NotificationsService } from '../notifications/notifications.service'


@Injectable()
export class LocationService {

  userId: string;
  items: Observable<any[]>;
  itemsRef: AngularFireList<any>;

  loc1: any = []
  loc2: any = []
  loc3: any = []
  loc4: any = []

  map_points_mock: any = [];
latlng: any = [];
alertList: any = [];
inside: string;

  constructor(public geolocation: Geolocation, public database: AngularFireDatabase, private auth: AngularFireAuth, private notifications: NotificationsService) {
    this.auth.authState.subscribe(user => {
      if(user) this.userId = user.uid

  });
  }

  insidePolygon() {

  this.itemsRef = this.database.list(`locations-list/${this.userId}`);
this.itemsRef.snapshotChanges()
  .subscribe(actions => {
    actions.forEach(action => {
      this.loc1.push({"latitude": action.payload.val().latitude + .0025, "longitude": action.payload.val().longitude + .0025})
      this.loc2.push({"latitude": action.payload.val().latitude - .0025, "longitude": action.payload.val().longitude + .0025})
      this.loc3.push({"latitude": action.payload.val().latitude - .0025, "longitude": action.payload.val().longitude - .0025})
      this.loc4.push({"latitude": action.payload.val().latitude + .0025, "longitude": action.payload.val().longitude - .0025})
    })
          for (let i = 0; i < this.loc1.length; i++) {
            this.map_points_mock.push( {"square": 
              [
                this.loc1[i].latitude, this.loc1[i].longitude,              
                this.loc2[i].latitude, this.loc2[i].longitude,
                this.loc3[i].latitude, this.loc3[i].longitude,
                this.loc4[i].latitude, this.loc4[i].longitude
             ]
          })}

          const subscription = this.geolocation.watchPosition()
          .filter((p) => p.coords !== undefined)
          .subscribe(position => {

              this.latlng.push(position.coords.latitude, position.coords.longitude)

              let m,j,temparray = [],chunk = 2

      for (let p = 0; p < this.map_points_mock.length; p++) {
        for (m=0, j = this.map_points_mock[p].square.length; m<j; m+=chunk) {
        temparray.push(this.map_points_mock[p].square.slice(m, m+chunk));
         }
         this.alertList.push(d3.polygonContains(temparray, this.latlng))
         temparray = []  
      }
      for (let a = 0; a < this.alertList.length; a++) {
      if (this.alertList[a] === true ) {
        this.notifications.areaNotification()
          subscription.unsubscribe();
        this.inside = "false"
        } else {
        this.inside = "true"}
         }
});
  });
  };
}

我理解代码有点难看;我现在只关心功能 . 因此,用户的一组地理坐标已输入firebase实时数据库 . 在上面,我检索那些地理坐标,通过添加和减去值创建一个正方形,激活.watchPosition()来监视用户的位置,然后说要检查当前监控位置对所有多边形(即地理围栏)以检查是否用户在其中任何一个 . 如果用户在内部,则“inside”的值应为true,并且应从我的通知提供程序发送本地通知 . 这是代码:

areaNotification () {

 let data = { title:'WARNING', description:'You have entered a dangerous area'};

  this.localNotifications.schedule({
    title: data.title,
    text: data.description,
    led: 'FF0000',
})
}

(我依靠cordova-plugin-local-notification通过离子原生的方式通知 . )

否则,将内部设置为“False”,这只是确定在DOM中显示的内容 .

当我的应用程序的主页加载时调用所有这些:

ionViewWillLoad() {
this.location.insidePolygon()
}

好吧,我期望这里的行为是,每当用户输入一个地理位置时,内部的值将被设置为“True”并且本地通知将被发送,无论应用程序是打开还是关闭等等 . 我有权在所有测试期间随时跟踪位置 . 我已经在android和ios模拟器以及iPhone上通过离子运行命令和Test Flight进行了测试 . (我还没有在Android设备上测试过 . )

结果是我在应用程序加载时获得了一次预期结果 . 当我在其中一个地理围栏之内或之外时,它表现得如预期的那样 . 但它只会这样做一次,好像我正在运行.getCurrentPosition(),我不是 . 每次我重新加载主页时,我都会得到预期的结果,内部值的变化以及DOM中的伴随变化,如果我在地理围栏内,则会显示本地通知 . 但无论我是否在前台打开应用程序,内部的值都不会更改,除非我重新加载主页或重新打开应用程序,否则不会显示本地通知 .

为了让它发挥作用,我尝试了许多不同的排列 . 我已将整个功能放在home.ts中,包括本地通知的所有代码 . 我已经嵌套了.watchPosition()里面的insidePolygon()中的所有代码 . 我做了其他的事情并且已经和它搏斗了好几天 .

我也试过一些地理围栏插件 . 例如,我尝试过cordova-plugin-geofence及其分支和各种人提出的修复程序,试图使其与Xcode 9兼容,包括此处提到的修复程序(http://invisibleloop.com/troubleshooting-ionic-native-geofence-plugin-build-issues/)和此处(https://www.npmjs.com/package/cordova-plugin-custom-geofence) . 我已经考虑过使用radar.io,我想要搞乱插件和外部服务的兼容性问题,而不仅仅是我必须这样做 .

如果有办法让我的代码以我想要的方式工作,我将非常感谢被指向那个方向 .