geofencing login check fix

merge-requests/236/head
Zohaib Kambrani 4 years ago
parent d8bd7d145d
commit 508bc191be

@ -80,7 +80,7 @@
<receiver android:name=".geofence.GeofenceBroadcastReceiver" android:enabled="true" android:exported="true" /> <receiver android:name=".geofence.GeofenceBroadcastReceiver" android:enabled="true" android:exported="true" />
<receiver android:name=".geofence.GeofencingRebootBroadcastReceiver" android:enabled="true"> <receiver android:name=".geofence.GeofencingRebootBroadcastReceiver" android:enabled="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="android.intent.action.BOOT_COMPLETE"/>
</intent-filter> </intent-filter>
</receiver> </receiver>

@ -37,6 +37,7 @@ class GeoZoneModel {
val rad = Radius.toFloat() val rad = Radius.toFloat()
if(lat != null && long != null){ if(lat != null && long != null){
val loiteringDelayMinutes:Int = 5 // in Minutes
return Geofence.Builder() return Geofence.Builder()
.setRequestId(identifier()) .setRequestId(identifier())
.setCircularRegion( .setCircularRegion(
@ -46,6 +47,7 @@ class GeoZoneModel {
) )
.setTransitionTypes(GeofenceTransition.ENTER_EXIT.value) .setTransitionTypes(GeofenceTransition.ENTER_EXIT.value)
// .setNotificationResponsiveness(0) // .setNotificationResponsiveness(0)
// .setLoiteringDelay(loiteringDelayMinutes * 60 * 1000)
.setExpirationDuration(Geofence.NEVER_EXPIRE) .setExpirationDuration(Geofence.NEVER_EXPIRE)
.build() .build()
} }

@ -5,9 +5,24 @@ package com.cloud.diplomaticquarterapp.geofence
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.util.Log
import com.cloud.diplomaticquarterapp.utils.saveLog
import com.google.android.gms.location.GeofencingEvent
class GeofenceBroadcastReceiver : BroadcastReceiver() { class GeofenceBroadcastReceiver : BroadcastReceiver() {
private val LOG_TAG = "GeofenceBroadcastReceiver"
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
GeofenceTransitionsJobIntentService.enqueueWork(context, intent)
val geofencingEvent = GeofencingEvent.fromIntent(intent)
if (geofencingEvent.hasError()) {
val errorMessage = GeofenceErrorMessages.getErrorString(context, geofencingEvent.errorCode)
Log.e(LOG_TAG, errorMessage)
saveLog(context,LOG_TAG,errorMessage)
return
} }
HMG_Geofence.shared(context).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition));
}
} }

@ -0,0 +1,13 @@
package com.cloud.diplomaticquarterapp.geofence
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
class GeofenceBroadcastReceiverWithService : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
GeofenceTransitionsJobIntentService.enqueueWork(context, intent)
}
}

@ -52,8 +52,9 @@ class GeofenceTransitionsJobIntentService : JobIntentService() {
private const val LOG_TAG = "GeoTrIntentService" private const val LOG_TAG = "GeoTrIntentService"
private const val JOB_ID = 573 private const val JOB_ID = 573
var context_: Context? = null
fun enqueueWork(context: Context, intent: Intent) { fun enqueueWork(context: Context, intent: Intent) {
context_ = context
enqueueWork( enqueueWork(
context, context,
GeofenceTransitionsJobIntentService::class.java, JOB_ID, GeofenceTransitionsJobIntentService::class.java, JOB_ID,
@ -70,37 +71,9 @@ class GeofenceTransitionsJobIntentService : JobIntentService() {
} }
if (geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { if (geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); context_?.let {
} HMG_Geofence.shared(it).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition));
} }
private fun handleEvent(triggerGeofences: List<Geofence>, location:Location, transition:GeofenceTransition) {
val hmg = HMG_Geofence.shared(this)
hmg.getPatientID()?.let { patientId ->
hmg.getActiveGeofences({ activeGeofences ->
triggerGeofences.forEach { geofence ->
// Extract PointID from 'geofence.requestId' and find from active geofences
val pointID = activeGeofences.firstOrNull {it == geofence.requestId}?.split('_')?.first()
if(!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null){
val body = mapOf(
"PointsID" to pointID.toIntOrNull(),
"GeoType" to transition.value,
"PatientID" to patientId
)
httpPost<Map<String,Any>>(API.LOG_GEOFENCE, body, { response ->
sendNotification(this, transition.named(), geofence.requestId, "Notified to server.😎")
},{ exception ->
sendNotification(this, transition.named(), geofence.requestId, "Failed to notify server.😔")
})
}
}
},null)
} }
} }
} }

@ -13,7 +13,8 @@ import com.cloud.diplomaticquarterapp.utils.HMGUtils
class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.action)) { // if (Intent.ACTION_BOOT_COMPLETED.equals(intent.action)) {
if (intent.action.equals("android.intent.action.BOOT_COMPLETE")) {
val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE)
pref.edit().putString("REBOOT_DETECTED","YES").apply() pref.edit().putString("REBOOT_DETECTED","YES").apply()

@ -6,7 +6,9 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.location.Location
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.cloud.diplomaticquarterapp.utils.*
import com.google.android.gms.location.Geofence import com.google.android.gms.location.Geofence
import com.google.android.gms.location.GeofencingClient import com.google.android.gms.location.GeofencingClient
import com.google.android.gms.location.GeofencingRequest import com.google.android.gms.location.GeofencingRequest
@ -37,6 +39,7 @@ const val PREFS_STORAGE = "FlutterSharedPreferences"
const val PREF_KEY_SUCCESS = "HMG_GEOFENCE_SUCCESS" const val PREF_KEY_SUCCESS = "HMG_GEOFENCE_SUCCESS"
const val PREF_KEY_FAILED = "HMG_GEOFENCE_FAILED" const val PREF_KEY_FAILED = "HMG_GEOFENCE_FAILED"
const val PREF_KEY_HMG_ZONES = "flutter.hmg-geo-fences" const val PREF_KEY_HMG_ZONES = "flutter.hmg-geo-fences"
const val PREF_KEY_LANGUAGE = "flutter.language"
class HMG_Geofence { class HMG_Geofence {
// https://developer.android.com/training/location/geofencing#java // https://developer.android.com/training/location/geofencing#java
@ -99,6 +102,7 @@ class HMG_Geofence {
} }
.addOnFailureListener { .addOnFailureListener {
print(it.localizedMessage) print(it.localizedMessage)
saveLog(context,"error:ADD_GEOFENCES", it.localizedMessage)
} }
} }
},null) },null)
@ -107,7 +111,6 @@ class HMG_Geofence {
fun unRegisterAll(completion: (status: Boolean, exception:Exception?) -> Unit){ fun unRegisterAll(completion: (status: Boolean, exception:Exception?) -> Unit){
getActiveGeofences({ success -> getActiveGeofences({ success ->
val mList = success.toMutableList() val mList = success.toMutableList()
mList.add("12345")
geofencingClient geofencingClient
.removeGeofences(success) .removeGeofences(success)
.addOnSuccessListener { .addOnSuccessListener {
@ -115,6 +118,7 @@ class HMG_Geofence {
} }
.addOnFailureListener { .addOnFailureListener {
completion(false, it) completion(false, it)
saveLog(context,"error:REMOVE_GEOFENCES", it.localizedMessage)
} }
removeActiveGeofences() removeActiveGeofences()
}, { failed -> }, { failed ->
@ -154,7 +158,10 @@ class HMG_Geofence {
} }
fun getPatientID():Int?{ fun getPatientID():Int?{
val profileJson = preferences.getString("flutter.imei-user-data", "{}") var profileJson = preferences.getString("flutter.imei-user-data", null)
if (profileJson == null)
profileJson = preferences.getString("flutter.user-profile", null)
val type = object : TypeToken<Map<String?, Any?>?>() {}.type val type = object : TypeToken<Map<String?, Any?>?>() {}.type
return gson.fromJson<Map<String?, Any?>?>(profileJson,type) return gson.fromJson<Map<String?, Any?>?>(profileJson,type)
?.get("PatientID") ?.get("PatientID")
@ -162,4 +169,34 @@ class HMG_Geofence {
.toDoubleOrNull() .toDoubleOrNull()
?.toInt() ?.toInt()
} }
fun handleEvent(triggerGeofences: List<Geofence>, location: Location, transition:GeofenceTransition) {
getPatientID()?.let { patientId ->
getActiveGeofences({ activeGeofences ->
triggerGeofences.forEach { geofence ->
// Extract PointID from 'geofence.requestId' and find from active geofences
val pointID = activeGeofences.firstOrNull {it == geofence.requestId}?.split('_')?.first()
if(!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null){
val body = mutableMapOf<String,Any?>(
"PointsID" to pointID.toIntOrNull(),
"GeoType" to transition.value,
"PatientID" to patientId
)
body.putAll(HMGUtils.defaultHTTPParams(context))
httpPost<Map<String,Any>>(API.LOG_GEOFENCE, body, { response ->
sendNotification(context, transition.named(), geofence.requestId, "Notified to server.😎")
},{ exception ->
sendNotification(context, transition.named(), geofence.requestId, "Failed to notify server.😔")
})
}
}
},null)
}
}
} }

@ -16,6 +16,7 @@ import com.cloud.diplomaticquarterapp.R
import com.cloud.diplomaticquarterapp.geofence.GeoZoneModel import com.cloud.diplomaticquarterapp.geofence.GeoZoneModel
import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE
import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_HMG_ZONES import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_HMG_ZONES
import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_LANGUAGE
import com.github.kittinunf.fuel.core.extensions.jsonBody import com.github.kittinunf.fuel.core.extensions.jsonBody
import com.github.kittinunf.fuel.httpPost import com.github.kittinunf.fuel.httpPost
import com.google.android.gms.location.Geofence import com.google.android.gms.location.Geofence
@ -76,6 +77,26 @@ class HMGUtils {
return geoZones return geoZones
} }
fun getLanguageCode(context: Context) : Int{
val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE)
val lang = pref.getString(PREF_KEY_LANGUAGE,"ar")
return if(lang == "ar") 2 else 1
}
fun defaultHTTPParams(context: Context) : Map<String,Any?>{
return mapOf(
"ZipCode" to "966",
"VersionID" to 5.6,
"Channel" to 3,
"LanguageID" to getLanguageCode(context),
"IPAdress" to "10.20.10.20",
"generalid" to "Cs2020@2016$2958",
"PatientOutSA" to 0,
"SessionID" to null,
"isDentalAllowedBackend" to false,
"DeviceTypeID" to 2)
}
} }
} }
@ -117,7 +138,9 @@ fun sendNotification(context: Context, title:String, @Nullable subtitle:String?,
notificationManager.notify(getUniqueId(), notification.build()) notificationManager.notify(getUniqueId(), notification.build())
} }
//-------------------------
// Open Helper Methods
//-------------------------
private fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt()) private fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt())
fun isJSONValid(jsonString: String?): Boolean { fun isJSONValid(jsonString: String?): Boolean {
@ -129,11 +152,18 @@ fun isJSONValid(jsonString: String?): Boolean {
return true return true
} }
fun saveLog(context:Context, tag:String, message:String){
val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE)
var logs = pref.getString("GEO_LOGS","")
logs += "$tag -> $message \n"
pref.edit().putString("PLATFORM_LOGS", logs).apply();
}
class HTTPResponse<T>(data: T){ class HTTPResponse<T>(data: T){
final var data:T = data final var data:T = data
} }
fun <T>httpPost(url: String, body: Map<String, Any?>, onSuccess: (response: HTTPResponse<T>) -> Unit, onError: (error: Exception) -> Unit){
fun <T>httpPost(url: String, body: Map<String, Any?>, onSuccess: (response: HTTPResponse<T>) -> Unit, onError: (error: Exception) -> Unit){
val gson = Gson() val gson = Gson()
val type = object : TypeToken<T>() {}.type val type = object : TypeToken<T>() {}.type
val jsonBody = gson.toJson(body) val jsonBody = gson.toJson(body)
@ -153,7 +183,6 @@ fun <T>httpPost(url: String, body: Map<String, Any?>, onSuccess: (response: HTTP
} }
}, { }, {
onError(it) onError(it)
it.localizedMessage
}) })
} }

