diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 9bff802f..b2132a0d 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -7,6 +7,7 @@
FlutterApplication and put your custom class here. -->
+
@@ -73,6 +74,13 @@
+
+
+
+
+
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 8c6c1ed1..e27d2e38 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -24,6 +24,8 @@
NSCameraUsageDescription
Need camera access for uploading images
+ NSLocationAlwaysAndWhenInUseUsageDescription
+ This app will use your location to show cool stuffs near you.
NSLocationUsageDescription
Need location access for updating nearby friends
NSLocationWhenInUseUsageDescription
@@ -32,6 +34,10 @@
Need microphone access for uploading videos
NSPhotoLibraryUsageDescription
Need photo library access for uploading images
+ UIBackgroundModes
+
+ location
+
UILaunchStoryboardName
LaunchScreen
UIMainStoryboardFile
@@ -53,5 +59,11 @@
io.flutter.embedded_views_preview
+ UIRequiredDeviceCapabilities
+
+ location-services
+ gps
+ armv7
+
diff --git a/lib/config/config.dart b/lib/config/config.dart
index 1108a6e2..c82c8593 100644
--- a/lib/config/config.dart
+++ b/lib/config/config.dart
@@ -1,5 +1,6 @@
import 'dart:io';
+import 'package:diplomaticquarterapp/core/service/geofencing/GeofencingServices.dart';
import 'package:diplomaticquarterapp/models/Request.dart';
import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart';
import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.dart';
@@ -17,6 +18,10 @@ const PING_SERVICE = 'Services/Weather.svc/REST/CheckConnectivity';
// const BASE_URL = 'https://hmgwebservices.com/';
const GET_PROJECT = 'Services/Lists.svc/REST/GetProject';
+///Geofencing
+const GET_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_GetAllPoints';
+const LOG_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_InsertPatientFileInfo';
+
///Doctor
const GET_MY_DOCTOR = 'Services/Doctors.svc/REST/GetPatientDoctorAppointmentResult';
const GET_DOCTOR_PROFILE = 'Services/Doctors.svc/REST/GetDocProfiles';
diff --git a/lib/config/shared_pref_kay.dart b/lib/config/shared_pref_kay.dart
index b79edb08..30d866de 100644
--- a/lib/config/shared_pref_kay.dart
+++ b/lib/config/shared_pref_kay.dart
@@ -20,3 +20,4 @@ const IS_VIBRATION = 'is_vibration';
const THEME_VALUE = 'is_vibration';
const MAIN_USER = 'main-user';
const PHARMACY_LAST_VISITED_PRODUCTS = 'last-visited';
+const HMG_GEOFENCES = 'hmg-geo-fences';
diff --git a/lib/core/model/geofencing/requests/GeoZonesRequestModel.dart b/lib/core/model/geofencing/requests/GeoZonesRequestModel.dart
new file mode 100644
index 00000000..b807691e
--- /dev/null
+++ b/lib/core/model/geofencing/requests/GeoZonesRequestModel.dart
@@ -0,0 +1,9 @@
+class GeoZonesRequestModel {
+ final String PatientID;
+
+ GeoZonesRequestModel({this.PatientID});
+
+ Map toFlatMap() {
+ return {"PatientID": PatientID.toString()};
+ }
+}
diff --git a/lib/core/model/geofencing/requests/LogGeoZoneRequestModel.dart b/lib/core/model/geofencing/requests/LogGeoZoneRequestModel.dart
new file mode 100644
index 00000000..181dea37
--- /dev/null
+++ b/lib/core/model/geofencing/requests/LogGeoZoneRequestModel.dart
@@ -0,0 +1,10 @@
+class LogGeoZoneRequestModel {
+ final int PointsID;
+ final int GeoType;
+
+ LogGeoZoneRequestModel({this.PointsID, this.GeoType});
+
+ Map toFlatMap() {
+ return {"PointsID": PointsID.toString(), "GeoType": GeoType.toString()};
+ }
+}
diff --git a/lib/core/model/geofencing/responses/GeoZonesResponseModel.dart b/lib/core/model/geofencing/responses/GeoZonesResponseModel.dart
new file mode 100644
index 00000000..58771fab
--- /dev/null
+++ b/lib/core/model/geofencing/responses/GeoZonesResponseModel.dart
@@ -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 {
+ @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;
+ }
+}
diff --git a/lib/core/model/geofencing/responses/LogGeoZoneResponseModel.dart b/lib/core/model/geofencing/responses/LogGeoZoneResponseModel.dart
new file mode 100644
index 00000000..2242755f
--- /dev/null
+++ b/lib/core/model/geofencing/responses/LogGeoZoneResponseModel.dart
@@ -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 {
+ @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;
+}
diff --git a/lib/core/service/geofencing/GeofencingServices.dart b/lib/core/service/geofencing/GeofencingServices.dart
new file mode 100644
index 00000000..a40fa8ea
--- /dev/null
+++ b/lib/core/service/geofencing/GeofencingServices.dart
@@ -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 geoZones = List();
+
+ Future> 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 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;
+ }
+}
diff --git a/lib/core/service/packages_offers/PackagesOffersServices.dart b/lib/core/service/packages_offers/PackagesOffersServices.dart
index d75744b6..e58c3fa3 100644
--- a/lib/core/service/packages_offers/PackagesOffersServices.dart
+++ b/lib/core/service/packages_offers/PackagesOffersServices.dart
@@ -18,7 +18,6 @@ class OffersAndPackagesServices extends BaseService {
hasError = false;
var url = EXA_CART_API_BASE_URL + PACKAGES_CATEGORIES;
await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) {
- log(stringResponse);
if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse);
jsonResponse['categories'].forEach((json) {
@@ -37,7 +36,6 @@ class OffersAndPackagesServices extends BaseService {
hasError = false;
var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS;
await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) {
- log(stringResponse);
if (statusCode == 200) {
var jsonResponse = json.decode(stringResponse);
jsonResponse['products'].forEach((json) {
diff --git a/lib/generated/json/GeoZonesResponseModel_helper.dart b/lib/generated/json/GeoZonesResponseModel_helper.dart
new file mode 100644
index 00000000..7cf3cc5f
--- /dev/null
+++ b/lib/generated/json/GeoZonesResponseModel_helper.dart
@@ -0,0 +1,50 @@
+import 'package:diplomaticquarterapp/core/model/geofencing/responses/GeoZonesResponseModel.dart';
+
+geoZonesResponseModelEntityFromJson(GeoZonesResponseModel data, Map 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 geoZonesResponseModelEntityToJson(GeoZonesResponseModel entity) {
+ final Map data = new Map();
+ 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;
+}
diff --git a/lib/generated/json/offer_categories_response_model_entity_helper_.dart b/lib/generated/json/OfferCategoriesResponseModel_helper.dart
similarity index 96%
rename from lib/generated/json/offer_categories_response_model_entity_helper_.dart
rename to lib/generated/json/OfferCategoriesResponseModel_helper.dart
index 08d1c7f9..e5ebc914 100644
--- a/lib/generated/json/offer_categories_response_model_entity_helper_.dart
+++ b/lib/generated/json/OfferCategoriesResponseModel_helper.dart
@@ -1,6 +1,6 @@
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart';
-offerCategoriesResponseModelEntityFromJson(OfferCategoriesResponseModel data, Map json) {
+offerCategoriesResponseModelFromJson(OfferCategoriesResponseModel data, Map json) {
if (json['id'] != null) {
data.id = json['id']?.toString();
}
@@ -91,7 +91,7 @@ offerCategoriesResponseModelEntityFromJson(OfferCategoriesResponseModel data, Ma
return data;
}
-Map offerCategoriesResponseModelEntityToJson(OfferCategoriesResponseModel entity) {
+Map offerCategoriesResponseModelToJson(OfferCategoriesResponseModel entity) {
final Map data = new Map();
data['id'] = entity.id;
data['name'] = entity.name;
diff --git a/lib/generated/json/OfferProductsResponseModel_helper_.dart b/lib/generated/json/OfferProductsResponseModel_helper.dart
similarity index 100%
rename from lib/generated/json/OfferProductsResponseModel_helper_.dart
rename to lib/generated/json/OfferProductsResponseModel_helper.dart
diff --git a/lib/generated/json/base/json_convert_content.dart b/lib/generated/json/base/json_convert_content.dart
index fbec021d..9fab946e 100644
--- a/lib/generated/json/base/json_convert_content.dart
+++ b/lib/generated/json/base/json_convert_content.dart
@@ -4,9 +4,13 @@
// This file is automatically generated. DO NOT EDIT, all your changes would be lost.
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart';
+import 'package:diplomaticquarterapp/generated/json/OfferCategoriesResponseModel_helper.dart';
+import 'package:diplomaticquarterapp/core/model/geofencing/responses/LogGeoZoneResponseModel.dart';
+import 'package:diplomaticquarterapp/generated/json/log_geo_zone_response_model_entity_helper.dart';
import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferProductsResponseModel.dart';
-import 'package:diplomaticquarterapp/generated/json/offer_categories_response_model_entity_helper_.dart';
-import 'package:diplomaticquarterapp/generated/json/OfferProductsResponseModel_helper_.dart';
+import 'package:diplomaticquarterapp/generated/json/OfferProductsResponseModel_helper.dart';
+import 'package:diplomaticquarterapp/core/model/geofencing/responses/GeoZonesResponseModel.dart';
+import 'package:diplomaticquarterapp/generated/json/GeoZonesResponseModel_helper.dart';
class JsonConvert {
T fromJson(Map json) {
@@ -20,11 +24,13 @@ class JsonConvert {
static _getFromJson(Type type, data, json) {
switch (type) {
case OfferCategoriesResponseModel:
- return offerCategoriesResponseModelEntityFromJson(data as OfferCategoriesResponseModel, json) as T;
+ return offerCategoriesResponseModelFromJson(data as OfferCategoriesResponseModel, json) as T;
case OfferCategoriesResponseModelLocalizedName:
return offerCategoriesResponseModelLocalizedNameFromJson(data as OfferCategoriesResponseModelLocalizedName, json) as T;
case OfferCategoriesResponseModelImage:
return offerCategoriesResponseModelImageFromJson(data as OfferCategoriesResponseModelImage, json) as T;
+ case LogGeoZoneResponseModel:
+ return logGeoZoneResponseModelEntityFromJson(data as LogGeoZoneResponseModel, json) as T;
case OfferProductsResponseModel:
return offerProductsResponseModelFromJson(data as OfferProductsResponseModel, json) as T;
case OfferProductsResponseModelLocalizedName:
@@ -33,6 +39,8 @@ class JsonConvert {
return offerProductsResponseModelImageFromJson(data as OfferProductsResponseModelImage, json) as T;
case OfferProductsResponseModelSpecification:
return offerProductsResponseModelSpecificationFromJson(data as OfferProductsResponseModelSpecification, json) as T;
+ case GeoZonesResponseModel:
+ return geoZonesResponseModelEntityFromJson(data as GeoZonesResponseModel, json) as T;
}
return data as T;
}
@@ -40,11 +48,13 @@ class JsonConvert {
static _getToJson(Type type, data) {
switch (type) {
case OfferCategoriesResponseModel:
- return offerCategoriesResponseModelEntityToJson(data as OfferCategoriesResponseModel);
+ return offerCategoriesResponseModelToJson(data as OfferCategoriesResponseModel);
case OfferCategoriesResponseModelLocalizedName:
return offerCategoriesResponseModelLocalizedNameToJson(data as OfferCategoriesResponseModelLocalizedName);
case OfferCategoriesResponseModelImage:
return offerCategoriesResponseModelImageToJson(data as OfferCategoriesResponseModelImage);
+ case LogGeoZoneResponseModel:
+ return logGeoZoneResponseModelEntityToJson(data as LogGeoZoneResponseModel);
case OfferProductsResponseModel:
return offerProductsResponseModelToJson(data as OfferProductsResponseModel);
case OfferProductsResponseModelLocalizedName:
@@ -53,6 +63,8 @@ class JsonConvert {
return offerProductsResponseModelImageToJson(data as OfferProductsResponseModelImage);
case OfferProductsResponseModelSpecification:
return offerProductsResponseModelSpecificationToJson(data as OfferProductsResponseModelSpecification);
+ case GeoZonesResponseModel:
+ return geoZonesResponseModelEntityToJson(data as GeoZonesResponseModel);
}
return data as T;
}
@@ -66,6 +78,8 @@ class JsonConvert {
return OfferCategoriesResponseModelLocalizedName().fromJson(json);
} else if (type == (OfferCategoriesResponseModelImage).toString()) {
return OfferCategoriesResponseModelImage().fromJson(json);
+ } else if (type == (LogGeoZoneResponseModel).toString()) {
+ return LogGeoZoneResponseModel().fromJson(json);
} else if (type == (OfferProductsResponseModel).toString()) {
return OfferProductsResponseModel().fromJson(json);
} else if (type == (OfferProductsResponseModelLocalizedName).toString()) {
@@ -74,6 +88,8 @@ class JsonConvert {
return OfferProductsResponseModelImage().fromJson(json);
} else if (type == (OfferProductsResponseModelSpecification).toString()) {
return OfferProductsResponseModelSpecification().fromJson(json);
+ } else if (type == (GeoZonesResponseModel).toString()) {
+ return GeoZonesResponseModel().fromJson(json);
}
return null;
}
@@ -86,6 +102,8 @@ class JsonConvert {
return data.map((e) => OfferCategoriesResponseModelLocalizedName().fromJson(e)).toList() as M;
} else if (List() is M) {
return data.map((e) => OfferCategoriesResponseModelImage().fromJson(e)).toList() as M;
+ } else if (List() is M) {
+ return data.map((e) => LogGeoZoneResponseModel().fromJson(e)).toList() as M;
} else if (List() is M) {
return data.map((e) => OfferProductsResponseModel().fromJson(e)).toList() as M;
} else if (List() is M) {
@@ -94,6 +112,8 @@ class JsonConvert {
return data.map((e) => OfferProductsResponseModelImage().fromJson(e)).toList() as M;
} else if (List() is M) {
return data.map((e) => OfferProductsResponseModelSpecification().fromJson(e)).toList() as M;
+ } else if (List() is M) {
+ return data.map((e) => GeoZonesResponseModel().fromJson(e)).toList() as M;
}
return null;
}
diff --git a/lib/generated/json/log_geo_zone_response_model_entity_helper.dart b/lib/generated/json/log_geo_zone_response_model_entity_helper.dart
new file mode 100644
index 00000000..28b8c996
--- /dev/null
+++ b/lib/generated/json/log_geo_zone_response_model_entity_helper.dart
@@ -0,0 +1,54 @@
+import 'package:diplomaticquarterapp/core/model/geofencing/responses/LogGeoZoneResponseModel.dart';
+
+logGeoZoneResponseModelEntityFromJson(LogGeoZoneResponseModel data, Map 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 logGeoZoneResponseModelEntityToJson(LogGeoZoneResponseModel entity) {
+ final Map data = new Map();
+ 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;
+}
diff --git a/lib/locator.dart b/lib/locator.dart
index 8916d08e..f00cc1f6 100644
--- a/lib/locator.dart
+++ b/lib/locator.dart
@@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/user_informa
import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart';
import 'package:diplomaticquarterapp/uitl/navigation_service.dart';
+import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get_it/get_it.dart';
import 'core/service/AlHabibMedicalService/cmc_service.dart';
@@ -25,6 +26,7 @@ import 'core/service/dashboard_service.dart';
import 'core/service/er/am_service.dart';
import 'core/service/er/er_service.dart';
import 'core/service/feedback/feedback_service.dart';
+import 'core/service/geofencing/GeofencingServices.dart';
import 'core/service/hospital_service.dart';
import 'core/service/medical/ActiveMedicationsService.dart';
import 'core/service/medical/AllergiesService.dart';
@@ -95,6 +97,9 @@ GetIt locator = GetIt.instance;
///di
void setupLocator() {
+ /// Others
+ locator.registerLazySingleton(() => FlutterLocalNotificationsPlugin());
+
/// Services
locator.registerLazySingleton(() => AuthenticatedUserObject());
locator.registerLazySingleton(() => HospitalService());
@@ -195,4 +200,8 @@ void setupLocator() {
locator.registerLazySingleton(() => OffersAndPackagesServices()); // offerPackagesServices Service
locator.registerFactory(() => OfferCategoriesViewModel()); // Categories View Model
locator.registerFactory(() => OfferProductsViewModel()); // Products View Model
+
+ // Geofencing
+ // ---------------------
+ locator.registerLazySingleton(() => GeofencingServices()); // Geofencing Services
}
diff --git a/lib/main.dart b/lib/main.dart
index 83492d81..54cc5040 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart';
import 'package:diplomaticquarterapp/services/robo_search/search_provider.dart';
import 'package:diplomaticquarterapp/theme/theme_value.dart';
+import 'package:diplomaticquarterapp/uitl/HMG_Geofence.dart';
import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:flutter/material.dart';
@@ -12,6 +13,8 @@ import 'package:hexcolor/hexcolor.dart';
import 'package:provider/provider.dart';
import 'config/size_config.dart';
+import 'core/model/geofencing/requests/GeoZonesRequestModel.dart';
+import 'core/service/geofencing/GeofencingServices.dart';
import 'core/viewModels/project_view_model.dart';
import 'locator.dart';
@@ -25,6 +28,11 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
PlatformBridge.init(context);
+ var geofence = HMG_Geofence(context);
+ locator().getAllGeoZones(GeoZonesRequestModel(PatientID: "1231755")).then((value) {
+ geofence.initiate(value);
+ }).catchError((e) {});
+
return LayoutBuilder(
builder: (context, constraints) {
return OrientationBuilder(
diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart
index 745733b2..79d462b5 100644
--- a/lib/pages/landing/home_page.dart
+++ b/lib/pages/landing/home_page.dart
@@ -1,6 +1,10 @@
import 'package:diplomaticquarterapp/config/size_config.dart';
+import 'package:diplomaticquarterapp/core/model/geofencing/requests/GeoZonesRequestModel.dart';
+import 'package:diplomaticquarterapp/core/model/geofencing/requests/LogGeoZoneRequestModel.dart';
+import 'package:diplomaticquarterapp/core/service/geofencing/GeofencingServices.dart';
import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart';
import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
+import 'package:diplomaticquarterapp/locator.dart';
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_index_page.dart';
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_index_page.dart';
import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/all_habib_medical_service_page.dart';
@@ -11,6 +15,7 @@ import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart';
import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart';
import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy_module_page.dart';
+import 'package:diplomaticquarterapp/uitl/HMG_Geofence.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/widgets/buttons/button.dart';
@@ -37,6 +42,7 @@ class _HomePageState extends State {
@override
Widget build(BuildContext context) {
ProjectViewModel projectViewModel = Provider.of(context);
+
return BaseView(
onModelReady: (model) => model.getPatientRadOrders(),
builder: (_, model, wi) => AppScaffold(
diff --git a/lib/uitl/HMG_Geofence.dart b/lib/uitl/HMG_Geofence.dart
new file mode 100644
index 00000000..b17d9269
--- /dev/null
+++ b/lib/uitl/HMG_Geofence.dart
@@ -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 _zones;
+ List registeredGeofences = [];
+
+ final AndroidGeofencingSettings androidSettings = AndroidGeofencingSettings(initialTrigger: [GeofenceEvent.enter, GeofenceEvent.exit, GeofenceEvent.dwell], loiteringDelay: 1000 * 60);
+
+ final BuildContext context;
+ final List triggers = List();
+ ReceivePort port = ReceivePort();
+
+ HMG_Geofence(this.context) {
+ triggers.add(GeofenceEvent.enter);
+ triggers.add(GeofenceEvent.exit);
+ // triggers.add(GeofenceEvent.dwell);
+ }
+
+ void initiate(List 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> _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 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");
+ });
+ }
+}
diff --git a/lib/uitl/LocalNotification.dart b/lib/uitl/LocalNotification.dart
index 5b826f00..43cb598a 100644
--- a/lib/uitl/LocalNotification.dart
+++ b/lib/uitl/LocalNotification.dart
@@ -1,17 +1,31 @@
+import 'dart:math';
import 'dart:typed_data';
import 'dart:ui';
+import 'package:diplomaticquarterapp/locator.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
-final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
- FlutterLocalNotificationsPlugin();
+final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
class LocalNotification {
- static Future scheduleNotification(
- {@required DateTime scheduledNotificationDateTime,
- @required String title,
- @required String description}) async {
+ static Future showNow({@required String title, @required String subtitle, String payload, Function(String payload) onClickNotification}) {
+ var plugin = FlutterLocalNotificationsPlugin();
+ var initializationSettingsAndroid = new AndroidInitializationSettings('app_icon');
+ var initializationSettingsIOS = IOSInitializationSettings(onDidReceiveLocalNotification: null);
+ var initializationSettings = InitializationSettings(initializationSettingsAndroid, initializationSettingsIOS);
+ plugin.initialize(initializationSettings, onSelectNotification: onClickNotification);
+
+ var rng = new Random();
+ Future.delayed(Duration(seconds: 1)).then((result) async {
+ var androidPlatformChannelSpecifics = AndroidNotificationDetails('com.hmg', 'HMG', 'HMG', importance: Importance.Max, priority: Priority.High, ticker: 'ticker');
+ var iOSPlatformChannelSpecifics = IOSNotificationDetails();
+ var platformChannelSpecifics = NotificationDetails(androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
+ await flutterLocalNotificationsPlugin.show(rng.nextInt(100000), title, subtitle, platformChannelSpecifics, payload: payload);
+ });
+ }
+
+ static Future scheduleNotification({@required DateTime scheduledNotificationDateTime, @required String title, @required String description}) async {
///vibrationPattern
var vibrationPattern = Int64List(4);
vibrationPattern[0] = 0;
@@ -19,10 +33,7 @@ class LocalNotification {
vibrationPattern[2] = 5000;
vibrationPattern[3] = 2000;
- var androidPlatformChannelSpecifics = AndroidNotificationDetails(
- 'active-prescriptions',
- 'ActivePrescriptions',
- 'ActivePrescriptionsDescription',
+ var androidPlatformChannelSpecifics = AndroidNotificationDetails('active-prescriptions', 'ActivePrescriptions', 'ActivePrescriptionsDescription',
// icon: 'secondary_icon',
sound: RawResourceAndroidNotificationSound('slow_spring_board'),
@@ -34,8 +45,7 @@ class LocalNotification {
ledColor: const Color.fromARGB(255, 255, 0, 0),
ledOnMs: 1000,
ledOffMs: 500);
- var iOSPlatformChannelSpecifics =
- IOSNotificationDetails(sound: 'slow_spring_board.aiff');
+ var iOSPlatformChannelSpecifics = IOSNotificationDetails(sound: 'slow_spring_board.aiff');
///change it to be as ionic
// var platformChannelSpecifics = NotificationDetails(
@@ -47,10 +57,7 @@ class LocalNotification {
///Repeat notification every day at approximately 10:00:00 am
static Future showDailyAtTime() async {
var time = Time(10, 0, 0);
- var androidPlatformChannelSpecifics = AndroidNotificationDetails(
- 'repeatDailyAtTime channel id',
- 'repeatDailyAtTime channel name',
- 'repeatDailyAtTime description');
+ var androidPlatformChannelSpecifics = AndroidNotificationDetails('repeatDailyAtTime channel id', 'repeatDailyAtTime channel name', 'repeatDailyAtTime description');
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
// var platformChannelSpecifics = NotificationDetails(
// androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
@@ -65,10 +72,7 @@ class LocalNotification {
///Repeat notification weekly on Monday at approximately 10:00:00 am
static Future showWeeklyAtDayAndTime() async {
var time = Time(10, 0, 0);
- var androidPlatformChannelSpecifics = AndroidNotificationDetails(
- 'show weekly channel id',
- 'show weekly channel name',
- 'show weekly description');
+ var androidPlatformChannelSpecifics = AndroidNotificationDetails('show weekly channel id', 'show weekly channel name', 'show weekly description');
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
// var platformChannelSpecifics = NotificationDetails(
// androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
diff --git a/pubspec.yaml b/pubspec.yaml
index 4a9206e0..a4129776 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -162,6 +162,7 @@ dependencies:
# Dep by Zohaib
shimmer: ^1.1.2
+ geofencing: ^0.1.0
dev_dependencies:
flutter_test: