Closed dann95 closed 5 years ago
Don’t use method #configure. It’s deprecated in favor of new #ready.
thats really weird, cause, executions of number (odd) 1, 3, 5 , 7 , 9 , 11 , 13.. it starts the tasks... on even executions, it don't starts the task..
testing on another devices, if you want to, i can send u the .apk
Are you watching the native logs? You’re doing something wrong on your end.
No, i'm not looking for native logs, i just see that calling .start() gives foregroundService true/false depending on "number" of execution..
foregroundService is enforced true by the plugin on SDK 23+.
I got some logs of adb catlog, they are dirty with some private info, can i send it by e-mail?
See you using #ready method (not #configure)?
It’s pointless to observe changes in foregroundService.
but if user didn't allow app to use geolocation, what would .ready() do?
Doesn’t matter: you MUST call #ready each and every time your app boots.
ok.
its needed ready and start() ?
No. The plugin persists its state.
You don’t typically want to #start in the callback to #ready at all. I do this in the example just so people get the plugin started immediately.
Typically you’d execute #start / #stop from some UI interaction or app event.
Well, calling Ready on the bootstrap, and "start" when "session" is confirmed, still not opening the background task, only on odd executions, even not..
Show me your JavaScript
opening the background task
What does this mean?
import {
EIOSLocationMode,
ErrorGeolocationCallback,
IGeolocationError,
IGeolocationHardwareAbstraction,
SuccessGeolocationCallback
} from '../hardware-interfaces';
import { EHardwareResourceStatus } from "./vendor/hardware-status";
import { Window } from './definitions/diagnostic';
import { CordovaPermissionsService } from "./permissions/cordova-permissions.service";
import { getClock, isValid } from "@colmeia/core/tools/utility";
import { CordovaGeolocationConstants } from "./cordova-hardware.constants";
import { ILocationCoordinates } from "@colmeia/core/tools/geo-util";
import { Location } from './transistorsoft-location';
import { SignalListenerService } from "../../../../component-comm/system-signals/sign-emissor/signal-listener";
import { PlayerCachedInfo } from "@colmeia/core/business/player-cached";
import { TGlobalUID } from "@colmeia/core/core-constants/types";
import { Injectable } from '@angular/core';
declare var window: Window;
declare var BackgroundGeolocation: any;
@Injectable({
providedIn: 'root'
})
export class CordovaGeolocation implements IGeolocationHardwareAbstraction {
private _successCallbacksMap: Map<number, SuccessGeolocationCallback> = new Map<number, SuccessGeolocationCallback>();
private _errorCallbacksMap: Map<number, ErrorGeolocationCallback> = new Map<number, ErrorGeolocationCallback>();
private _baterySaveMode: boolean = false;
private _lastTimeReceivedPos: number = getClock();
private player: PlayerCachedInfo;
constructor(
private permissions: CordovaPermissionsService,
private listener: SignalListenerService
) {
document.addEventListener('deviceready', () => {
BackgroundGeolocation.onHttp(response => {
console.log('[http] - ', response.success, response.status, response.responseText);
});
BackgroundGeolocation.onHeartbeat((event) => {
this.onHeartbeatReceived();
});
BackgroundGeolocation.onLocation(location => {
this.onLocationReceived(location);
}, error => {
this.onLocationErrorReceived(error);
});
BackgroundGeolocation.onMotionChange(event => {
this.onLocationReceived(event.location);
});
BackgroundGeolocation.onPowerSaveChange(enabled => {
this._baterySaveMode = enabled;
});
BackgroundGeolocation.ready({
...CordovaGeolocationConstants.Defaults,
...CordovaGeolocationConstants.IOSOnly,
...CordovaGeolocationConstants.AndroidOnly,
});
this.determineTrackingState();
this.setEmergencyMode(false);
});
this.listener.listenToActivateGeoSignal(() => {
this.determineTrackingState();
});
this.listener.listenToDeactivateGeoSignal(() => {
this.determineTrackingState();
});
}
private isTrackingOn(): boolean {
if(! this.player) { //session isn't available.......
return false;
}
const isLoged: boolean = isValid(this.player.getOriginalAvatarID());
const isTrackingOn: boolean = this.player.isTrackingOn();
return isLoged && isTrackingOn;
}
private async determineTrackingState(): Promise<void> {
const isOn = this.isTrackingOn();
const isAllowed = await this.isAllowed();
if (isOn && isAllowed) {
BackgroundGeolocation.start((state) => {
console.log(state);
})
}
}
setCachedPlayer(player: PlayerCachedInfo) {
this.player = player;
console.warn("SETANDO NOVO PLAYER LOGADO PARA ENVIAR OS SINAIS DE GPS...")
const idPlayer: TGlobalUID = player.getPlayerID(),
personalID: TGlobalUID = player.getParticipantIDPersonalGroup(),
part: TGlobalUID = player.getPersonalGroupParticipant(player.getOriginalAvatarID()).primaryID;
console.log(player);
if (player) {
this.appendConfigs({
params: {
"playerID": idPlayer,
"personalID": personalID,
"partID": part
}
});
}
this.determineTrackingState();
}
private onHeartbeatReceived(): void {
console.warn('HEARTBEAT')
BackgroundGeolocation.getCurrentPosition({
persist: true,
desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH
}, this.onLocationReceived,
this.onLocationErrorReceived
);
}
setEmergencyMode(active: boolean): void {
this.appendConfigs(
(active) ? CordovaGeolocationConstants.EmergencyModeOn : CordovaGeolocationConstants.EmergencyModeOff
);
}
private appendConfigs(settings: object): void {
BackgroundGeolocation.setConfig(settings);
}
private normalizeLocation(loc: Location): ILocationCoordinates {
return {
uuid: loc.uuid,
speed: loc.coords.speed,
powerSaveMode: this._baterySaveMode,
longitude: loc.coords.longitude,
latitude: loc.coords.latitude,
isMoving: loc.is_moving,
heading: loc.coords.heading,
gpsTimestamp: getClock(),
batery: loc.battery.level,
altitudeAccuracy: null,
altitude: loc.coords.altitude,
activity: loc.activity.type,
accuracy: loc.coords.accuracy
}
}
private normalizeError(err: PositionError): IGeolocationError {
return {
gpsTimestamp: getClock(),
message: err.message
}
}
private onLocationReceived = (location: Location) => {
this._lastTimeReceivedPos = getClock();
this._successCallbacksMap.forEach(cb => {
cb(this.normalizeLocation(location));
});
};
private onLocationErrorReceived = (err) => {
this._errorCallbacksMap.forEach(cb => {
cb(this.normalizeError(err));
});
};
isEnabled(): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
window.cordova
.plugins
.diagnostic
.isLocationEnabled((status: boolean) => {
resolve(status);
}, (error) => {
resolve(false);
});
});
}
getAuthorizationStatus(): Promise<EHardwareResourceStatus> {
return new Promise<EHardwareResourceStatus>((resolve, reject) => {
window.cordova
.plugins
.diagnostic
.getLocationAuthorizationStatus((status: EHardwareResourceStatus) => {
resolve(status);
}, (error) => {
// Atenção, isso é questionável, não queremos na prática gerar erro desnecessário
resolve(EHardwareResourceStatus.NOT_REQUESTED)
})
});
}
isAllowed(): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
window.cordova
.plugins
.diagnostic
.isLocationAuthorized((status: boolean) => {
resolve(status);
}, (error) => {
resolve(false);
})
});
}
requestAuthorization(): Promise<EHardwareResourceStatus> {
return new Promise<EHardwareResourceStatus>((resolve, reject) => {
window.cordova
.plugins
.diagnostic
.requestLocationAuthorization((status: EHardwareResourceStatus) => {
resolve(status);
}, (error) => {
throw new Error(error)
}, EIOSLocationMode.ALWAYS)
});
}
getPosition(successCallback: SuccessGeolocationCallback, errorCallback: ErrorGeolocationCallback, options: object): void {
BackgroundGeolocation.getCurrentPosition({
persist: false,
desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
samples: 5
}, (pos: Location) => {
successCallback(this.normalizeLocation(pos));
}, (err: PositionError) => {
errorCallback(this.normalizeError(err));
});
}
watchPosition(successCallback: SuccessGeolocationCallback, errorCallback: ErrorGeolocationCallback, options?: PositionOptions): number {
const _id = this._successCallbacksMap.size + 1;
this._successCallbacksMap.set(_id, successCallback);
this._errorCallbacksMap.set(_id, errorCallback);
return _id;
}
clearWatchPosition(id: number): void {
this._errorCallbacksMap.delete(id);
this._successCallbacksMap.delete(id);
}
getLastKnownPosition(): ILocationCoordinates {
return null;
}
}
opening the background task
What does this mean?
at phone top bar it shows an small icon of application when "background" task is open, when i say that it dosn't open, no icon on topbar and no HTTP post.
that service is constructed on "app.component.ts", it is an abstraction of geolocation For cordova build, for Browser we use another implementation.. this service is required on constructor of another service called "HardwareAbstractService"
don't do this:
BackgroundGeolocation.ready({
...CordovaGeolocationConstants.Defaults,
...CordovaGeolocationConstants.IOSOnly,
...CordovaGeolocationConstants.AndroidOnly,
});
// NO. You must not execute #start until the callback to #ready
this.determineTrackingState();
BackgroundGeolocation.ready(config).then((state) => {
this.determineTrackingState();
});
ok, will try it.
but at this momment, there is no session, cause: this.player is = undefined, so it won't call Start at this moment, only when setCachedPlayer its called.
and you should probably place these into the callback to #ready
, as well. Never execute #start
until the callback to #ready
fires:
this.listener.listenToActivateGeoSignal(() => {
this.determineTrackingState();
});
this.listener.listenToDeactivateGeoSignal(() => {
this.determineTrackingState();
});
The method is called #ready
because you're not supposed to do anything that requires location (eg: #start
, #getCurrentPosition
until the plugin is "ready".
Yeah man, but its impossible to call .start before .ready finished, cause determineTrackingState checks for "CachedPlayer" and cached player is set after an http request..
The problem is 100% guaranteed in your usage of the plugin.
Email me the result of #emailLog
.
is there any breaking change between 2.14 and 3? im thinking in update it, not sure if will solve our problem =/
The problem is 100% guaranteed in your usage of the plugin.
Email me the result of
#emailLog
.
how i do that?
have you an android device? i can pass the the .apk and u will reproduce exactly what i do =/
how i do that?
See docs emailLog
See CHANGELOG. No breaking changes other than key change.
im thinking in update it, not sure if will solve our problem =/
It won't. This is not caused by the plugin. It's caused by your usage of it. However, 3.0.0 is a significant improvement in the behaviour of the Android service, which is no longer active when plugin is in stationary state.
have you an android device? i can pass the the .apk and u will reproduce exactly what i do =/
Dude...what do you think?? I have 13 of them:
i reproduced this issue on any device, have u skype? or google talk?
My rate for talking is $300/hour.
two logs, names represent what happened with background task xD
I wan't filtered logs.
$ adb logcat -s TSLocationManager
ok, i will ran it with filter, but when it dont open it shows: 04-10 18:23:22.399 17445 17606 W TSLocationManager: [c.t.l.a.BackgroundGeolocation$28 onPermissionGranted] 04-10 18:23:22.399 17445 17606 W TSLocationManager: ⚠️ Already started. Ignored
04-10 18:23:22.399 17445 17606 W TSLocationManager: ⚠️ Already started. Ignored
Normal.
ok, i ran with filter: normal.log wrong.log
first execution = normal, than i close app, go to "running services" and stoped the background task, than try execute app again, and the only log i got is "wrong.log"...
but... if i close app (after wrong.log) and look at "settings > running services, no service running", open app, and it opens normal again..
Install 3.0.0.
ok i will test with 3.0
yeah im using the key >= 3.0
must be that one of the image of annoucement, not the key i have in dashboard, right?
There's a new 3.0.0 key waiting for you in the Dashboard.
In the future, customers post issues to private repo.
Other than that, see License Validation Failure
yeah i used that one of dashboard and it prints "invalid license when app opens"
begins with 39 and ends with 50, i also did the "license validation failure" --nosave...
trying again..
If your key is in the AndroidManifest.xml, it will work. If it doesn't, your package-name in AndroidManifest must not match the key it was generated for.
yeah, on version 3.0 it works fine, every app reboot open task again, but, it automatically closes but still "re-open" and send http yeah, is this expected behavior yeah?
Your Environment
cordova -v
): 8.1.2 (cordova-lib@8.1.1)cordova platform ls
): android 7.1.4Expected Behavior
when call BackgroundGeolocation.start() it should start the task..
Actual Behavior
on first execution (and even executions ) the result of .start() is:
on second execution (and odd) the result of .start() is:
Steps to Reproduce
Context
Enable the geolocation tracking service, but sometimes when i close the app and open again it wont start.. also if i go to GoogleChrome inspect console and try to start it manually typing BackgroundGeolocation.start()... it don't start...