我正在使用此地理定位插件 ( https://github.com/NativeScript/nativescript-geolocation/tree/e125998c07ced42a215aca1a8feac1b7dbe7b6d6 ) 在应用程序处于后台时获取持续的位置更新。
我尝试使用演示中的代码,但我不知道如何使其工作。
我希望用户按下按钮,应用程序就开始监视他的位置,即使应用程序进入后台也是如此。
home.component.ts
import { Component, OnInit, AfterViewInit } from "@angular/core";
import { RadSideDrawer } from "nativescript-ui-sidedrawer";
import { getRootView } from "tns-core-modules/application";
import * as app from "tns-core-modules/application";
const utils = require("tns-core-modules/utils/utils");
import { device } from "tns-core-modules/platform";
//import { GeolocationService } from "../services/geolocation/geolocation.service";
@Component({
selector: "Home",
moduleId: module.id,
templateUrl: "./home.component.html"
})
export class HomeComponent implements OnInit {
public drawer: RadSideDrawer;
public buttonText = "Start";
locations = [];
watchIds = [];
jobId = 308;
constructor(
public geolocationService: GeolocationService,
) {}
ngOnInit(): void {
app.on(app.exitEvent, this._stopBackgroundJob);
}
ngAfterViewInit() {
this.drawer = <RadSideDrawer>getRootView();
this.drawer.gesturesEnabled = true;
}
onDrawerButtonTap(): void {
const sideDrawer = <RadSideDrawer>app.getRootView();
sideDrawer.showDrawer();
}
_stopBackgroundJob() {
if (app.android) {
let context = utils.ad.getApplicationContext();
const jobScheduler = context.getSystemService((<any>android.content.Context).JOB_SCHEDULER_SERVICE);
if (jobScheduler.getPendingJob(this.jobId) !== null) {
jobScheduler.cancel(this.jobId);
console.log(`Job Canceled: ${this.jobId}`);
}
}
}
checkLoc(){
this.geolocationService.buttonGetLocationTap()
}
_onGeolocationService(){
this.geolocationService.enableLocation()
.then(result => {
this.geolocationService.monitorLocation();
if(this.geolocationService.locationMonitor === true){
this.buttonText = "Stop";
} else {
this.buttonText = "Start";
}
})
}
public startBackgroundTap() {
if (app.android) {
let context = utils.ad.getApplicationContext();
if (device.sdkVersion >= "26") {
const jobScheduler = context.getSystemService((<any>android.content.Context).JOB_SCHEDULER_SERVICE);
const component = new android.content.ComponentName(context, com.nativescript.location.BackgroundService26.class);
const builder = new (<any>android.app).job.JobInfo.Builder(this.jobId, component);
builder.setOverrideDeadline(0);
return jobScheduler.schedule(builder.build());
} else {
let intent = new android.content.Intent(context, com.nativescript.location.BackgroundService.class);
context.startService(intent);
}
}
}
public stopBackgroundTap() {
if (app.android) {
if (device.sdkVersion >= "26") {
this._stopBackgroundJob();
} else {
let context = utils.ad.getApplicationContext();
let intent = new android.content.Intent(context, com.nativescript.location.BackgroundService.class);
context.stopService(intent);
}
}
}
}
地理位置.service.ts
import { Injectable } from '@angular/core';
import * as geolocation from "nativescript-geolocation";
import { Accuracy } from "tns-core-modules/ui/enums";
@Injectable({
providedIn: 'root'
})
export class GeolocationService {
locations= [];
watchIds = [];
constructor() { }
public enableLocation() {
return geolocation.enableLocationRequest();
}
public checkIfLocationIsEnabled() {
geolocation.isEnabled()
.then(function (isEnabled) {
if(isEnabled) {
return true;
} else {
return false;
}
})
}
public buttonGetLocationTap() {
let that = this;
geolocation.getCurrentLocation({
desiredAccuracy: Accuracy.high,
iosAllowsBackgroundLocationUpdates: true,
iosPausesLocationUpdatesAutomatically: false,
iosOpenSettingsIfLocationHasBeenDenied: true,
maximumAge: 5000,
timeout: 10000,
updateTime: 10000,
}).then(function (loc) {
console.log(loc["latitude"], loc["longitude"])
if (loc) {
that.locations.push(loc);
}
}, function (e) {
console.log("Error: " + (e.message || e));
});
}
public buttonStartTap() {
try {
let that = this;
that.watchIds.push(geolocation.watchLocation(
function (loc) {
if (loc) {
that.locations.push(loc);
}
},
function (e) {
console.log("Error: " + e.message);
},
{
desiredAccuracy: Accuracy.high,
iosAllowsBackgroundLocationUpdates: true,
iosPausesLocationUpdatesAutomatically: false,
iosOpenSettingsIfLocationHasBeenDenied: true,
maximumAge: 7000,
timeout: 9000,
updateTime: 9000,
}));
} catch (ex) {
console.log("Error: " + ex.message);
}
}
public buttonStopTap() {
let watchId = this.watchIds.pop();
while (watchId != null) {
geolocation.clearWatch(watchId);
watchId = this.watchIds.pop();
}
}
public buttonClearTap() {
this.locations.splice(0, this.locations.length);
}
}
背景.service.ts
import * as geolocation from "nativescript-geolocation";
import { Accuracy } from "tns-core-modules/ui/enums";
import * as application from "tns-core-modules/application";
import { device } from "tns-core-modules/platform";
let watchId;
function _clearWatch() {
if (watchId) {
geolocation.clearWatch(watchId);
watchId = null;
}
}
function _startWatch() {
geolocation.enableLocationRequest().then(function () {
_clearWatch();
watchId = geolocation.watchLocation(
function (loc) {
if (loc) {
console.log('Background Location: ' + loc.latitude + ' ' + loc.longitude);
}
},
function (e) {
console.log("Background watchLocation error: " + (e.message || e));
},
{
desiredAccuracy: Accuracy.high,
updateDistance: 1.0,
updateTime: 3000,
minimumUpdateTime: 100
});
}, function (e) {
console.log("Background enableLocationRequest error: " + (e.message || e));
});
}
application.on(application.exitEvent, _clearWatch);
if (application.android) {
if (device.sdkVersion < "26") {
(<any>android.app.Service).extend("com.nativescript.location.BackgroundService", {
onStartCommand: function (intent, flags, startId) {
this.super.onStartCommand(intent, flags, startId);
return android.app.Service.START_STICKY;
},
onCreate: function () {
_startWatch();
},
onBind: function (intent) {
console.log("on Bind Services");
},
onUnbind: function (intent) {
console.log('UnBind Service');
},
onDestroy: function () {
console.log('service onDestroy');
_clearWatch();
}
});
} else {
(<any>android.app).job.JobService.extend("com.nativescript.location.BackgroundService26", {
onStartJob() {
console.log('service onStartJob');
_startWatch();
return true;
},
onStopJob(jobParameters: any) {
console.log('service onStopJob');
this.jobFinished(jobParameters, false);
_clearWatch();
return false;
},
});
}
}
首先,“com”命名空间存在问题,因为它显示“属性“nativescript”在“typeof com”类型上不存在”。问题出现在 home.component.ts 的以下 3 行中:
const 组件 = new android.content.ComponentName(context, com.nativescript.location.BackgroundService26.class); 让intent = new android.content.Intent(context, com.nativescript.location.BackgroundService.class); 让intent = new android.content.Intent(context, com.nativescript.location.BackgroundService.class);
其次,我不知道后台服务的目的是什么,因为我在演示中没有使用它(或者也许是,但以一种我不熟悉的方式)。
谢谢!
最佳答案
"Property 'nativescript' does not exist on type 'typeof com' "
这是一个简单的 TypeScript 声明错误,将其转换为 any 可能会解决您的问题。
const component = new android.content.ComponentName(context, (com as any).nativescript.location.BackgroundService26.class);
let intent = new android.content.Intent(context, (com as any).nativescript.location.BackgroundService.class);
let intent = new android.content.Intent(context, (com as any).nativescript.location.BackgroundService.class);
正如您在演示应用程序中所看到的,declare var com: any;
具有相同的目的。或者,如果您熟悉 TypeScript,则可以声明正确的类型。
Secondly, I don't know what is the purpose of background-service
我想我们已经在不同的线程中讨论过这个问题,当您想要运行某些任务(即使您的应用程序未运行)时,就会使用后台服务。
您在上面使用的类com.nativescript.location.BackgroundService
来自该文件(background-service.ts
)。相同的类应该在 AndroidManifest.xml 中声明也是。
编辑:
听起来您没有使用 background-service.ts
文件条目更新您的 webpack.config.js
。
// Add your custom Activities, Services and other Android app components here.
const appComponents = [
"tns-core-modules/ui/frame",
"tns-core-modules/ui/frame/activity",
resolve(__dirname, "src/path/to/background-service"),
];
关于android - 如何使地理定位后台服务在我的 NativeScript-Angular 应用程序中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57819491/