Geofencing in progress
parent
1155466d19
commit
8d5d55a150
@ -0,0 +1,9 @@
|
|||||||
|
class GeoZonesRequestModel {
|
||||||
|
final String PatientID;
|
||||||
|
|
||||||
|
GeoZonesRequestModel({this.PatientID});
|
||||||
|
|
||||||
|
Map<String, dynamic> toFlatMap() {
|
||||||
|
return {"PatientID": PatientID.toString()};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
class LogGeoZoneRequestModel {
|
||||||
|
final int PointsID;
|
||||||
|
final int GeoType;
|
||||||
|
|
||||||
|
LogGeoZoneRequestModel({this.PointsID, this.GeoType});
|
||||||
|
|
||||||
|
Map<String, dynamic> toFlatMap() {
|
||||||
|
return {"PointsID": PointsID.toString(), "GeoType": GeoType.toString()};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
import 'package:diplomaticquarterapp/generated/json/base/json_convert_content.dart';
|
||||||
|
import 'package:diplomaticquarterapp/generated/json/base/json_field.dart';
|
||||||
|
|
||||||
|
class GeoZonesResponseModel with JsonConvert<GeoZonesResponseModel> {
|
||||||
|
@JSONField(name: "GEOF_ID")
|
||||||
|
int geofId;
|
||||||
|
@JSONField(name: "Description")
|
||||||
|
String description;
|
||||||
|
@JSONField(name: "DescriptionN")
|
||||||
|
String descriptionN;
|
||||||
|
@JSONField(name: "Latitude")
|
||||||
|
String latitude;
|
||||||
|
@JSONField(name: "Longitude")
|
||||||
|
String longitude;
|
||||||
|
@JSONField(name: "Radius")
|
||||||
|
int radius;
|
||||||
|
@JSONField(name: "Type")
|
||||||
|
int type;
|
||||||
|
@JSONField(name: "ProjectID")
|
||||||
|
int projectID;
|
||||||
|
@JSONField(name: "ImageURL")
|
||||||
|
String imageURL;
|
||||||
|
@JSONField(name: "IsCity")
|
||||||
|
bool isCity;
|
||||||
|
|
||||||
|
// Outside Server Response
|
||||||
|
bool isRegistered = false;
|
||||||
|
bool onEntry = true;
|
||||||
|
bool onExit = true;
|
||||||
|
|
||||||
|
String geofenceId() {
|
||||||
|
return "$geofId\_${description.replaceAll(" ", "")}";
|
||||||
|
}
|
||||||
|
|
||||||
|
static get(String coordinates, int radius, String name) {
|
||||||
|
coordinates = coordinates.replaceAll(" ", "");
|
||||||
|
var geo = GeoZonesResponseModel();
|
||||||
|
geo.latitude = coordinates.split(",").first;
|
||||||
|
geo.longitude = coordinates.split(",").last;
|
||||||
|
geo.radius = radius;
|
||||||
|
geo.description = name;
|
||||||
|
return geo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GeoZonesResponseModel zkH() {
|
||||||
|
var geo = GeoZonesResponseModel();
|
||||||
|
geo.latitude = "24.691136";
|
||||||
|
geo.longitude = "46.650116";
|
||||||
|
geo.radius = 150;
|
||||||
|
geo.description = "zkH";
|
||||||
|
return geo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GeoZonesResponseModel csO() {
|
||||||
|
var geo = GeoZonesResponseModel();
|
||||||
|
geo.latitude = "24.7087913";
|
||||||
|
geo.longitude = "46.6656461";
|
||||||
|
geo.radius = 150;
|
||||||
|
geo.description = "csO";
|
||||||
|
return geo;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
import 'package:diplomaticquarterapp/generated/json/base/json_convert_content.dart';
|
||||||
|
import 'package:diplomaticquarterapp/generated/json/base/json_field.dart';
|
||||||
|
|
||||||
|
class LogGeoZoneResponseModel with JsonConvert<LogGeoZoneResponseModel> {
|
||||||
|
@JSONField(name: "LanguageID")
|
||||||
|
int languageID;
|
||||||
|
@JSONField(name: "ErrorCode")
|
||||||
|
dynamic errorCode;
|
||||||
|
@JSONField(name: "ErrorEndUserMessage")
|
||||||
|
String errorEndUserMessage;
|
||||||
|
@JSONField(name: "ErrorEndUserMessageN")
|
||||||
|
dynamic errorEndUserMessageN;
|
||||||
|
@JSONField(name: "ErrorMessage")
|
||||||
|
dynamic errorMessage;
|
||||||
|
@JSONField(name: "ErrorType")
|
||||||
|
int errorType;
|
||||||
|
@JSONField(name: "IsAuthenticated")
|
||||||
|
bool isAuthenticated;
|
||||||
|
@JSONField(name: "SuccessMsg")
|
||||||
|
dynamic successMsg;
|
||||||
|
@JSONField(name: "SuccessMsgN")
|
||||||
|
dynamic successMsgN;
|
||||||
|
int statusCode;
|
||||||
|
@JSONField(name: "MessageStatus")
|
||||||
|
int messageStatus;
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:diplomaticquarterapp/config/config.dart';
|
||||||
|
import 'package:diplomaticquarterapp/core/model/geofencing/requests/GeoZonesRequestModel.dart';
|
||||||
|
import 'package:diplomaticquarterapp/core/model/geofencing/requests/LogGeoZoneRequestModel.dart';
|
||||||
|
import 'package:diplomaticquarterapp/core/model/geofencing/responses/GeoZonesResponseModel.dart';
|
||||||
|
import 'package:diplomaticquarterapp/core/model/geofencing/responses/LogGeoZoneResponseModel.dart';
|
||||||
|
import 'package:diplomaticquarterapp/core/service/base_service.dart';
|
||||||
|
|
||||||
|
import '../../../locator.dart';
|
||||||
|
|
||||||
|
class GeofencingServices extends BaseService {
|
||||||
|
List<GeoZonesResponseModel> geoZones = List();
|
||||||
|
|
||||||
|
Future<List<GeoZonesResponseModel>> getAllGeoZones(GeoZonesRequestModel request) async {
|
||||||
|
hasError = false;
|
||||||
|
await baseAppClient.post(GET_GEO_ZONES, onSuccess: (dynamic response, int statusCode) {
|
||||||
|
response['GeoF_PointsList'].forEach((json) {
|
||||||
|
geoZones.add(GeoZonesResponseModel().fromJson(json));
|
||||||
|
});
|
||||||
|
}, onFailure: (String error, int statusCode) {
|
||||||
|
hasError = true;
|
||||||
|
return Future.error(error);
|
||||||
|
}, body: request.toFlatMap());
|
||||||
|
return geoZones;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogGeoZoneResponseModel logResponse;
|
||||||
|
Future<LogGeoZoneResponseModel> logMyGeoZone(LogGeoZoneRequestModel request) async {
|
||||||
|
hasError = false;
|
||||||
|
await baseAppClient.post(LOG_GEO_ZONES, onSuccess: (dynamic response, int statusCode) {
|
||||||
|
logResponse = LogGeoZoneResponseModel().fromJson(response);
|
||||||
|
}, onFailure: (String error, int statusCode) {
|
||||||
|
hasError = true;
|
||||||
|
return Future.error(error);
|
||||||
|
}, body: request.toFlatMap());
|
||||||
|
return logResponse;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
import 'package:diplomaticquarterapp/core/model/geofencing/responses/GeoZonesResponseModel.dart';
|
||||||
|
|
||||||
|
geoZonesResponseModelEntityFromJson(GeoZonesResponseModel data, Map<String, dynamic> json) {
|
||||||
|
if (json['GEOF_ID'] != null) {
|
||||||
|
data.geofId = json['GEOF_ID']?.toInt();
|
||||||
|
}
|
||||||
|
if (json['Description'] != null) {
|
||||||
|
data.description = json['Description']?.toString();
|
||||||
|
}
|
||||||
|
if (json['DescriptionN'] != null) {
|
||||||
|
data.descriptionN = json['DescriptionN']?.toString();
|
||||||
|
}
|
||||||
|
if (json['Latitude'] != null) {
|
||||||
|
data.latitude = json['Latitude']?.toString();
|
||||||
|
}
|
||||||
|
if (json['Longitude'] != null) {
|
||||||
|
data.longitude = json['Longitude']?.toString();
|
||||||
|
}
|
||||||
|
if (json['Radius'] != null) {
|
||||||
|
data.radius = json['Radius']?.toInt();
|
||||||
|
}
|
||||||
|
if (json['Type'] != null) {
|
||||||
|
data.type = json['Type']?.toInt();
|
||||||
|
}
|
||||||
|
if (json['ProjectID'] != null) {
|
||||||
|
data.projectID = json['ProjectID']?.toInt();
|
||||||
|
}
|
||||||
|
if (json['ImageURL'] != null) {
|
||||||
|
data.imageURL = json['ImageURL']?.toString();
|
||||||
|
}
|
||||||
|
if (json['IsCity'] != null) {
|
||||||
|
data.isCity = json['IsCity'];
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> geoZonesResponseModelEntityToJson(GeoZonesResponseModel entity) {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['GEOF_ID'] = entity.geofId;
|
||||||
|
data['Description'] = entity.description;
|
||||||
|
data['DescriptionN'] = entity.descriptionN;
|
||||||
|
data['Latitude'] = entity.latitude;
|
||||||
|
data['Longitude'] = entity.longitude;
|
||||||
|
data['Radius'] = entity.radius;
|
||||||
|
data['Type'] = entity.type;
|
||||||
|
data['ProjectID'] = entity.projectID;
|
||||||
|
data['ImageURL'] = entity.imageURL;
|
||||||
|
data['IsCity'] = entity.isCity;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
import 'package:diplomaticquarterapp/core/model/geofencing/responses/LogGeoZoneResponseModel.dart';
|
||||||
|
|
||||||
|
logGeoZoneResponseModelEntityFromJson(LogGeoZoneResponseModel data, Map<String, dynamic> json) {
|
||||||
|
if (json['LanguageID'] != null) {
|
||||||
|
data.languageID = json['LanguageID']?.toInt();
|
||||||
|
}
|
||||||
|
if (json['ErrorCode'] != null) {
|
||||||
|
data.errorCode = json['ErrorCode'];
|
||||||
|
}
|
||||||
|
if (json['ErrorEndUserMessage'] != null) {
|
||||||
|
data.errorEndUserMessage = json['ErrorEndUserMessage']?.toString();
|
||||||
|
}
|
||||||
|
if (json['ErrorEndUserMessageN'] != null) {
|
||||||
|
data.errorEndUserMessageN = json['ErrorEndUserMessageN'];
|
||||||
|
}
|
||||||
|
if (json['ErrorMessage'] != null) {
|
||||||
|
data.errorMessage = json['ErrorMessage'];
|
||||||
|
}
|
||||||
|
if (json['ErrorType'] != null) {
|
||||||
|
data.errorType = json['ErrorType']?.toInt();
|
||||||
|
}
|
||||||
|
if (json['IsAuthenticated'] != null) {
|
||||||
|
data.isAuthenticated = json['IsAuthenticated'];
|
||||||
|
}
|
||||||
|
if (json['SuccessMsg'] != null) {
|
||||||
|
data.successMsg = json['SuccessMsg'];
|
||||||
|
}
|
||||||
|
if (json['SuccessMsgN'] != null) {
|
||||||
|
data.successMsgN = json['SuccessMsgN'];
|
||||||
|
}
|
||||||
|
if (json['statusCode'] != null) {
|
||||||
|
data.statusCode = json['statusCode']?.toInt();
|
||||||
|
}
|
||||||
|
if (json['MessageStatus'] != null) {
|
||||||
|
data.messageStatus = json['MessageStatus']?.toInt();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> logGeoZoneResponseModelEntityToJson(LogGeoZoneResponseModel entity) {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['LanguageID'] = entity.languageID;
|
||||||
|
data['ErrorCode'] = entity.errorCode;
|
||||||
|
data['ErrorEndUserMessage'] = entity.errorEndUserMessage;
|
||||||
|
data['ErrorEndUserMessageN'] = entity.errorEndUserMessageN;
|
||||||
|
data['ErrorMessage'] = entity.errorMessage;
|
||||||
|
data['ErrorType'] = entity.errorType;
|
||||||
|
data['IsAuthenticated'] = entity.isAuthenticated;
|
||||||
|
data['SuccessMsg'] = entity.successMsg;
|
||||||
|
data['SuccessMsgN'] = entity.successMsgN;
|
||||||
|
data['statusCode'] = entity.statusCode;
|
||||||
|
data['MessageStatus'] = entity.messageStatus;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
@ -0,0 +1,120 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'dart:isolate';
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:diplomaticquarterapp/config/shared_pref_kay.dart';
|
||||||
|
import 'package:diplomaticquarterapp/core/model/geofencing/responses/GeoZonesResponseModel.dart';
|
||||||
|
import 'package:diplomaticquarterapp/uitl/LocalNotification.dart';
|
||||||
|
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:geofencing/geofencing.dart';
|
||||||
|
|
||||||
|
class HMG_Geofence {
|
||||||
|
static var _isolatePortName = "hmg_geofencing_send_port";
|
||||||
|
|
||||||
|
List<GeoZonesResponseModel> _zones;
|
||||||
|
List<String> registeredGeofences = [];
|
||||||
|
|
||||||
|
final AndroidGeofencingSettings androidSettings = AndroidGeofencingSettings(initialTrigger: <GeofenceEvent>[GeofenceEvent.enter, GeofenceEvent.exit, GeofenceEvent.dwell], loiteringDelay: 1000 * 60);
|
||||||
|
|
||||||
|
final BuildContext context;
|
||||||
|
final List<GeofenceEvent> triggers = List();
|
||||||
|
ReceivePort port = ReceivePort();
|
||||||
|
|
||||||
|
HMG_Geofence(this.context) {
|
||||||
|
triggers.add(GeofenceEvent.enter);
|
||||||
|
triggers.add(GeofenceEvent.exit);
|
||||||
|
// triggers.add(GeofenceEvent.dwell);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initiate(List<GeoZonesResponseModel> zones) async {
|
||||||
|
_zones = zones;
|
||||||
|
|
||||||
|
if (kDebugMode) {
|
||||||
|
// debug check
|
||||||
|
addTestingGeofences();
|
||||||
|
}
|
||||||
|
_saveZones();
|
||||||
|
await GeofencingManager.initialize();
|
||||||
|
await Future.delayed(Duration(seconds: 2));
|
||||||
|
_registerIsolatePort();
|
||||||
|
_registerGeofences().then((value) {
|
||||||
|
debugPrint(value.toString());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _saveZones() {
|
||||||
|
var list = List();
|
||||||
|
_zones.forEach((element) {
|
||||||
|
list.add(element.toJson());
|
||||||
|
});
|
||||||
|
|
||||||
|
var jsonString = jsonEncode(list);
|
||||||
|
AppSharedPreferences pref = AppSharedPreferences();
|
||||||
|
pref.setString(HMG_GEOFENCES, jsonString);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<String>> _registerGeofences() async {
|
||||||
|
registeredGeofences = await GeofencingManager.getRegisteredGeofenceIds();
|
||||||
|
|
||||||
|
var maxLimit = Platform.isIOS ? 20 : 100;
|
||||||
|
|
||||||
|
if (registeredGeofences.length < maxLimit) {
|
||||||
|
var notRegistered = _zones.where((element) => !(registeredGeofences.contains(element.geofenceId()))).toList();
|
||||||
|
for (int i = 0; i < notRegistered.length; i++) {
|
||||||
|
var zone = notRegistered.elementAt(i);
|
||||||
|
var lat = double.tryParse(zone.latitude);
|
||||||
|
var lon = double.tryParse(zone.longitude);
|
||||||
|
var rad = double.tryParse(zone.radius.toString());
|
||||||
|
|
||||||
|
if (lat != null || lon != null || rad != null) {
|
||||||
|
await GeofencingManager.registerGeofence(GeofenceRegion(zone.geofenceId(), lat, lon, rad, triggers), transitionTrigger);
|
||||||
|
registeredGeofences.add(zone.geofenceId());
|
||||||
|
if (registeredGeofences.length >= maxLimit) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
await Future.delayed(Duration(milliseconds: 100));
|
||||||
|
debugPrint("Geofence: ${zone.description} registered");
|
||||||
|
} else {
|
||||||
|
debugPrint("Geofence: ${zone.description} registered");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return registeredGeofences;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addTestingGeofences() {
|
||||||
|
_zones.add(GeoZonesResponseModel.get("24.777577,46.652675", 150, "msH"));
|
||||||
|
_zones.add(GeoZonesResponseModel.get("24.691136,46.650116", 150, "zkH"));
|
||||||
|
_zones.add(GeoZonesResponseModel.get("24.7087913,46.6656461", 150, "csO"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void transitionTrigger(List<String> id, Location location, GeofenceEvent event) async {
|
||||||
|
id.forEach((element) {
|
||||||
|
final SendPort send = IsolateNameServer.lookupPortByName(_isolatePortName);
|
||||||
|
send?.send(event.toString());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _registerIsolatePort() {
|
||||||
|
IsolateNameServer.registerPortWithName(port.sendPort, _isolatePortName);
|
||||||
|
AppSharedPreferences pref = AppSharedPreferences();
|
||||||
|
var jsonString = pref.getString(HMG_GEOFENCES);
|
||||||
|
List jsonList = json.decode(jsonString);
|
||||||
|
jsonList.forEach((element) {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
port.listen((dynamic data) {
|
||||||
|
LocalNotification.showNow(
|
||||||
|
title: "HMG-Geofence",
|
||||||
|
subtitle: element,
|
||||||
|
onClickNotification: (payload) {
|
||||||
|
debugPrint(payload);
|
||||||
|
},
|
||||||
|
payload: "Zohaib Kambrani");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue