【发布时间】:2018-11-14 23:20:29
【问题描述】:
我在 Angular 6 中构建了一个 PWA,并打算使用 Google Maps API 进行地理定位。但是,我很快意识到 PWA 中的地理定位服务仅在用户与 UI 交互以故意请求其位置时才起作用。但是,我的应用程序应该在用户开车时在后台跟踪他们的位置。因此,当他们锁定屏幕或转到其他应用程序时,它仍应跟踪他们。作为记录,这是一个私人应用程序,用户完全知道他们正在被跟踪。因此,我使用 Cordova 将 PWA 转换为混合应用程序。到目前为止,一切都适用于我已经拥有的东西(模拟很好,等等),但我似乎无法弄清楚如何添加地理定位部分。我已经安装了this 插件,它似乎已安装并且可用。我见过的所有示例都使用 Ionic(此时我不需要),并且适用于用户单击按钮以获取其位置的场景,但我需要它在地理定位内容位于服务中并启动的情况下他们登录后在后台运行。我似乎找不到显示如何执行此操作的内容。以下是我认为我应该做的事情:
(这不完整,我只是将 GitHub 的示例代码粘贴到此处,并打算在我知道它实际上被调用时用“stuff”填充它)
_services/geolocation.service.ts:
import { Injectable } from '@angular/core';
import { Component, ViewChild } from '@angular/core';
declare var cordova: any;
@Injectable()
export class GeolocationService {
startBackgroundGeolocation() {
console.log("Geolocation service called...");
cordova.plugins.BackgroundGeolocation.configure({
locationProvider: cordova.plugins.BackgroundGeolocation.ACTIVITY_PROVIDER,
desiredAccuracy: cordova.plugins.BackgroundGeolocation.HIGH_ACCURACY,
stationaryRadius: 50,
distanceFilter: 50,
notificationTitle: 'Background tracking',
notificationText: 'enabled',
debug: true,
interval: 10000,
fastestInterval: 5000,
activitiesInterval: 10000,
url: 'http://192.168.0.3:3000/location',
httpHeaders: {
'X-FOO': 'bar'
},
// customize post properties
postTemplate: {
lat: '@latitude',
lon: '@longitude',
foo: 'bar' // you can also add your own properties
}
});
cordova.plugins.BackgroundGeolocation.on('location', function(location) {
// handle your locations here
// to perform long running operation on iOS
// you need to create background task
cordova.plugins.BackgroundGeolocation.startTask(function(taskKey) {
// execute long running task
// eg. ajax post location
// IMPORTANT: task has to be ended by endTask
cordova.plugins.BackgroundGeolocation.endTask(taskKey);
});
});
cordova.plugins.BackgroundGeolocation.on('stationary', function(stationaryLocation) {
// handle stationary locations here
});
cordova.plugins.BackgroundGeolocation.on('error', function(error) {
console.log('[ERROR] cordova.plugins.BackgroundGeolocation error:', error.code, error.message);
});
cordova.plugins.BackgroundGeolocation.on('start', function() {
console.log('[INFO] cordova.plugins.BackgroundGeolocation service has been started');
});
cordova.plugins.BackgroundGeolocation.on('stop', function() {
console.log('[INFO] cordova.plugins.BackgroundGeolocation service has been stopped');
});
cordova.plugins.BackgroundGeolocation.on('authorization', function(status) {
console.log('[INFO] cordova.plugins.BackgroundGeolocation authorization status: ' + status);
if (status !== cordova.plugins.BackgroundGeolocation.AUTHORIZED) {
// we need to set delay or otherwise alert may not be shown
setTimeout(function() {
var showSettings = confirm('App requires location tracking permission. Would you like to open app settings?');
if (showSettings) {
return cordova.plugins.BackgroundGeolocation.showAppSettings();
}
}, 1000);
}
});
cordova.plugins.BackgroundGeolocation.on('background', function() {
console.log('[INFO] App is in background');
// you can also reconfigure service (changes will be applied immediately)
cordova.plugins.BackgroundGeolocation.configure({ debug: true });
});
cordova.plugins.BackgroundGeolocation.on('foreground', function() {
console.log('[INFO] App is in foreground');
cordova.plugins.BackgroundGeolocation.configure({ debug: false });
});
cordova.plugins.BackgroundGeolocation.on('abort_requested', function() {
console.log('[INFO] Server responded with 285 Updates Not Required');
cordova.plugins.BackgroundGeolocation.stop();
// Here we can decide whether we want stop the updates or not.
// If you've configured the server to return 285, then it means the server does not require further update.
// So the normal thing to do here would be to `cordova.plugins.BackgroundGeolocation.stop()`.
// But you might be counting on it to receive location updates in the UI, so you could just reconfigure and set `url` to null.
});
cordova.plugins.BackgroundGeolocation.on('http_authorization', () => {
console.log('[INFO] App needs to authorize the http requests');
});
cordova.plugins.BackgroundGeolocation.checkStatus(function(status) {
console.log('[INFO] cordova.plugins.BackgroundGeolocation service is running', status.isRunning);
console.log('[INFO] cordova.plugins.BackgroundGeolocation services enabled', status.locationServicesEnabled);
console.log('[INFO] cordova.plugins.BackgroundGeolocation auth status: ' + status.authorization);
// you don't need to check status before start (this is just the example)
if (!status.isRunning) {
cordova.plugins.BackgroundGeolocation.start(); //triggers start on start event
}
});
// you can also just start without checking for status
// cordova.plugins.BackgroundGeolocation.start();
// Don't forget to remove listeners at some point!
// cordova.plugins.BackgroundGeolocation.events.forEach(function(event) {
// return cordova.plugins.BackgroundGeolocation.removeAllListeners(event);
// });
}
}
然后从 app.component:
import { Component, OnInit } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {
transition,
trigger,
query,
style,
animate,
group,
animateChild
} from '@angular/animations';
import { GeolocationService } from './_services/geolocation.service';
declare const device;
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [
trigger('routeAnimation', [
transition('* => *', [
query(
':enter',
[style({ opacity: 0 })],
{ optional: true }
),
query(
':leave',
[style({ opacity: 1 }), animate('0.3s', style({ opacity: 0 }))],
{ optional: true }
),
query(
':enter',
[style({ opacity: 0 }), animate('0.3s', style({ opacity: 1 }))],
{ optional: true }
)
])
])
]
})
export class AppComponent implements OnInit{
title = 'HLD Phlebotomist App';
constructor(private geolocationService: GeolocationService) { }
ngOnInit() {
document.addEventListener("deviceready", function() {
this.geolocationService.startBackgroundGeolocation();
alert(device.platform);
}, false);
}
}
但是,当我在 android 模拟器中运行它时,我得到“未捕获的类型错误:无法读取未定义的属性 'startBackgroundGeolocation'”。不知道为什么。有人可以帮我理解这里的结构吗?我认为我的问题是我不完全了解如何“调用”Cordova 插件。
【问题讨论】:
标签: android angular cordova google-geolocation