2019-08-30 15:04:51 +03:00
|
|
|
part of '../main.dart';
|
|
|
|
|
|
|
|
class LocationManager {
|
|
|
|
|
2019-10-20 20:54:29 +03:00
|
|
|
static final LocationManager _instance = LocationManager
|
|
|
|
._internal();
|
|
|
|
|
|
|
|
factory LocationManager() {
|
|
|
|
return _instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
LocationManager._internal() {
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
2019-10-21 21:22:25 +03:00
|
|
|
final int defaultUpdateIntervalMinutes = 20;
|
|
|
|
final String backgroundTaskId = "haclocationtask4352";
|
|
|
|
final String backgroundTaskTag = "haclocation";
|
2019-10-20 20:54:29 +03:00
|
|
|
Duration _updateInterval;
|
2019-10-24 21:34:38 +03:00
|
|
|
bool _isRunning;
|
2019-10-20 20:54:29 +03:00
|
|
|
|
|
|
|
void init() async {
|
|
|
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
|
|
await prefs.reload();
|
|
|
|
_updateInterval = Duration(minutes: prefs.getInt("location-interval") ??
|
|
|
|
defaultUpdateIntervalMinutes);
|
2019-10-24 21:34:38 +03:00
|
|
|
_isRunning = prefs.getBool("location-enabled") ?? false;
|
|
|
|
if (_isRunning) {
|
|
|
|
await _startLocationService();
|
2019-10-20 20:54:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-24 21:58:48 +03:00
|
|
|
setSettings(bool enabled, int interval) async {
|
2019-10-20 20:54:29 +03:00
|
|
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
|
|
if (interval != _updateInterval.inMinutes) {
|
|
|
|
prefs.setInt("location-interval", interval);
|
|
|
|
_updateInterval = Duration(minutes: interval);
|
2019-10-24 21:34:38 +03:00
|
|
|
if (_isRunning) {
|
|
|
|
Logger.d("Stopping location tracking...");
|
|
|
|
_isRunning = false;
|
|
|
|
await _stopLocationService();
|
|
|
|
}
|
2019-10-20 20:54:29 +03:00
|
|
|
}
|
2019-10-24 21:34:38 +03:00
|
|
|
if (enabled && !_isRunning) {
|
|
|
|
Logger.d("Starting location tracking");
|
2019-10-20 20:54:29 +03:00
|
|
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
|
|
prefs.setBool("location-enabled", enabled);
|
2019-10-24 21:34:38 +03:00
|
|
|
_isRunning = true;
|
|
|
|
await _startLocationService();
|
|
|
|
} else if (!enabled && _isRunning) {
|
|
|
|
Logger.d("Stopping location tracking...");
|
2019-10-20 20:54:29 +03:00
|
|
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
|
|
prefs.setBool("location-enabled", enabled);
|
2019-10-24 21:34:38 +03:00
|
|
|
_isRunning = false;
|
|
|
|
await _stopLocationService();
|
2019-10-20 20:54:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-24 21:34:38 +03:00
|
|
|
_startLocationService() async {
|
2019-10-20 20:54:29 +03:00
|
|
|
Logger.d("Scheduling location update for every ${_updateInterval
|
|
|
|
.inMinutes} minutes...");
|
2019-10-21 21:22:25 +03:00
|
|
|
String webhookId = ConnectionManager().webhookId;
|
|
|
|
String httpWebHost = ConnectionManager().httpWebHost;
|
|
|
|
if (webhookId != null && webhookId.isNotEmpty) {
|
|
|
|
await workManager.Workmanager.registerPeriodicTask(
|
|
|
|
backgroundTaskId,
|
|
|
|
"haClientLocationTracking",
|
|
|
|
tag: backgroundTaskTag,
|
|
|
|
inputData: {
|
|
|
|
"webhookId": webhookId,
|
|
|
|
"httpWebHost": httpWebHost
|
|
|
|
},
|
|
|
|
frequency: _updateInterval,
|
2019-10-22 21:42:30 +03:00
|
|
|
existingWorkPolicy: workManager.ExistingWorkPolicy.keep,
|
2019-10-21 21:22:25 +03:00
|
|
|
backoffPolicy: workManager.BackoffPolicy.linear,
|
2019-10-22 21:42:30 +03:00
|
|
|
backoffPolicyDelay: _updateInterval,
|
2019-10-21 21:22:25 +03:00
|
|
|
constraints: workManager.Constraints(
|
|
|
|
networkType: workManager.NetworkType.connected
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
2019-10-20 20:54:29 +03:00
|
|
|
}
|
|
|
|
|
2019-10-24 21:34:38 +03:00
|
|
|
_stopLocationService() async {
|
2019-10-20 20:54:29 +03:00
|
|
|
Logger.d("Canceling previous schedule if any...");
|
2019-10-21 21:22:25 +03:00
|
|
|
await workManager.Workmanager.cancelByTag(backgroundTaskTag);
|
2019-10-20 20:54:29 +03:00
|
|
|
}
|
|
|
|
|
2019-10-24 21:34:38 +03:00
|
|
|
updateDeviceLocation() async {
|
2019-10-30 18:54:25 +02:00
|
|
|
Logger.d("[Test location] Started");
|
2019-11-01 15:44:51 +02:00
|
|
|
Logger.d("[Test location] Forcing Android location manager...");
|
|
|
|
Geolocator geolocator = Geolocator()..forceAndroidLocationManager = true;
|
2019-10-30 18:54:25 +02:00
|
|
|
var battery = Battery();
|
|
|
|
int batteryLevel = 100;
|
|
|
|
String webhookId = ConnectionManager().webhookId;
|
|
|
|
String httpWebHost = ConnectionManager().httpWebHost;
|
|
|
|
if (webhookId != null && webhookId.isNotEmpty) {
|
|
|
|
String url = "$httpWebHost/api/webhook/$webhookId";
|
2019-10-20 20:54:29 +03:00
|
|
|
Map<String, String> headers = {};
|
2019-10-30 18:54:25 +02:00
|
|
|
headers["Content-Type"] = "application/json";
|
|
|
|
Map data = {
|
2019-10-20 20:54:29 +03:00
|
|
|
"type": "update_location",
|
|
|
|
"data": {
|
2019-10-30 18:54:25 +02:00
|
|
|
"gps": [],
|
|
|
|
"gps_accuracy": 0,
|
|
|
|
"battery": batteryLevel
|
2019-10-20 20:54:29 +03:00
|
|
|
}
|
|
|
|
};
|
2019-10-30 18:54:25 +02:00
|
|
|
Logger.d("[Test location] Getting battery level...");
|
|
|
|
battery.batteryLevel.then((val) => data["data"]["battery"] = val).whenComplete((){
|
|
|
|
Logger.d("[Test location] Getting device location...");
|
2019-11-01 15:44:51 +02:00
|
|
|
geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high, locationPermissionLevel: GeolocationPermission.locationAlways).then((location) {
|
2019-10-30 18:54:25 +02:00
|
|
|
Logger.d("[Test location] Got location: ${location.latitude} ${location.longitude} with accuracy of ${location.accuracy}");
|
|
|
|
if (location != null) {
|
|
|
|
data["data"]["gps"] = [location.latitude, location.longitude];
|
|
|
|
data["data"]["gps_accuracy"] = location.accuracy;
|
|
|
|
Logger.d("[Test location] Sending data home...");
|
|
|
|
http.post(
|
|
|
|
url,
|
|
|
|
headers: headers,
|
|
|
|
body: json.encode(data)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}).catchError((e) {
|
|
|
|
Logger.d("[Test location] Error getting current location: ${e.toString()}. Trying last known...");
|
2019-11-01 15:44:51 +02:00
|
|
|
geolocator.getLastKnownPosition(desiredAccuracy: LocationAccuracy.medium).then((location){
|
2019-10-30 18:54:25 +02:00
|
|
|
Logger.d("[Test location] Got last known location: ${location.latitude} ${location.longitude} with accuracy of ${location.accuracy}");
|
|
|
|
if (location != null) {
|
|
|
|
data["data"]["gps"] = [location.latitude, location.longitude];
|
|
|
|
data["data"]["gps_accuracy"] = location.accuracy;
|
|
|
|
Logger.d("[Test location] Sending data home...");
|
|
|
|
http.post(
|
|
|
|
url,
|
|
|
|
headers: headers,
|
|
|
|
body: json.encode(data)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2019-10-20 20:54:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void updateDeviceLocationIsolate() {
|
2019-10-21 21:22:25 +03:00
|
|
|
workManager.Workmanager.executeTask((backgroundTask, data) {
|
2019-10-24 21:34:38 +03:00
|
|
|
//print("[Background $backgroundTask] Started");
|
2019-11-01 15:44:51 +02:00
|
|
|
Geolocator geolocator = Geolocator()..forceAndroidLocationManager = true;
|
2019-10-24 21:34:38 +03:00
|
|
|
var battery = Battery();
|
|
|
|
int batteryLevel = 100;
|
2019-10-21 21:22:25 +03:00
|
|
|
String webhookId = data["webhookId"];
|
|
|
|
String httpWebHost = data["httpWebHost"];
|
|
|
|
if (webhookId != null && webhookId.isNotEmpty) {
|
2019-10-24 21:34:38 +03:00
|
|
|
//print("[Background $backgroundTask] hour=$battery");
|
2019-10-22 21:42:30 +03:00
|
|
|
String url = "$httpWebHost/api/webhook/$webhookId";
|
|
|
|
Map<String, String> headers = {};
|
|
|
|
headers["Content-Type"] = "application/json";
|
2019-10-24 21:34:38 +03:00
|
|
|
Map data = {
|
|
|
|
"type": "update_location",
|
|
|
|
"data": {
|
|
|
|
"gps": [],
|
|
|
|
"gps_accuracy": 0,
|
|
|
|
"battery": batteryLevel
|
|
|
|
}
|
|
|
|
};
|
|
|
|
//print("[Background $backgroundTask] Getting battery level...");
|
|
|
|
battery.batteryLevel.then((val) => data["data"]["battery"] = val).whenComplete((){
|
|
|
|
//print("[Background $backgroundTask] Getting device location...");
|
2019-11-01 15:44:51 +02:00
|
|
|
geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high, locationPermissionLevel: GeolocationPermission.locationAlways).then((location) {
|
2019-10-24 21:34:38 +03:00
|
|
|
//print("[Background $backgroundTask] Got location: ${location.latitude} ${location.longitude}");
|
2019-10-24 22:18:27 +03:00
|
|
|
if (location != null) {
|
2019-10-24 21:34:38 +03:00
|
|
|
data["data"]["gps"] = [location.latitude, location.longitude];
|
|
|
|
data["data"]["gps_accuracy"] = location.accuracy;
|
|
|
|
//print("[Background $backgroundTask] Sending data home...");
|
|
|
|
http.post(
|
2019-10-24 22:18:27 +03:00
|
|
|
url,
|
|
|
|
headers: headers,
|
|
|
|
body: json.encode(data)
|
2019-10-24 21:34:38 +03:00
|
|
|
);
|
2019-10-24 22:18:27 +03:00
|
|
|
}
|
|
|
|
}).catchError((e) {
|
|
|
|
//print("[Background $backgroundTask] Error getting current location: ${e.toString()}. Trying last known...");
|
2019-11-01 15:44:51 +02:00
|
|
|
geolocator.getLastKnownPosition(desiredAccuracy: LocationAccuracy.medium).then((location){
|
2019-10-24 22:18:27 +03:00
|
|
|
//print("[Background $backgroundTask] Got last known location: ${location.latitude} ${location.longitude}");
|
|
|
|
if (location != null) {
|
|
|
|
data["data"]["gps"] = [location.latitude, location.longitude];
|
|
|
|
data["data"]["gps_accuracy"] = location.accuracy;
|
|
|
|
//print("[Background $backgroundTask] Sending data home...");
|
|
|
|
http.post(
|
|
|
|
url,
|
|
|
|
headers: headers,
|
|
|
|
body: json.encode(data)
|
|
|
|
);
|
|
|
|
}
|
2019-10-22 21:42:30 +03:00
|
|
|
});
|
|
|
|
});
|
2019-10-20 20:54:29 +03:00
|
|
|
});
|
2019-10-21 21:22:25 +03:00
|
|
|
}
|
2019-10-20 20:54:29 +03:00
|
|
|
return Future.value(true);
|
|
|
|
});
|
2019-08-30 15:04:51 +03:00
|
|
|
}
|