Reputation: 741
I'm trying to create a background service for nativescript-geolocation
to get notifications when an event has been triggered.
I've found a lot of examples for the general NS version, but nothing for the Angular version and I can't find the way to implement it.
Currently, I'm getting Class "com.nativescript.location.BackgroundService" not found.
error messages.
Services have been declared in the AndroidManifest.xml, deleted the platforms dir, and did a clean build.
<service android:name="com.nativescript.location.BackgroundService"
android:exported="false" >
</service>
<service android:name="com.nativescript.location.BackgroundService26"
android:permission="android.permission.BIND_JOB_SERVICE"
android:enabled="true"
android:exported="false">
</service>
I use this as a reference and trying to create the Angular version of this https://github.com/NativeScript/nativescript-geolocation/tree/master/demo
background-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";
import * as Toast from "nativescript-toast";
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) {
let toast = Toast.makeText('Background Location: \n' + loc.latitude + ', ' + loc.longitude);
toast.show();
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);
export function getBackgroundServiceClass() {
if (application.android) {
if (device.sdkVersion < "26") {
@JavaProxy("com.nativescript.location.BackgroundService")
class BackgroundService extends (<any>android).app.Service {
constructor() {
super();
return global.__native(this);
}
onStartCommand(intent, flags, startId) {
console.log('service onStartCommand');
this.super.onStartCommand(intent, flags, startId);
return android.app.Service.START_STICKY;
}
onCreate() {
console.log('service onCreate');
_startWatch();
}
onBind(intent) {
console.log('service onBind');
}
onUnbind(intent) {
console.log('service onUnbind');
}
onDestroy() {
console.log('service onDestroy');
_clearWatch();
}
}
return BackgroundService;
} else {
@JavaProxy("com.nativescript.location.BackgroundService26")
class BackgroundService26 extends (<any>android.app).job.JobService {
constructor() {
super();
return global.__native(this);
}
onStartJob(): boolean {
console.log('service onStartJob');
_startWatch();
return true;
}
onStopJob(jobParameters: any): boolean {
console.log('service onStopJob');
this.jobFinished(jobParameters, false);
_clearWatch();
return false;
}
}
return BackgroundService26;
}
} else {
return null;
}
}
export const BackgroundServiceClass = getBackgroundServiceClass();
app.component.tns.ts
import {Component, ElementRef, ViewChild} from '@angular/core';
import { BackgroundServiceClass } from "@src/background-service";
import { Page } from "tns-core-modules/ui/page";
const utils = require("tns-core-modules/utils/utils");
import * as application from "tns-core-modules/application";
import { device } from "tns-core-modules/platform";
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
/* Background servie stuffs */
page: Page;
watchIds = [];
jobId = 308; // the id should be unique for each background job. We only use one, so we set the id to be the same each time.
com: any;
constructor(
) {
}
ngOnInit(){
application.on(application.exitEvent, this._stopBackgroundJob);
}
ngAfterViewInit(){
}
_stopBackgroundJob() {
if (application.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}`);
}
}
}
startBackgroundTap() {
if (application.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, BackgroundServiceClass.class);
const builder = new (<any>android.app).job.JobInfo.Builder(this.jobId, component);
builder.setOverrideDeadline(0);
jobScheduler.schedule(builder.build());
} else {
let intent = new android.content.Intent(context, BackgroundServiceClass.class);
context.startService(intent);
}
}
}
}
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android" package="__PACKAGE__" android:versionCode="13" android:versionName="1.31">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application android:name="com.tns.NativeScriptApplication" android:allowBackup="true" android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/AppTheme" android:windowSoftInputMode="adjustResize" android:hardwareAccelerated="true" android:networkSecurityConfig="@xml/network_security_config">
<service android:name="com.nativescript.location.BackgroundService"
android:exported="false" >
</service>
<service android:name="com.nativescript.location.BackgroundService26"
android:permission="android.permission.BIND_JOB_SERVICE"
android:enabled="true"
android:exported="false">
</service>
<activity android:name="com.tns.NativeScriptActivity" android:label="@string/title_activity_kimera" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode" android:theme="@style/LaunchScreenTheme">
<meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.tns.ErrorReportActivity" />
</application>
</manifest>
Upvotes: 0
Views: 1842
Reputation: 43
For the problem you mention try this:
For Background Location Tracking, I suggest you to try Foreground Services combined with nativescript-geolocation plugin. Check this article is a well explained tutorial of the first topic:
https://dev.to/ozymandiasthegreat/android-continuous-background-services-with-nativescript-42c9
Repo link:
https://github.com/OzymandiasTheGreat/Nativescript-ServiceExample/blob/master/package-lock.json
Upvotes: 0