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.GeofencingRebootBroadcastReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.BOOT_COMPLETE"/>
</intent-filter>
</receiver>

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

@ -5,9 +5,24 @@ package com.cloud.diplomaticquarterapp.geofence
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
import com.cloud.diplomaticquarterapp.utils.saveLog
import com.google.android.gms.location.GeofencingEvent
class GeofenceBroadcastReceiver : BroadcastReceiver() {
private val LOG_TAG = "GeofenceBroadcastReceiver"
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 JOB_ID = 573
var context_: Context? = null
fun enqueueWork(context: Context, intent: Intent) {
context_ = context
enqueueWork(
context,
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) {
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(){
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)
pref.edit().putString("REBOOT_DETECTED","YES").apply()

@ -6,7 +6,9 @@ import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.location.Location
import androidx.core.content.ContextCompat
import com.cloud.diplomaticquarterapp.utils.*
import com.google.android.gms.location.Geofence
import com.google.android.gms.location.GeofencingClient
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_FAILED = "HMG_GEOFENCE_FAILED"
const val PREF_KEY_HMG_ZONES = "flutter.hmg-geo-fences"
const val PREF_KEY_LANGUAGE = "flutter.language"
class HMG_Geofence {
// https://developer.android.com/training/location/geofencing#java
@ -99,6 +102,7 @@ class HMG_Geofence {
}
.addOnFailureListener {
print(it.localizedMessage)
saveLog(context,"error:ADD_GEOFENCES", it.localizedMessage)
}
}
},null)
@ -107,7 +111,6 @@ class HMG_Geofence {
fun unRegisterAll(completion: (status: Boolean, exception:Exception?) -> Unit){
getActiveGeofences({ success ->
val mList = success.toMutableList()
mList.add("12345")
geofencingClient
.removeGeofences(success)
.addOnSuccessListener {
@ -115,6 +118,7 @@ class HMG_Geofence {
}
.addOnFailureListener {
completion(false, it)
saveLog(context,"error:REMOVE_GEOFENCES", it.localizedMessage)
}
removeActiveGeofences()
}, { failed ->
@ -154,7 +158,10 @@ class HMG_Geofence {
}
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
return gson.fromJson<Map<String?, Any?>?>(profileJson,type)
?.get("PatientID")
@ -162,4 +169,34 @@ class HMG_Geofence {
.toDoubleOrNull()
?.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.PREFS_STORAGE
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.httpPost
import com.google.android.gms.location.Geofence
@ -76,6 +77,26 @@ class HMGUtils {
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())
}
//-------------------------
// Open Helper Methods
//-------------------------
private fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt())
fun isJSONValid(jsonString: String?): Boolean {
@ -129,11 +152,18 @@ fun isJSONValid(jsonString: String?): Boolean {
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){
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 type = object : TypeToken<T>() {}.type
val jsonBody = gson.toJson(body)
@ -153,7 +183,6 @@ fun <T>httpPost(url: String, body: Map<String, Any?>, onSuccess: (response: HTTP
}
}, {
onError(it)
it.localizedMessage
})
}

@ -8,7 +8,6 @@ import GoogleMaps
let locationManager = CLLocationManager()
override func application( _ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// initLocationManager()
GMSServices.provideAPIKey("AIzaSyCiiJiHkocPbcziHt9O8rGWavDrxHRQys8")
GeneratedPluginRegistrant.register(with: self)
@ -24,24 +23,3 @@ import GoogleMaps
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 {
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)?){
let json: [String: Any] = jsonBody
fileprivate let defaultHTTPParams:[String : Any?] = [
"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)
// create post request

@ -156,8 +156,13 @@ extension HMG_Geofence{
func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?){
df.dateFormat = "MMM/dd/yyyy hh:mm:ss"
if let userProfileJson = UserDefaults.standard.string(forKey: "flutter.imei-user-data"),
let userProfile = dictionary(from: userProfileJson), let patientId = userProfile["PatientID"] as? Int{
var userInfo = UserDefaults.standard.string(forKey: "flutter.imei-user-data")
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){
let body:[String:Any] = [
@ -172,15 +177,14 @@ extension HMG_Geofence{
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]{
geo.append("\(status_) at \(df.string(from: Date()))")
}else{
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)});
}).checkAndConnectIfNoInternet();
if (Platform.isIOS) {
_firebaseMessaging.requestNotificationPermissions();
}
requestPermissions().then((results) {
registerGeofences();
if (results[Permission.notification].isGranted)
_firebaseMessaging.getToken().then((String 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.camera].isGranted) ;
if (results[Permission.photos].isGranted) ;
@ -436,7 +439,6 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
void checkUserStatus(token) async {
var result = await authService.selectDeviceImei(token);
await setUserValues(result);
registerGeofences();
if (await sharedPref.getObject(USER_PROFILE) != null) {
var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE));
@ -483,22 +485,14 @@ class _LandingPageState extends State<LandingPage> with WidgetsBindingObserver {
registerGeofences() async {
await locator<GeofencingServices>().getAllGeoZones(GeoZonesRequestModel());
var userInfo = await getUserInformation();
void doIt() {
projectViewModel.platformBridge().registerHmgGeofences();
}
if (userInfo != null) {
if (await Permission.location.isGranted) {
doIt();
PlatformBridge().registerHmgGeofences();
} else {
[Permission.location].request().then((value) async {
if (await Permission.location.isGranted) {
doIt();
[Permission.location].request().then((results) async {
if (results[Permission.locationAlways].isGranted){
PlatformBridge().registerHmgGeofences();
}
});
}
}
}
}

Loading…
Cancel
Save