@ -8,7 +8,6 @@ import GoogleMaps
let locationManager = CLLocationManager() let locationManager = CLLocationManager()
override func application( _ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { override func application( _ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// initLocationManager()
GMSServices.provideAPIKey("AIzaSyCiiJiHkocPbcziHt9O8rGWavDrxHRQys8") GMSServices.provideAPIKey("AIzaSyCiiJiHkocPbcziHt9O8rGWavDrxHRQys8")
GeneratedPluginRegistrant.register(with: self) GeneratedPluginRegistrant.register(with: self)
@ -24,24 +23,3 @@ import GoogleMaps
return super.application(application, didFinishLaunchingWithOptions: launchOptions) return super.application(application, didFinishLaunchingWithOptions: launchOptions)
} }
} }
extension AppDelegate: CLLocationManagerDelegate {
func initLocationManager(){
locationManager.allowsBackgroundLocationUpdates = true
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.activityType = .other
locationManager.delegate = self
locationManager.requestAlwaysAuthorization()
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
if region is CLCircularRegion {
}
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
if region is CLCircularRegion {
}
}
}

@ -18,6 +18,16 @@ extension String{
} }
} }
extension Dictionary{
func merge(dict:[String:Any?]) -> [String:Any?]{
var self_ = self as! [String:Any?]
dict.forEach { (kv) in
self_.updateValue(kv.value, forKey: kv.key)
}
return self_
}
}
extension Bundle { extension Bundle {
func certificate(named name: String) -> SecCertificate { func certificate(named name: String) -> SecCertificate {

@ -49,9 +49,35 @@ func showNotification(identifier:String? = nil, title:String?, subtitle:String?,
} }
} }
func appLanguageCode() -> Int{
let lang = UserDefaults.standard.string(forKey: "language") ?? "ar"
return lang == "ar" ? 2 : 1
}
func userProfile() -> [String:Any?]?{
var userProf = UserDefaults.standard.string(forKey: "flutter.imei-user-data")
if(userProf == nil){
userProf = UserDefaults.standard.string(forKey: "flutter.user-profile")
}
return dictionary(from: userProf ?? "{}")
}
func httpPostRequest(urlString:String, jsonBody:[String:Any], completion:((Bool,[String:Any]?)->Void)?){ fileprivate let defaultHTTPParams:[String : Any?] = [
let json: [String: Any] = jsonBody "ZipCode" : "966",
"VersionID" : 5.6,
"Channel" : 3,
"LanguageID" : appLanguageCode(),
"IPAdress" : "10.20.10.20",
"generalid" : "Cs2020@2016$2958",
"PatientOutSA" : 0,
"SessionID" : nil,
"isDentalAllowedBackend" : false,
"DeviceTypeID" : 2
]
func httpPostRequest(urlString:String, jsonBody:[String:Any?], completion:((Bool,[String:Any]?)->Void)?){
var json: [String: Any?] = jsonBody
json = json.merge(dict: defaultHTTPParams)
let jsonData = try? JSONSerialization.data(withJSONObject: json) let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request // create post request

@ -156,8 +156,13 @@ extension HMG_Geofence{
func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?){ func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?){
df.dateFormat = "MMM/dd/yyyy hh:mm:ss" df.dateFormat = "MMM/dd/yyyy hh:mm:ss"
if let userProfileJson = UserDefaults.standard.string(forKey: "flutter.imei-user-data"), var userInfo = UserDefaults.standard.string(forKey: "flutter.imei-user-data")
let userProfile = dictionary(from: userProfileJson), let patientId = userProfile["PatientID"] as? Int{ if(userInfo == nil){
userInfo = UserDefaults.standard.string(forKey: "flutter.user-profile")
}
if let userProfile = userProfile(),
let patientId = userProfile["PatientID"] as? Int{
if let idString = forRegion.identifier.split(separator: "_").first, let idInt = Int(idString){ if let idString = forRegion.identifier.split(separator: "_").first, let idInt = Int(idString){
let body:[String:Any] = [ let body:[String:Any] = [
@ -172,15 +177,14 @@ extension HMG_Geofence{
showNotification(title: transition.name(), subtitle: forRegion.identifier, message: status_) showNotification(title: transition.name(), subtitle: forRegion.identifier, message: status_)
var logs = UserDefaults.init(suiteName: "GeoFenceLog")?.dictionary(forKey: "LOGS") ?? [:] var logs = UserDefaults.init(suiteName: "GeoFenceLog")?.dictionary(forKey: "GEOFENCE_LOGS") ?? [:]
if var geo = logs[forRegion.identifier] as? [String]{ if var geo = logs[forRegion.identifier] as? [String]{
geo.append("\(status_) at \(df.string(from: Date()))") geo.append("\(status_) at \(df.string(from: Date()))")
}else{ }else{
logs.updateValue(["\(status_) at \(df.string(from: Date()))"], forKey: forRegion.identifier) logs.updateValue(["\(status_) at \(df.string(from: Date()))"], forKey: forRegion.identifier)
} }
UserDefaults.init(suiteName: "GeoFenceLog")?.set(logs, forKey: "LOGS") UserDefaults.init(suiteName: "GeoFenceLog")?.set(logs, forKey: "GEOFENCE_LOGS")
} }
} }
} }

@ -142,11 +142,14 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
PlatformBridge().connectHMGGuestWifi().then((value) => {GifLoaderDialogUtils.hideDialog(context)}); PlatformBridge().connectHMGGuestWifi().then((value) => {GifLoaderDialogUtils.hideDialog(context)});
}).checkAndConnectIfNoInternet(); }).checkAndConnectIfNoInternet();
if (Platform.isIOS) { if (Platform.isIOS) {
_firebaseMessaging.requestNotificationPermissions(); _firebaseMessaging.requestNotificationPermissions();
} }
requestPermissions().then((results) { requestPermissions().then((results) {
registerGeofences();
if (results[Permission.notification].isGranted) if (results[Permission.notification].isGranted)
_firebaseMessaging.getToken().then((String token) { _firebaseMessaging.getToken().then((String token) {
sharedPref.setString(PUSH_TOKEN, token); sharedPref.setString(PUSH_TOKEN, token);
@ -156,7 +159,7 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
} }
}); });
if (results[Permission.location].isGranted) ; if (results[Permission.locationAlways].isGranted) ;
if (results[Permission.storage].isGranted) ; if (results[Permission.storage].isGranted) ;
if (results[Permission.camera].isGranted) ; if (results[Permission.camera].isGranted) ;
if (results[Permission.photos].isGranted) ; if (results[Permission.photos].isGranted) ;
@ -436,7 +439,6 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
void checkUserStatus(token) async { void checkUserStatus(token) async {
var result = await authService.selectDeviceImei(token); var result = await authService.selectDeviceImei(token);
await setUserValues(result); await setUserValues(result);
registerGeofences();
if (await sharedPref.getObject(USER_PROFILE) != null) { if (await sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE));
@ -483,22 +485,14 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
registerGeofences() async { registerGeofences() async {
await locator<GeofencingServices>().getAllGeoZones(GeoZonesRequestModel()); await locator<GeofencingServices>().getAllGeoZones(GeoZonesRequestModel());
var userInfo = await getUserInformation();
void doIt() {
projectViewModel.platformBridge().registerHmgGeofences();
}
if (userInfo != null) {
if (await Permission.location.isGranted) { if (await Permission.location.isGranted) {
doIt(); PlatformBridge().registerHmgGeofences();
} else { } else {
[Permission.location].request().then((value) async { [Permission.location].request().then((results) async {
if (await Permission.location.isGranted) { if (results[Permission.locationAlways].isGranted){
doIt(); PlatformBridge().registerHmgGeofences();
} }
}); });
} }
} }
}
} }

Loading…
Cancel
Save