diff --git a/android/app/build.gradle b/android/app/build.gradle index 91c15cde..99f2b204 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -86,7 +86,8 @@ dependencies { // Native Dependency implementation "org.jetbrains.anko:anko-commons:0.10.4" implementation 'com.github.kittinunf.fuel:fuel:2.3.0' //for JVM - implementation 'com.github.kittinunf.fuel:fuel-android:2.3.0' //for Android + implementation 'com.github.kittinunf.fuel:fuel-android:2.3.0' + implementation 'com.google.android.gms:play-services-location:17.1.0'//for Android } diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index b2132a0d..0b8b7998 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -63,8 +63,6 @@ - @@ -74,20 +72,20 @@ - - + + + + + - - diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt new file mode 100644 index 00000000..7eba1ead --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt @@ -0,0 +1,56 @@ +package com.cloud.diplomaticquarterapp.geofence + +import com.google.android.gms.location.Geofence +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken + +class GeoZoneModel { + var GEOF_ID:Int = 0 + var Radius:Int = 0 + var Type:Int = 0 + var ProjectID:Int = 0 + + var Description:String? = null + var DescriptionN:String? = null + var Latitude:String? = null + var Longitude:String? = null + var ImageURL:String? = null + var IsCity:String? = null + + fun identifier():String{ + return "$GEOF_ID" + "_hmg" + } + + fun message():String{ + return Description ?: "nil" + } + + fun listFrom(jsonString: String) : List{ + val type = object : TypeToken?>() {}.getType() + return Gson().fromJson(jsonString, type) + } + + fun toGeofence() : Geofence?{ + if (!Latitude.isNullOrEmpty() && !Longitude.isNullOrEmpty() && Radius > 50) { + val lat = Latitude!!.trim().toDoubleOrNull() + val long = Longitude!!.trim().toDoubleOrNull() + val rad = Radius.toFloat() + if(lat != null && long != null){ + + return Geofence.Builder() + .setRequestId(identifier()) + .setCircularRegion( + lat, + long, + rad + ) + .setTransitionTypes(GeofenceTransition.ENTER_EXIT.value) +// .setNotificationResponsiveness(0) + .setExpirationDuration(Geofence.NEVER_EXPIRE) + .build() + } + } + return null + } + +} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt new file mode 100644 index 00000000..e9accb04 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018 Razeware LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, + * distribute, sublicense, create a derivative work, and/or sell copies of the + * Software in any work that is designed, intended, or marketed for pedagogical or + * instructional purposes related to programming, coding, application development, + * or information technology. Permission for such use, copying, modification, + * merger, publication, distribution, sublicensing, creation of derivative works, + * or sale is expressly withheld. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.cloud.diplomaticquarterapp.geofence + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent + +class GeofenceBroadcastReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + GeofenceTransitionsJobIntentService.enqueueWork(context, intent) + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceErrorMessages.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceErrorMessages.kt new file mode 100755 index 00000000..e85c7ea3 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceErrorMessages.kt @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2018 Razeware LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, + * distribute, sublicense, create a derivative work, and/or sell copies of the + * Software in any work that is designed, intended, or marketed for pedagogical or + * instructional purposes related to programming, coding, application development, + * or information technology. Permission for such use, copying, modification, + * merger, publication, distribution, sublicensing, creation of derivative works, + * or sale is expressly withheld. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package com.cloud.diplomaticquarterapp.geofence + +import android.content.Context +import com.cloud.diplomaticquarterapp.R +import com.google.android.gms.common.api.ApiException +import com.google.android.gms.location.GeofenceStatusCodes + +object GeofenceErrorMessages { + fun getErrorString(context: Context, e: Exception): String { + return if (e is ApiException) { + getErrorString(context, e.statusCode) + } else { + context.resources.getString(R.string.geofence_unknown_error) + } + } + + fun getErrorString(context: Context, errorCode: Int): String { + val resources = context.resources + return when (errorCode) { + GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE -> + resources.getString(R.string.geofence_not_available) + + GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES -> + resources.getString(R.string.geofence_too_many_geofences) + + GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS -> + resources.getString(R.string.geofence_too_many_pending_intents) + + else -> resources.getString(R.string.geofence_unknown_error) + } + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt new file mode 100755 index 00000000..f28e1720 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2018 Razeware LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * Notwithstanding the foregoing, you may not use, copy, modify, merge, publish, + * distribute, sublicense, create a derivative work, and/or sell copies of the + * Software in any work that is designed, intended, or marketed for pedagogical or + * instructional purposes related to programming, coding, application development, + * or information technology. Permission for such use, copying, modification, + * merger, publication, distribution, sublicensing, creation of derivative works, + * or sale is expressly withheld. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +package com.cloud.diplomaticquarterapp.geofence + +import android.content.Context +import android.content.Intent +import android.location.Location +import android.util.Log +import androidx.core.app.JobIntentService +import com.cloud.diplomaticquarterapp.utils.API +import com.cloud.diplomaticquarterapp.utils.httpPost +import com.cloud.diplomaticquarterapp.utils.sendNotification +import com.github.kittinunf.fuel.core.extensions.jsonBody +import com.github.kittinunf.fuel.core.isSuccessful +import com.github.kittinunf.fuel.httpPost +import com.google.android.gms.location.Geofence +import com.google.android.gms.location.GeofencingEvent +import com.google.gson.Gson + +class GeofenceTransitionsJobIntentService : JobIntentService() { + + companion object { + private const val LOG_TAG = "GeoTrIntentService" + + private const val JOB_ID = 573 + + fun enqueueWork(context: Context, intent: Intent) { + enqueueWork( + context, + GeofenceTransitionsJobIntentService::class.java, JOB_ID, + intent) + } + } + + override fun onHandleWork(intent: Intent) { + val geofencingEvent = GeofencingEvent.fromIntent(intent) + if (geofencingEvent.hasError()) { + val errorMessage = GeofenceErrorMessages.getErrorString(this, geofencingEvent.errorCode) + Log.e(LOG_TAG, errorMessage) + return + } + + if (geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { + handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); + } + } + + private fun handleEvent(triggerGeofences: List, 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>(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) + } + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt new file mode 100644 index 00000000..641e1522 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt @@ -0,0 +1,21 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.geofencing + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.util.Log +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence + +class GeofencingRebootBroadcastReceiver : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action.equals("android.intent.action.BOOT_COMPLETED")) { + HMG_Geofence.shared(context).unRegisterAll { status, exception -> + HMG_Geofence.shared(context).re + } + } + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt new file mode 100644 index 00000000..fbef8749 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt @@ -0,0 +1,155 @@ +package com.cloud.diplomaticquarterapp.geofence + +import android.Manifest +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.content.pm.PackageManager +import androidx.core.content.ContextCompat +import com.google.android.gms.location.Geofence +import com.google.android.gms.location.GeofencingClient +import com.google.android.gms.location.GeofencingRequest +import com.google.android.gms.location.LocationServices +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken + +enum class GeofenceTransition(val value: Int) { + ENTER(1), + EXIT(2), + ENTER_EXIT((ENTER.value or EXIT.value)), + DWELL(4); + + companion object { + fun fromInt(value: Int) = GeofenceTransition.values().first { it.value == value } + } + + fun named():String{ + if (value == 1)return "Enter" + if (value == 2)return "Exit" + if (value == (ENTER.value or EXIT.value))return "Enter or Exit" + if (value == 4)return "dWell" + return "unknown" + } +} + +const val PREFS_STORAGE = "FlutterSharedPreferences" +const val PREF_KEY_SUCCESS = "HMG_GEOFENCE_SUCCESS" +const val PREF_KEY_FAILED = "HMG_GEOFENCE_FAILED" + +class HMG_Geofence { + // https://developer.android.com/training/location/geofencing#java + + private lateinit var context: Context + private lateinit var preferences:SharedPreferences + private val gson = Gson() + + private lateinit var geofencingClient:GeofencingClient + private val geofencePendingIntent: PendingIntent by lazy { + val intent = Intent(context, GeofenceBroadcastReceiver::class.java) + PendingIntent.getBroadcast( + context, + 0, + intent, + PendingIntent.FLAG_UPDATE_CURRENT) + } + + companion object{ + + var instance: HMG_Geofence? = null + fun shared(context: Context) : HMG_Geofence { + if (instance == null) { + instance = HMG_Geofence() + instance?.context = context + instance?.geofencingClient = LocationServices.getGeofencingClient(context) + instance?.preferences = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + } + return instance!! + } + } + + fun register(geoZones: List){ + + fun buildGeofencingRequest(geofences: List): GeofencingRequest { + return GeofencingRequest.Builder() + .setInitialTrigger(0) + .addGeofences(geofences) + .build() + } + + getActiveGeofences({ active -> + + val geofences = mutableListOf() + geoZones.forEach { + it.toGeofence()?.let { geof -> + if(!active.contains(geof.requestId)){ // if not already registered then register + geofences.add(geof) + } + } + } + + if (checkPermission() && geofences.isNotEmpty()) { + geofencingClient + .addGeofences(buildGeofencingRequest(geofences), geofencePendingIntent) + .addOnSuccessListener { + saveGeofenceResults(geofences.map { it.requestId }, listOf()) + } + .addOnFailureListener { + print(it.localizedMessage) + } + } + },null) + } + + fun unRegisterAll(completion: (status: Boolean, exception:Exception?) -> Unit){ + getActiveGeofences({ success -> + geofencingClient + .removeGeofences(success) + .addOnSuccessListener { + completion(true, null) + } + .addOnFailureListener { + completion(false, it) + } + }, { failed -> + // Nothing to do with failed geofences. + }) + } + + fun saveGeofenceResults(success: List, failed: List){ + val jsonSuccess = gson.toJson(success) + val jsonFailure = gson.toJson(failed) + preferences.edit().putString(PREF_KEY_SUCCESS, jsonSuccess).apply() + preferences.edit().putString(PREF_KEY_FAILED, jsonFailure).apply() + + } + + fun getActiveGeofences(success: (success: List) -> Unit, failure: ((failed: List) -> Unit)?){ + val type = object : TypeToken?>() {}.type + + val jsonSuccess = preferences.getString(PREF_KEY_SUCCESS, "[]") + val success = gson.fromJson>(jsonSuccess, type) + success(success) + + if(failure != null){ + val jsonFailure = preferences.getString(PREF_KEY_FAILED, "[]") + val failed = gson.fromJson>(jsonFailure, type) + failure(failed) + } + + } + + private fun checkPermission() : Boolean{ + return ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED + } + + fun getPatientID():Int?{ + val profileJson = preferences.getString("flutter.user-profile", "{}") + val type = object : TypeToken?>() {}.type + return gson.fromJson?>(profileJson,type) + ?.get("PatientID") + .toString() + .toDoubleOrNull() + ?.toInt() + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt index 0d5f1e7e..30f57dde 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt @@ -6,5 +6,6 @@ class API { private val SERVICE = "Services/Patients.svc/REST" val WIFI_CREDENTIALS = "$BASE/$SERVICE/Hmg_SMS_Get_By_ProjectID_And_PatientID" + val LOG_GEOFENCE = "$BASE/$SERVICE/GeoF_InsertPatientFileInfo" } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt index 13d31d74..5b0201f2 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt @@ -1,12 +1,30 @@ package com.cloud.diplomaticquarterapp.utils -import android.view.View +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.os.Build import android.widget.Toast +import androidx.annotation.Nullable +import androidx.core.app.NotificationCompat +import androidx.core.app.TaskStackBuilder +import com.cloud.diplomaticquarterapp.BuildConfig import com.cloud.diplomaticquarterapp.MainActivity +import com.cloud.diplomaticquarterapp.R +import com.github.kittinunf.fuel.core.extensions.jsonBody +import com.github.kittinunf.fuel.httpPost +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import io.flutter.plugin.common.MethodChannel +import org.json.JSONArray +import org.json.JSONException +import org.json.JSONObject import java.util.* import kotlin.concurrent.timerTask + class HMGUtils { companion object{ @@ -14,34 +32,34 @@ class HMGUtils { fun getPlatformChannel():MethodChannel{ return platformChannel } - fun setPlatformChannel(channel:MethodChannel){ + fun setPlatformChannel(channel: MethodChannel){ platformChannel = channel } - fun timer(delay:Long, repeat:Boolean, tick:(Timer)->Unit) : Timer{ + fun timer(delay: Long, repeat: Boolean, tick: (Timer) -> Unit) : Timer{ val timer = Timer() if(repeat) timer.schedule(timerTask { tick(timer) - },delay,delay) + }, delay, delay) else timer.schedule(timerTask { tick(timer) - },delay) + }, delay) return timer } - fun popMessage(context:MainActivity, message:String){ + fun popMessage(context: MainActivity, message: String){ context.runOnUiThread { - Toast.makeText(context,message,Toast.LENGTH_LONG).show() + Toast.makeText(context, message, Toast.LENGTH_LONG).show() } } - fun popFlutterText(context:MainActivity, key:String){ + fun popFlutterText(context: MainActivity, key: String){ context.runOnUiThread { FlutterText.with(key){ - Toast.makeText(context,it,Toast.LENGTH_LONG).show() + Toast.makeText(context, it, Toast.LENGTH_LONG).show() } } } @@ -53,3 +71,78 @@ class HMGUtils { private fun Timer.schedule(timerTask: TimerTask) { } +private const val NOTIFICATION_CHANNEL_ID = BuildConfig.APPLICATION_ID + ".channel" + +fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, message:String?) { + val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID) == null) { + val name = context.getString(R.string.app_name) + val channel = NotificationChannel(NOTIFICATION_CHANNEL_ID, + name, + NotificationManager.IMPORTANCE_DEFAULT) + + notificationManager.createNotificationChannel(channel) + } + + val intent = Intent(context, MainActivity::class.java) + + val stackBuilder = TaskStackBuilder.create(context) + .addParentStack(MainActivity::class.java) + .addNextIntent(intent) + val notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT) + + val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) + .setSmallIcon(R.mipmap.ic_launcher) + .setContentIntent(notificationPendingIntent) + .setAutoCancel(true) + .setContentTitle(title) + + subtitle.let { notification.setContentText(it) } + message.let { notification.setSubText(it) } + + notificationManager.notify(getUniqueId(), notification.build()) +} + + +private fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt()) + +fun isJSONValid(jsonString: String?): Boolean { + try { JSONObject(jsonString) } catch (ex: JSONException) { + try { JSONArray(jsonString) } catch (ex1: JSONException) { + return false + } + } + return true +} + +class HTTPResponse(data: T){ + final var data:T = data +} +fun httpPost(url: String, body: Map, onSuccess: (response: HTTPResponse) -> Unit, onError: (error: Exception) -> Unit){ + + val gson = Gson() + val type = object : TypeToken() {}.type + val jsonBody = gson.toJson(body) + url.httpPost() + .jsonBody(jsonBody, Charsets.UTF_8) + .timeout(10000) + .header("Content-Type","application/json") + .header("Allow","*/*") + .response { request, response, result -> + result.fold({ data -> + val dataString = String(data) + if(isJSONValid(dataString)){ + val responseData = gson.fromJson(dataString,type) + onSuccess(HTTPResponse(responseData)) + }else{ + onError(Exception("Invalid response from server (Not a valid JSON)")) + } + }, { + onError(it) + it.localizedMessage + }) + + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HTTPRequest.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HTTPRequest.kt deleted file mode 100644 index e34c7c9b..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HTTPRequest.kt +++ /dev/null @@ -1,46 +0,0 @@ -package com.cloud.diplomaticquarterapp.utils - -import android.util.Log -import java.io.BufferedReader -import java.io.InputStreamReader -import java.io.OutputStreamWriter -import java.net.HttpURLConnection -import java.net.URL -import java.net.URLEncoder - -class HTTPRequest { - val TAG = "HTTPRequest" - - fun post(serverURL:String, params:Map){ - - var encodedParamsList = params.map { - URLEncoder.encode(it.key, "UTF-8") + "=" + URLEncoder.encode(it.value,"UTF-8") - } - - val postParam = encodedParamsList.joinToString (separator = "&") - - - val url = URL(serverURL) - - with(url.openConnection() as HttpURLConnection) { - requestMethod = "POST" - - val wr = OutputStreamWriter(outputStream) - wr.write(postParam) - wr.flush() - - BufferedReader(InputStreamReader(inputStream)).use { - val response = StringBuffer() - - var inputLIne = it.readLine() - while(inputLIne != null) { - response.append(inputLIne) - inputLIne = it.readLine() - } - - it.close() - Log.v(TAG,response.toString()) - } - } - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt index 0f69a444..ed1a62c8 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt @@ -3,11 +3,11 @@ package com.cloud.diplomaticquarterapp.utils import android.content.Context import android.net.wifi.WifiManager import android.util.Log -import android.widget.Toast -import androidx.annotation.UiThread import com.cloud.diplomaticquarterapp.MainActivity import com.cloud.diplomaticquarterapp.hmgwifi.HMG_Guest import com.cloud.diplomaticquarterapp.hmgwifi.HMG_Internet +import com.cloud.diplomaticquarterapp.geofence.GeoZoneModel +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel @@ -23,7 +23,8 @@ class PlatformBridge(binaryMessenger: BinaryMessenger, flutterMainActivity: Main private const val HMG_INTERNET_WIFI_CONNECT_METHOD = "connectHMGInternetWifi" private const val HMG_GUEST_WIFI_CONNECT_METHOD = "connectHMGGuestWifi" private const val ENABLE_WIFI_IF_NOT = "enableWifiIfNot" - + private const val REGISTER_HMG_GEOFENCES = "registerHmgGeofences" + private const val UN_REGISTER_HMG_GEOFENCES = "unRegisterHmgGeofences" } fun create(){ @@ -39,6 +40,10 @@ class PlatformBridge(binaryMessenger: BinaryMessenger, flutterMainActivity: Main }else if (methodCall.method == ENABLE_WIFI_IF_NOT) { enableWifiIfNot(methodCall,result) + }else if (methodCall.method == REGISTER_HMG_GEOFENCES) { + registerHmgGeofences(methodCall,result) + }else if (methodCall.method == UN_REGISTER_HMG_GEOFENCES) { + unRegisterHmgGeofences(methodCall,result) }else{ result.notImplemented() @@ -89,8 +94,34 @@ class PlatformBridge(binaryMessenger: BinaryMessenger, flutterMainActivity: Main if (!wm.isWifiEnabled) wm.isWifiEnabled = true result.success(true) - }else{ + }else result.error("101","Error while opening wifi, Please try to open wifi yourself and try again","'WifiManager' service failed"); + } + + + private fun registerHmgGeofences(methodCall: MethodCall, result: MethodChannel.Result) { + + channel.invokeMethod("getGeoZones",null, object : MethodChannel.Result{ + override fun success(result: Any?) { + if(result is String) { + val geoZones = GeoZoneModel().listFrom(result) + HMG_Geofence.shared(mainActivity).register(geoZones) + } + } + + override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) { print(result) } + override fun notImplemented() { print(result) } + }) + + } + + private fun unRegisterHmgGeofences(methodCall: MethodCall, result: MethodChannel.Result) { + HMG_Geofence.shared(mainActivity).unRegisterAll { status, exception -> + if(status) + result.success(true) + else + result.error("101", exception?.localizedMessage, exception); } } -} \ No newline at end of file + +} diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml new file mode 100755 index 00000000..8acc0c12 --- /dev/null +++ b/android/app/src/main/res/values/strings.xml @@ -0,0 +1,16 @@ + + HMG Patient App + + + Unknown error: the Geofence service is not available now. + + + Geofence service is not available now. Go to Settings>Location>Mode and choose High accuracy. + + + Your app has registered too many geofences. + + + You have provided too many PendingIntents to the addGeofences() call. + + diff --git a/ios/.gitignore b/ios/.gitignore index e67828a4..04b5cf29 100644 --- a/ios/.gitignore +++ b/ios/.gitignore @@ -30,6 +30,4 @@ Runner/GeneratedPluginRegistrant.* !default.mode2v3 !default.pbxuser !default.perspectivev3 -/Runner.xcworkspace/contents.xcworkspacedata -/Runner.xcodeproj/project.pbxproj /Flutter/.last_build_id diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6a965de8..d65de659 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -20,7 +20,7 @@ PODS: - Firebase/Messaging (6.33.0): - Firebase/CoreOnly - FirebaseMessaging (~> 4.7.0) - - firebase_core (0.5.2): + - firebase_core (0.5.3): - Firebase/CoreOnly (~> 6.33.0) - Flutter - firebase_core_web (0.1.0): @@ -70,7 +70,7 @@ PODS: - Flutter - flutter_tts (0.0.1): - Flutter - - "geolocator (6.0.0+4)": + - geolocator (6.1.9): - Flutter - google_maps_flutter (0.0.1): - Flutter @@ -375,7 +375,7 @@ SPEC CHECKSUMS: device_calendar: 23b28a5f1ab3bf77e34542fb1167e1b8b29a98f5 device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 - firebase_core: 350ba329d1641211bc6183a3236893cafdacfea7 + firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659 firebase_core_web: d501d8b946b60c8af265428ce483b0fff5ad52d1 firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75 FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd @@ -390,7 +390,7 @@ SPEC CHECKSUMS: flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186 flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35 flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d - geolocator: 1ae40084cc6c1586ce5ad12cfc3fd38c64d05f2f + geolocator: 057a0c63a43e9c5296d8ad845a3ac8e6df23d899 google_maps_flutter: c7f9c73576de1fbe152a227bfd6e6c4ae8088619 GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 GoogleMaps: 4b5346bddfe6911bb89155d43c903020170523ac @@ -438,6 +438,6 @@ SPEC CHECKSUMS: webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96 wifi: d7d77c94109e36c4175d845f0a5964eadba71060 -PODFILE CHECKSUM: ac5efa1ac3c9555d0008dc18004313c84746da62 +PODFILE CHECKSUM: 5a17be3f8af73a757fa4439c77cf6ab2db29a6e7 -COCOAPODS: 1.10.0 +COCOAPODS: 1.8.4 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..009006ed --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,697 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 813F9CBA7DD5ED63B28B8BB6 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 767C165F7ABF3BF1F829B9BF /* Pods_Runner.framework */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + E91B5396256AAA6500E96549 /* GlobalHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = E91B538D256AAA6500E96549 /* GlobalHelper.swift */; }; + E91B5397256AAA6500E96549 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E91B538E256AAA6500E96549 /* Extensions.swift */; }; + E91B5398256AAA6500E96549 /* API.swift in Sources */ = {isa = PBXBuildFile; fileRef = E91B538F256AAA6500E96549 /* API.swift */; }; + E91B539A256AAA6500E96549 /* MainFlutterVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = E91B5392256AAA6500E96549 /* MainFlutterVC.swift */; }; + E91B539B256AAA6500E96549 /* HMG_Internet.swift in Sources */ = {isa = PBXBuildFile; fileRef = E91B5394256AAA6500E96549 /* HMG_Internet.swift */; }; + E91B539C256AAA6500E96549 /* HMG_GUEST_bkp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E91B5395256AAA6500E96549 /* HMG_GUEST_bkp.swift */; }; + E91B539F256AAC1400E96549 /* GuestPOC_Certificate.p12 in Resources */ = {isa = PBXBuildFile; fileRef = E91B539D256AAC1400E96549 /* GuestPOC_Certificate.p12 */; }; + E91B53A0256AAC1400E96549 /* GuestPOC_Certificate.cer in Resources */ = {isa = PBXBuildFile; fileRef = E91B539E256AAC1400E96549 /* GuestPOC_Certificate.cer */; }; + E91B53A3256AAD8200E96549 /* Main_Custom.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E91B53A1256AAD8200E96549 /* Main_Custom.storyboard */; }; + E923EFD225863FDF00E3E751 /* GeoZoneModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E923EFD125863FDF00E3E751 /* GeoZoneModel.swift */; }; + E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */ = {isa = PBXBuildFile; fileRef = E923EFD3258645C100E3E751 /* HMG_Geofence.swift */; }; + E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */; }; + E923EFD82588D17700E3E751 /* gpx.gpx in Resources */ = {isa = PBXBuildFile; fileRef = E923EFD72588D17700E3E751 /* gpx.gpx */; }; + E9620805255C2ED100D3A35D /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9620804255C2ED100D3A35D /* NetworkExtension.framework */; }; + E9C8C136256BACDA00EFFB62 /* HMG_Guest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C8C135256BACDA00EFFB62 /* HMG_Guest.swift */; }; + E9E27168256E3A4000F49B69 /* LocalizedFromFlutter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 308FEC658188F7D588BE7580 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 767C165F7ABF3BF1F829B9BF /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 969F0CEC868FD7C196987A3E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DCFFD369041FFFFA94CF7B26 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + E91B538D256AAA6500E96549 /* GlobalHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalHelper.swift; sourceTree = ""; }; + E91B538E256AAA6500E96549 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; + E91B538F256AAA6500E96549 /* API.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = API.swift; sourceTree = ""; }; + E91B5392256AAA6500E96549 /* MainFlutterVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainFlutterVC.swift; sourceTree = ""; }; + E91B5394256AAA6500E96549 /* HMG_Internet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMG_Internet.swift; sourceTree = ""; }; + E91B5395256AAA6500E96549 /* HMG_GUEST_bkp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMG_GUEST_bkp.swift; sourceTree = ""; }; + E91B539D256AAC1400E96549 /* GuestPOC_Certificate.p12 */ = {isa = PBXFileReference; lastKnownFileType = file; path = GuestPOC_Certificate.p12; sourceTree = ""; }; + E91B539E256AAC1400E96549 /* GuestPOC_Certificate.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = GuestPOC_Certificate.cer; sourceTree = ""; }; + E91B53A2256AAD8200E96549 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_Custom.storyboard; sourceTree = ""; }; + E923EFD125863FDF00E3E751 /* GeoZoneModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoZoneModel.swift; sourceTree = ""; }; + E923EFD3258645C100E3E751 /* HMG_Geofence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMG_Geofence.swift; sourceTree = ""; }; + E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HMGPlatformBridge.swift; sourceTree = ""; }; + E923EFD72588D17700E3E751 /* gpx.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = gpx.gpx; sourceTree = ""; }; + E9620803255C2ED100D3A35D /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; + E9620804255C2ED100D3A35D /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; + E9C8C135256BACDA00EFFB62 /* HMG_Guest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMG_Guest.swift; sourceTree = ""; }; + E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedFromFlutter.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 813F9CBA7DD5ED63B28B8BB6 /* Pods_Runner.framework in Frameworks */, + E9620805255C2ED100D3A35D /* NetworkExtension.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 555EAAA626EFB641859EF0BE /* Frameworks */ = { + isa = PBXGroup; + children = ( + E9620804255C2ED100D3A35D /* NetworkExtension.framework */, + 767C165F7ABF3BF1F829B9BF /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 605039E5DDF72C245F9765FE /* Pods */ = { + isa = PBXGroup; + children = ( + DCFFD369041FFFFA94CF7B26 /* Pods-Runner.debug.xcconfig */, + 969F0CEC868FD7C196987A3E /* Pods-Runner.release.xcconfig */, + 308FEC658188F7D588BE7580 /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + E923EFD72588D17700E3E751 /* gpx.gpx */, + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 605039E5DDF72C245F9765FE /* Pods */, + 555EAAA626EFB641859EF0BE /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + E91B539E256AAC1400E96549 /* GuestPOC_Certificate.cer */, + E91B539D256AAC1400E96549 /* GuestPOC_Certificate.p12 */, + E91B5390256AAA6500E96549 /* Controllers */, + E91B538C256AAA6500E96549 /* Helper */, + E91B5393256AAA6500E96549 /* WifiConnect */, + E9620803255C2ED100D3A35D /* Runner.entitlements */, + E91B53A1256AAD8200E96549 /* Main_Custom.storyboard */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + E91B538C256AAA6500E96549 /* Helper */ = { + isa = PBXGroup; + children = ( + E91B538D256AAA6500E96549 /* GlobalHelper.swift */, + E91B538E256AAA6500E96549 /* Extensions.swift */, + E91B538F256AAA6500E96549 /* API.swift */, + E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */, + E923EFD125863FDF00E3E751 /* GeoZoneModel.swift */, + E923EFD3258645C100E3E751 /* HMG_Geofence.swift */, + E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */, + ); + path = Helper; + sourceTree = ""; + }; + E91B5390256AAA6500E96549 /* Controllers */ = { + isa = PBXGroup; + children = ( + E91B5392256AAA6500E96549 /* MainFlutterVC.swift */, + ); + path = Controllers; + sourceTree = ""; + }; + E91B5393256AAA6500E96549 /* WifiConnect */ = { + isa = PBXGroup; + children = ( + E9C8C135256BACDA00EFFB62 /* HMG_Guest.swift */, + E91B5394256AAA6500E96549 /* HMG_Internet.swift */, + E91B5395256AAA6500E96549 /* HMG_GUEST_bkp.swift */, + ); + path = WifiConnect; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 299B8FE131E5BAE7FA7E2FC9 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 125A739F71A29FBAE7B4D5AC /* [CP] Embed Pods Frameworks */, + 940F4A376A48B060117A1E5D /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E91B53A0256AAC1400E96549 /* GuestPOC_Certificate.cer in Resources */, + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + E923EFD82588D17700E3E751 /* gpx.gpx in Resources */, + E91B539F256AAC1400E96549 /* GuestPOC_Certificate.p12 in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + E91B53A3256AAD8200E96549 /* Main_Custom.storyboard in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 125A739F71A29FBAE7B4D5AC /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 299B8FE131E5BAE7FA7E2FC9 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 940F4A376A48B060117A1E5D /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E923EFD225863FDF00E3E751 /* GeoZoneModel.swift in Sources */, + E91B539A256AAA6500E96549 /* MainFlutterVC.swift in Sources */, + E91B539C256AAA6500E96549 /* HMG_GUEST_bkp.swift in Sources */, + E91B5396256AAA6500E96549 /* GlobalHelper.swift in Sources */, + E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */, + E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */, + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + E9E27168256E3A4000F49B69 /* LocalizedFromFlutter.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + E9C8C136256BACDA00EFFB62 /* HMG_Guest.swift in Sources */, + E91B539B256AAA6500E96549 /* HMG_Internet.swift in Sources */, + E91B5397256AAA6500E96549 /* Extensions.swift in Sources */, + E91B5398256AAA6500E96549 /* API.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; + E91B53A1256AAD8200E96549 /* Main_Custom.storyboard */ = { + isa = PBXVariantGroup; + children = ( + E91B53A2256AAD8200E96549 /* Base */, + ); + name = Main_Custom.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = ""; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..21a3cc14 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/ios/Runner/Helper/GeoZoneModel.swift b/ios/Runner/Helper/GeoZoneModel.swift index a6e10a45..e703b64c 100644 --- a/ios/Runner/Helper/GeoZoneModel.swift +++ b/ios/Runner/Helper/GeoZoneModel.swift @@ -21,7 +21,7 @@ class GeoZoneModel{ var isCity:String? func identifier() -> String{ - return "\(geofenceId)_hmg_geozone" + return "\(geofenceId)_hmg" } func message() -> String{ diff --git a/ios/Runner/Helper/HMGPlatformBridge.swift b/ios/Runner/Helper/HMGPlatformBridge.swift index 1e8ee735..f897188c 100644 --- a/ios/Runner/Helper/HMGPlatformBridge.swift +++ b/ios/Runner/Helper/HMGPlatformBridge.swift @@ -42,6 +42,9 @@ class HMGPlatformBridge{ }else if methodCall.method == "registerHmgGeofences"{ self.registerHmgGeofences(result: result) + + }else if methodCall.method == "unRegisterHmgGeofences"{ + self.unRegisterHmgGeofences(result: result) } print("") @@ -119,10 +122,16 @@ class HMGPlatformBridge{ if let jsonString = geoFencesJsonString as? String{ let allZones = GeoZoneModel.list(from: jsonString) HMG_Geofence.shared().register(geoZones: allZones) - + result(true) }else{ } } } + + // Register Geofence + func unRegisterHmgGeofences(result: @escaping FlutterResult){ + HMG_Geofence.shared().unRegisterAll() + result(true) + } } diff --git a/ios/Runner/Helper/HMG_Geofence.swift b/ios/Runner/Helper/HMG_Geofence.swift index 20d2d1e8..fb469165 100644 --- a/ios/Runner/Helper/HMG_Geofence.swift +++ b/ios/Runner/Helper/HMG_Geofence.swift @@ -71,6 +71,12 @@ class HMG_Geofence:NSObject{ return locationManager.monitoredRegions } + func unRegisterAll(){ + for region in locationManager.monitoredRegions { + locationManager.stopMonitoring(for: region) + } + } + } // CLLocationManager Delegates @@ -149,9 +155,9 @@ extension HMG_Geofence{ } func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?){ - showNotification(title: "Notifying server..." , subtitle: forRegion.identifier, message: "") - if let userProfileJson = UserDefaults.standard.string(forKey: "user-profile"), - let userProfile = dictionary(from: userProfileJson), let patientId = userProfile["PatientID"] as? String{ + df.dateFormat = "MMM/dd/yyyy hh:mm:ss" + if let userProfileJson = UserDefaults.standard.string(forKey: "flutter.user-profile"), + let userProfile = dictionary(from: userProfileJson), let patientId = userProfile["PatientID"] as? Int{ if let idString = forRegion.identifier.split(separator: "_").first, let idInt = Int(idString){ let body:[String:Any] = [ @@ -162,27 +168,22 @@ extension HMG_Geofence{ let url = "https://hmgwebservices.com/Services/Patients.svc/REST/GeoF_InsertPatientFileInfo" httpPostRequest(urlString: url, jsonBody: body){ (status,json) in - showNotification(title: transition.name(), subtitle: forRegion.identifier, message: status ? "Success: notified to server ✔️" : "Failed to notified server ✖️") + let status_ = status ? "Notified" : "Not notified" + showNotification(title: transition.name(), subtitle: forRegion.identifier, message: status_) + + + var logs = UserDefaults.init(suiteName: "GeoFenceLog")?.dictionary(forKey: "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") + } } } } - - // func notifyServer(forRegion:GeoZoneModel, transition:Transition, location:CLLocation?){ - // flutterMethodChannel?.invokeMethod("getLogGeofenceFullUrl", arguments: nil){ fullUrlString in - // if let url = fullUrlString as? String{ - // flutterMethodChannel?.invokeMethod("getDefaultHttpParameters", arguments: nil){ params in - // if var body = params as? [String : Any]{ - // body.updateValue(forZone.geofenceId, forKey: "PointsID") - // body.updateValue(transition.rawValue, forKey: "GeoType") - // httpPostRequest(urlString: url, jsonBody: body){ (status,json) in - // showNotification(title: transition.name(), subtitle: forZone.identifier(), message: status ? "Success: sent to server ✔️" : "Failed: sent to server ✖️") - // } - // } - // } - // } - // } - // } - } diff --git a/ios/gpx.gpx b/ios/gpx.gpx index addbfa24..9cc26956 100644 --- a/ios/gpx.gpx +++ b/ios/gpx.gpx @@ -1 +1 @@ - Sverrir Sigmundarson Office Office Panorama Mall Panorama Mall Saudi Architects Crossing Saudi Architects Crossing Office Office \ No newline at end of file + Sverrir Sigmundarson Office Office Mahmoud Home Mahmoud Home Panorama Mall Panorama Mall Saudi Architects Crossing Saudi Architects Crossing Office Office \ No newline at end of file diff --git a/lib/core/service/AuthenticatedUserObject.dart b/lib/core/service/AuthenticatedUserObject.dart index f48b1179..5f992478 100644 --- a/lib/core/service/AuthenticatedUserObject.dart +++ b/lib/core/service/AuthenticatedUserObject.dart @@ -17,7 +17,7 @@ class AuthenticatedUserObject { if (userData != null) user = AuthenticatedUser.fromJson(userData); } - // var isLogin = await sharedPref.getString(LOGIN_TOKEN_ID); + // var isLogin = await sharedPref.getString(LOGIN_TOKEN_ID); this.isLogin = user != null; } diff --git a/lib/core/service/geofencing/GeofencingServices.dart b/lib/core/service/geofencing/GeofencingServices.dart index a186b4c4..e8308480 100644 --- a/lib/core/service/geofencing/GeofencingServices.dart +++ b/lib/core/service/geofencing/GeofencingServices.dart @@ -56,10 +56,10 @@ class GeofencingServices extends BaseService { } addTestingGeoZones(List zones) { - zones.add({"GEOF_ID": -1, "Description": "ZiK Home", "Latitude": "24.691136", "Longitude": "46.650116", "Radius": 100, "Type": 1}); - zones.add({"GEOF_ID": -2, "Description": "CS Office", "Latitude": "24.7087913", "Longitude": "46.6656461", "Radius": 100, "Type": 1}); - zones.add({"GEOF_ID": -3, "Description": "Mahmoud Shrouf Home", "Latitude": "24.777577", "Longitude": "46.652675", "Radius": 100, "Type": 1}); - zones.add({"GEOF_ID": -4, "Description": "Panorama Mall", "Latitude": "24.692453", "Longitude": "46.669168", "Radius": 450, "Type": 1}); - zones.add({"GEOF_ID": -5, "Description": "Saudi Architects Crossing", "Latitude": "24.698375", "Longitude": "46.668567", "Radius": 140, "Type": 1}); + // zones.add({"GEOF_ID": 12, "Description": "ZiK Home", "Latitude": "24.691136", "Longitude": "46.650116", "Radius": 100, "Type": 1}); + // zones.add({"GEOF_ID": 13, "Description": "CS Office", "Latitude": "24.7087913", "Longitude": "46.6656461", "Radius": 100, "Type": 1}); + // zones.add({"GEOF_ID": 14, "Description": "Mahmoud Shrouf Home", "Latitude": "24.777577", "Longitude": "46.652675", "Radius": 100, "Type": 1}); + // zones.add({"GEOF_ID": 14, "Description": "Panorama Mall", "Latitude": "24.692453", "Longitude": "46.669168", "Radius": 450, "Type": 1}); + // zones.add({"GEOF_ID": 16, "Description": "Saudi Architects Crossing", "Latitude": "24.698375", "Longitude": "46.668567", "Radius": 140, "Type": 1}); } } diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index 799ca86e..b8c88eca 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -50,6 +50,8 @@ class LandingPage extends StatefulWidget { } class _LandingPageState extends State with WidgetsBindingObserver { + var authProvider = new AuthProvider(); + int currentTab = 0; PageController pageController; ProjectViewModel projectViewModel; @@ -145,12 +147,17 @@ class _LandingPageState extends State with WidgetsBindingObserver { // Flip Permission Checks [Zohaib Kambrani] requestPermissions().then((results) { - if (results[Permission.locationAlways].isGranted || results[Permission.location].isGranted) { + if (results[Permission.location].isGranted) { debugPrint("Fetching GEO ZONES from HMG service..."); locator().getAllGeoZones(GeoZonesRequestModel()).then((geoZones) { - debugPrint("GEO ZONES saved to AppPreferences with key '$HMG_GEOFENCES'"); debugPrint("Finished Fetching GEO ZONES from HMG service..."); - projectViewModel.platformBridge().registerHmgGeofences(); + debugPrint("GEO ZONES saved to AppPreferences with key '$HMG_GEOFENCES'"); + authProvider.authenticatedUserObject.getUser().then((value) { + debugPrint(value.toString()); + }); + if (authProvider.authenticatedUserObject.user != null) { + projectViewModel.platformBridge().registerHmgGeofences(); + } }); } diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index 700a0d0c..28961843 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -43,11 +43,9 @@ class _Login extends State { final authService = new AuthProvider(); var sharedPref = new AppSharedPreferences(); bool isLoading = false; - AppointmentRateViewModel appointmentRateViewModel = - locator(); + AppointmentRateViewModel appointmentRateViewModel = locator(); - AuthenticatedUserObject authenticatedUserObject = - locator(); + AuthenticatedUserObject authenticatedUserObject = locator(); ProjectViewModel projectViewModel; @@ -89,25 +87,15 @@ class _Login extends State { child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - MobileNo( - onNumberChange: (value) => - {mobileNo = value, validateForm()}, - onCountryChange: (value) => countryCode = value), + MobileNo(onNumberChange: (value) => {mobileNo = value, validateForm()}, onCountryChange: (value) => countryCode = value), Container( child: TextFields( fontWeight: FontWeight.normal, controller: nationalIDorFile, onChanged: (value) => {validateForm()}, - prefixIcon: Icon( - loginType == 1 - ? Icons.chrome_reader_mode - : Icons.receipt, - color: Color(0xFF40ACC9)), - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - hintText: loginType == 1 - ? TranslationBase.of(context).nationalID - : TranslationBase.of(context).fileNo, + prefixIcon: Icon(loginType == 1 ? Icons.chrome_reader_mode : Icons.receipt, color: Color(0xFF40ACC9)), + padding: EdgeInsets.only(top: 20, bottom: 20, left: 10, right: 10), + hintText: loginType == 1 ? TranslationBase.of(context).nationalID : TranslationBase.of(context).fileNo, )) ], ), @@ -121,16 +109,16 @@ class _Login extends State { color: Colors.grey, height: 2, ), - SizedBox(height: 10,), + SizedBox( + height: 10, + ), Row( children: [ Expanded( child: DefaultButton( TranslationBase.of(context).login, () => {this.startLogin()}, - color: isButtonDisabled == true - ? Colors.grey - : Colors.grey[900], + color: isButtonDisabled == true ? Colors.grey : Colors.grey[900], textColor: Colors.white, )) ], @@ -152,8 +140,7 @@ class _Login extends State { void validateForm() { //TODO fix login - if (util.validateIDBox(nationalIDorFile.text, loginType) == - true /*&& + if (util.validateIDBox(nationalIDorFile.text, loginType) == true /*&& mobileNo.length >= 9 */ && util.isSAUDIIDValid(nationalIDorFile.text, loginType) == true) { @@ -208,15 +195,13 @@ class _Login extends State { okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () => { - ConfirmDialog.closeAlertDialog(context), + ConfirmDialog.closeAlertDialog(context), Navigator.of(context).pushNamed( REGISTER, ), - }, cancelFunction: () => {ConfirmDialog.closeAlertDialog(context)}); dialog.showAlertDialog(context); - }); // SMSOTP.showLoadingDialog(context, false), } @@ -241,10 +226,13 @@ class _Login extends State { } // request.isRegister = false; this.authService.checkActivationCode(request, code).then((result) => { + // Register GeoZones after login + registerGeoZones(), + result = CheckActivationCode.fromJson(result), - result.list.isFamily =false, - this.sharedPref.setObject(USER_PROFILE, result.list), - this.sharedPref.setObject(MAIN_USER, result.list), + result.list.isFamily = false, + this.sharedPref.setObject(USER_PROFILE, result.list), + this.sharedPref.setObject(MAIN_USER, result.list), this.sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), this.sharedPref.setString(TOKEN, result.authenticationTokenID), authenticatedUserObject.getUser(), @@ -283,6 +271,10 @@ class _Login extends State { }); } + void registerGeoZones() { + projectViewModel.platformBridge().registerHmgGeofences(); + } + // showLoader(bool isTrue) { // setState(() { // isLoading = isTrue; diff --git a/lib/uitl/PlatformBridge.dart b/lib/uitl/PlatformBridge.dart index ca410435..3ad91cdd 100644 --- a/lib/uitl/PlatformBridge.dart +++ b/lib/uitl/PlatformBridge.dart @@ -90,6 +90,7 @@ class PlatformBridge { static const enable_wifi_if_not = "enableWifiIfNot"; static const show_loading_method = "loading"; static const register_Hmg_Geofences = "registerHmgGeofences"; + static const un_register_Hmg_Geofences = "unRegisterHmgGeofences"; Future connectHMGInternetWifi(String patientId) { print("Invoking platform method: $hmg_internet_wifi_connect_method"); @@ -134,7 +135,7 @@ class PlatformBridge { void showLoading(String message, bool show) async { print("Invoking platform method: $show_loading_method"); try { - final int result = await platform.invokeMethod(show_loading_method, [message, show]); + var result = await platform.invokeMethod(show_loading_method, [message, show]); } on PlatformException catch (e) { print(e); } @@ -142,6 +143,10 @@ class PlatformBridge { // GEO Fences void registerHmgGeofences() async { - final int result = await platform.invokeMethod(register_Hmg_Geofences); + var result = await platform.invokeMethod(register_Hmg_Geofences); + } + + void unRegisterHmgGeofences() async { + var result = await platform.invokeMethod(un_register_Hmg_Geofences); } } diff --git a/lib/widgets/drawer/app_drawer_widget.dart b/lib/widgets/drawer/app_drawer_widget.dart index c8af1ccb..9c6375e4 100644 --- a/lib/widgets/drawer/app_drawer_widget.dart +++ b/lib/widgets/drawer/app_drawer_widget.dart @@ -39,8 +39,7 @@ class _AppDrawerState extends State { var familyFileProvider = FamilyFilesProvider(); AuthenticatedUser user; AuthenticatedUser mainUser; - AuthenticatedUserObject authenticatedUserObject = - locator(); + AuthenticatedUserObject authenticatedUserObject = locator(); @override Widget build(BuildContext context) { @@ -64,67 +63,45 @@ class _AppDrawerState extends State { child: Column( children: [ Container( - child: - Image.asset('assets/images/DQ/DQ_logo.png'), - margin: EdgeInsets.all( - SizeConfig.imageSizeMultiplier * 4), + child: Image.asset('assets/images/DQ/DQ_logo.png'), + margin: EdgeInsets.all(SizeConfig.imageSizeMultiplier * 4), ), (user != null && projectProvider.isLogin) ? Padding( padding: EdgeInsets.all(15), - child: Column( - mainAxisAlignment: - MainAxisAlignment.start, + child: Column(mainAxisAlignment: MainAxisAlignment.start, children: [ + Row( children: [ - Row( - children: [ - Padding( - padding: EdgeInsets.only( - right: 5), - child: Icon( - Icons.account_circle, - color: Color(0xFF40ACC9), - )), - AppText( - user.firstName + - ' ' + - user.lastName, + Padding( + padding: EdgeInsets.only(right: 5), + child: Icon( + Icons.account_circle, color: Color(0xFF40ACC9), - ) - ], - ), - Row(children: [ - Padding( - padding: EdgeInsets.only( - left: 30, top: 5), - child: Column( - children: [ - AppText( - TranslationBase.of( - context) - .fileno + - ": " + - user.patientID - .toString(), - color: - Color(0xFF40ACC9), - fontSize: SizeConfig - .textMultiplier * - 1.5, - ), - AppText( - user.bloodGroup != null - ? 'Blood Group: ' + - user.bloodGroup - : '', - fontSize: SizeConfig - .textMultiplier * - 1.5, - ), - ], - )) - ]) - ])) + )), + AppText( + user.firstName + ' ' + user.lastName, + color: Color(0xFF40ACC9), + ) + ], + ), + Row(children: [ + Padding( + padding: EdgeInsets.only(left: 30, top: 5), + child: Column( + children: [ + AppText( + TranslationBase.of(context).fileno + ": " + user.patientID.toString(), + color: Color(0xFF40ACC9), + fontSize: SizeConfig.textMultiplier * 1.5, + ), + AppText( + user.bloodGroup != null ? 'Blood Group: ' + user.bloodGroup : '', + fontSize: SizeConfig.textMultiplier * 1.5, + ), + ], + )) + ]) + ])) : SizedBox(), ], ), @@ -135,9 +112,7 @@ class _AppDrawerState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ InkWell( - child: DrawerItem( - TranslationBase.of(context).arabicChange, - Icons.translate), + child: DrawerItem(TranslationBase.of(context).arabicChange, Icons.translate), onTap: () { // Navigator.of(context).pushNamed( // WELCOME_LOGIN, @@ -170,20 +145,13 @@ class _AppDrawerState extends State { ), FutureBuilder( future: getFamilyFiles(), // async work - builder: (BuildContext context, - AsyncSnapshot< - GetAllSharedRecordsByStatusResponse> - snapshot) { + builder: (BuildContext context, AsyncSnapshot snapshot) { switch (snapshot.connectionState) { case ConnectionState.waiting: - return Padding( - padding: EdgeInsets.all(10), - child: Text('Loading....')); + return Padding(padding: EdgeInsets.all(10), child: Text('Loading....')); default: if (snapshot.hasError) - return Padding( - padding: EdgeInsets.all(10), - child: Text(snapshot.error)); + return Padding(padding: EdgeInsets.all(10), child: Text(snapshot.error)); else return Container( decoration: BoxDecoration( @@ -198,76 +166,49 @@ class _AppDrawerState extends State { children: [ user.isFamily == true ? Container( - padding: - EdgeInsets.only( - bottom: 5), + padding: EdgeInsets.only(bottom: 5), child: InkWell( onTap: () { - switchUser( - mainUser, - context); + switchUser(mainUser, context); }, child: Row( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: < - Widget>[ + crossAxisAlignment: CrossAxisAlignment.start, + children: [ Expanded( - child: Icon( - Icons - .person), + child: Icon(Icons.person), ), Expanded( flex: 7, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - AppText(mainUser.firstName + ' ' + mainUser.lastName), - AppText(TranslationBase.of(context).fileno + ": " + mainUser.patientID.toString()), - ])), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + AppText(mainUser.firstName + ' ' + mainUser.lastName), + AppText(TranslationBase.of(context).fileno + ": " + mainUser.patientID.toString()), + ])), ], ))) : SizedBox(), Column( - mainAxisAlignment: - MainAxisAlignment - .start, - mainAxisSize: - MainAxisSize.min, - children: snapshot.data - .getAllSharedRecordsByStatusList - .map( - (result) { - return result - .status == - 3 + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: snapshot.data.getAllSharedRecordsByStatusList.map((result) { + return result.status == 3 ? Container( - padding: EdgeInsets - .only( - bottom: - 5), + padding: EdgeInsets.only(bottom: 5), child: InkWell( onTap: () { - switchUser( - result, - context); + switchUser(result, context); }, child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, - children: < - Widget>[ + crossAxisAlignment: CrossAxisAlignment.start, + children: [ Expanded( - child: - Icon(Icons.person, color: result.responseID == user.patientID ? Color(0xFF40ACC9) : Colors.black), + child: Icon(Icons.person, color: result.responseID == user.patientID ? Color(0xFF40ACC9) : Colors.black), ), Expanded( flex: 7, child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText(result.patientName, color: result.responseID == user.patientID ? Color(0xFF40ACC9) : Colors.black), - AppText(TranslationBase.of(context).fileno + ": " + result.iD.toString(), color: result.responseID == user.patientID ? Color(0xFF40ACC9) : Colors.black), + AppText(TranslationBase.of(context).fileno + ": " + result.iD.toString(), + color: result.responseID == user.patientID ? Color(0xFF40ACC9) : Colors.black), ])), ], ))) @@ -279,24 +220,15 @@ class _AppDrawerState extends State { }, ), InkWell( - child: DrawerItem( - TranslationBase.of(context) - .notification, - Icons.notifications), + child: DrawerItem(TranslationBase.of(context).notification, Icons.notifications), onTap: () { //NotificationsPage Navigator.of(context).pop(); - Navigator.push( - context, - MaterialPageRoute( - builder: (BuildContext context) => - NotificationsPage())); + Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) => NotificationsPage())); }, ), InkWell( - child: DrawerItem( - TranslationBase.of(context).appsetting, - Icons.settings_input_composite), + child: DrawerItem(TranslationBase.of(context).appsetting, Icons.settings_input_composite), onTap: () { Navigator.of(context).pushNamed( SETTINGS, @@ -304,23 +236,17 @@ class _AppDrawerState extends State { }, ), InkWell( - child: DrawerItem( - TranslationBase.of(context).rateApp, - Icons.star), + child: DrawerItem(TranslationBase.of(context).rateApp, Icons.star), onTap: () { if (Platform.isIOS) { - launch( - "https://apps.apple.com/sa/app/dr-suliaman-alhabib/id733503978"); + launch("https://apps.apple.com/sa/app/dr-suliaman-alhabib/id733503978"); } else { - launch( - "https://play.google.com/store/apps/details?id=com.ejada.hmg&hl=en"); + launch("https://play.google.com/store/apps/details?id=com.ejada.hmg&hl=en"); } }, ), InkWell( - child: DrawerItem( - TranslationBase.of(context).logout, - Icons.lock_open), + child: DrawerItem(TranslationBase.of(context).logout, Icons.lock_open), onTap: () { logout(); }, @@ -328,9 +254,7 @@ class _AppDrawerState extends State { ], ) : InkWell( - child: DrawerItem( - TranslationBase.of(context).loginregister, - Icons.lock_open), + child: DrawerItem(TranslationBase.of(context).loginregister, Icons.lock_open), onTap: () { login(); }, @@ -389,11 +313,9 @@ class _AppDrawerState extends State { checkUserData() async { if (await this.sharedPref.getObject(USER_PROFILE) != null) { - var data = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(USER_PROFILE)); + var data = AuthenticatedUser.fromJson(await this.sharedPref.getObject(USER_PROFILE)); - var data2 = AuthenticatedUser.fromJson( - await this.sharedPref.getObject(MAIN_USER)); + var data2 = AuthenticatedUser.fromJson(await this.sharedPref.getObject(MAIN_USER)); print(data2); setState(() { this.user = data; @@ -409,6 +331,7 @@ class _AppDrawerState extends State { await sharedPref.clear(); this.user = null; Navigator.of(context).pushNamed(HOME); + projectProvider.platformBridge().unRegisterHmgGeofences(); } login() async { @@ -427,8 +350,7 @@ class _AppDrawerState extends State { if (user != null) { if (await sharedPref.getObject(FAMILY_FILE) != null) { // print(await sharedPref.getObject(FAMILY_FILE)); - return Future.value(GetAllSharedRecordsByStatusResponse.fromJson( - await sharedPref.getObject(FAMILY_FILE))); + return Future.value(GetAllSharedRecordsByStatusResponse.fromJson(await sharedPref.getObject(FAMILY_FILE))); } else { return familyFileProvider.getSharedRecordByStatus(); } @@ -437,17 +359,11 @@ class _AppDrawerState extends State { switchUser(user, context) { Utils.showProgressDialog(context); - this - .familyFileProvider - .silentLoggin(user is AuthenticatedUser ? null : user, - mainUser: user is AuthenticatedUser) - .then((value) => loginAfter(value, context)) - .catchError((err) { + this.familyFileProvider.silentLoggin(user is AuthenticatedUser ? null : user, mainUser: user is AuthenticatedUser).then((value) => loginAfter(value, context)).catchError((err) { print(err); AppToast.showErrorToast(message: err); Navigator.of(context).pop(); - }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }).showProgressBar(text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); } loginAfter(result, context) async {