diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/Application.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/Application.kt deleted file mode 100644 index e179bc6a..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/Application.kt +++ /dev/null @@ -1,59 +0,0 @@ -//package com.cloud.diplomaticquarterapp -package com.ejada.hmg - -import com.facebook.stetho.Stetho -import io.flutter.app.FlutterApplication -import io.flutter.plugin.common.PluginRegistry -import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback -//import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService - -class Application : FlutterApplication(), PluginRegistrantCallback { - override fun onCreate() { - super.onCreate() - // FlutterFirebaseMessagingService.setPluginRegistrant(this) - -// Stetho.initializeWithDefaults(this); - // Create an InitializerBuilder - // Create an InitializerBuilder - val initializerBuilder = Stetho.newInitializerBuilder(this) - - - // Enable Chrome DevTools - initializerBuilder.enableWebKitInspector( - Stetho.defaultInspectorModulesProvider(this) - ) - - // Enable command line interface - initializerBuilder.enableDumpapp( - Stetho.defaultDumperPluginsProvider(this) - ) - - - // Use the InitializerBuilder to generate an Initializer - val initializer = initializerBuilder.build() - - - // Initialize Stetho with the Initializer - Stetho.initialize(initializer) - } - - override fun registerWith(registry: PluginRegistry) { - // io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")); - } -} - -//import io.flutter.app.FlutterApplication -//import io.flutter.plugin.common.PluginRegistry -//import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback -//import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService -// -//class Application : FlutterApplication(), PluginRegistrantCallback { -// override fun onCreate() { -// super.onCreate() -// FlutterFirebaseMessagingService.setPluginRegistrant(this) -// } -// -// override fun registerWith(registry: PluginRegistry?) { -// FirebaseCloudMessagingPluginRegistrant.registerWith(registry) -// } -//} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/FirebaseCloudMessagingPluginRegistrant.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/FirebaseCloudMessagingPluginRegistrant.kt deleted file mode 100644 index df471796..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/FirebaseCloudMessagingPluginRegistrant.kt +++ /dev/null @@ -1,25 +0,0 @@ -//package com.cloud.diplomaticquarterapp -package com.ejada.hmg - -import io.flutter.plugin.common.PluginRegistry -//import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin - -object FirebaseCloudMessagingPluginRegistrant { - fun registerWith(registry: PluginRegistry?) { - if (alreadyRegisteredWith(registry)) { - return - } - // FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")) - } - - private fun alreadyRegisteredWith(registry: PluginRegistry?): Boolean { - val key: String? = FirebaseCloudMessagingPluginRegistrant::class.java.canonicalName - if (key?.let { registry?.hasPlugin(it) }!!) { - return true - } - if (registry != null) { - registry.registrarFor(key) - } - return false - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt deleted file mode 100644 index c874ea4d..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt +++ /dev/null @@ -1,75 +0,0 @@ -package com.ejada.hmg -import android.app.PendingIntent -import android.content.Intent -import android.content.pm.PackageManager -import android.os.Build -import android.util.Log -import android.view.WindowManager -import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi -import com.cloud.diplomaticquarterapp.PenguinInPlatformBridge -import com.cloud.diplomaticquarterapp.whatsapp.AppSignatureRetriever -import com.ejada.hmg.utils.* -import io.flutter.embedding.android.FlutterFragmentActivity -import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugins.GeneratedPluginRegistrant -import com.cloud.diplomaticquarterapp.whatsapp.WhatsApp -import com.cloud.diplomaticquarterapp.whatsapp.WhatsAppOtpPlatformBridge - - -class MainActivity: FlutterFragmentActivity() { - @RequiresApi(Build.VERSION_CODES.O) - override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { - GeneratedPluginRegistrant.registerWith(flutterEngine); - // Create Flutter Platform Bridge - this.window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) - - PlatformBridge(flutterEngine, this).create() - OpenTokPlatformBridge(flutterEngine, this).create() - PenguinInPlatformBridge(flutterEngine, this).create() - WhatsAppOtpPlatformBridge(flutterEngine, this).invoke() - AppSignatureRetriever().logSignatures(this) -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {x -// val mChannel = NotificationChannel("video_call_noti", "video call", NotificationManager.IMPORTANCE_HIGH) -// val soundUri = Uri.parse("android.resource://" + getApplicationContext() -// .getPackageName() + "/" + R.raw.alert) -// System.out.println("soundUri"); -// System.out.println("soundUri: $soundUri"); -// System.out.println("soundUri : ${soundUri.path}"); -// val att = AudioAttributes.Builder() -// .setUsage(AudioAttributes.USAGE_NOTIFICATION) -// .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) -// .build(); -// mChannel.setSound(soundUri , att) -// mChannel.description = "Video Call Notifications" -// val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager -// notificationManager.createNotificationChannel(mChannel) -// } - -// val time = timeToMillis("04:00:00", "HH:mm:ss") - - } - override fun onRequestPermissionsResult( - requestCode: Int, - permissions: Array, - grantResults: IntArray - ) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults) - - val granted = grantResults.all { it == PackageManager.PERMISSION_GRANTED } - val intent = Intent("PERMISSION_RESULT_ACTION").apply { - putExtra("PERMISSION_GRANTED", granted) - } - sendBroadcast(intent) - - // Log the request code and permission results - Log.d("PermissionsResult", "Request Code: $requestCode") - Log.d("PermissionsResult", "Permissions: ${permissions.joinToString()}") - Log.d("PermissionsResult", "Grant Results: ${grantResults.joinToString()}") - - } - - override fun onResume() { - super.onResume() - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PenguinInPlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PenguinInPlatformBridge.kt deleted file mode 100644 index 373ed06a..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PenguinInPlatformBridge.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.cloud.diplomaticquarterapp - -import com.ejada.hmg.MainActivity -import android.os.Build -import android.util.Log -import androidx.annotation.RequiresApi -import com.cloud.diplomaticquarterapp.penguin.PenguinView -import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel - -class PenguinInPlatformBridge( - private var flutterEngine: FlutterEngine, - private var mainActivity: MainActivity -) { - - private lateinit var channel: MethodChannel - - companion object { - private const val CHANNEL = "launch_penguin_ui" - } - - @RequiresApi(Build.VERSION_CODES.O) - fun create() { -// openTok = OpenTok(mainActivity, flutterEngine) - channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) - channel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -> - when (call.method) { - "launchPenguin" -> { - print("the platform channel is being called") - val args = call.arguments as Map? - Log.d("TAG", "configureFlutterEngine: $args") - println("args") - args?.let { - PenguinView( - mainActivity, - 100, - args, - flutterEngine.dartExecutor.binaryMessenger, - activity = mainActivity, - channel - ) - } - } - - else -> { - result.notImplemented() - } - } - } - } - -} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionHelper.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionHelper.kt deleted file mode 100644 index b308af05..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionHelper.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.cloud.diplomaticquarterapp.PermissionManager - -import android.Manifest -import android.os.Build - -object PermissionHelper { - - fun getRequiredPermissions(): Array { - val permissions = mutableListOf( - Manifest.permission.INTERNET, - Manifest.permission.ACCESS_FINE_LOCATION, - Manifest.permission.ACCESS_COARSE_LOCATION, - Manifest.permission.ACCESS_NETWORK_STATE, - Manifest.permission.BLUETOOTH, - Manifest.permission.BLUETOOTH_ADMIN, -// Manifest.permission.ACTIVITY_RECOGNITION - ) - - // For Android 12 (API level 31) and above, add specific permissions - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // Android 12 (API 31) and above - permissions.add(Manifest.permission.BLUETOOTH_SCAN) - permissions.add(Manifest.permission.BLUETOOTH_CONNECT) - permissions.add(Manifest.permission.HIGH_SAMPLING_RATE_SENSORS) - } - - return permissions.toTypedArray() - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionManager.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionManager.kt deleted file mode 100644 index 81f2a6f0..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionManager.kt +++ /dev/null @@ -1,50 +0,0 @@ -package com.cloud.diplomaticquarterapp.PermissionManager - -import android.app.Activity -import android.content.Context -import android.content.pm.PackageManager -import android.os.Build -import androidx.core.app.ActivityCompat -import androidx.core.content.ContextCompat - -class PermissionManager( - private val context: Context, - val listener: PermissionListener, - private val requestCode: Int, - vararg permissions: String -) { - - private val permissionsArray = permissions - - interface PermissionListener { - fun onPermissionGranted() - fun onPermissionDenied() - } - - fun arePermissionsGranted(): Boolean { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - permissionsArray.all { - ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED - } - } else { - true - } - } - - fun requestPermissions(activity: Activity) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - ActivityCompat.requestPermissions(activity, permissionsArray, requestCode) - } - } - - fun handlePermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { - if (this.requestCode == requestCode) { - val allGranted = grantResults.all { it == PackageManager.PERMISSION_GRANTED } - if (allGranted) { - listener.onPermissionGranted() - } else { - listener.onPermissionDenied() - } - } - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionResultReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionResultReceiver.kt deleted file mode 100644 index 33765192..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/PermissionManager/PermissionResultReceiver.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.cloud.diplomaticquarterapp.PermissionManager - -// PermissionResultReceiver.kt -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent - -class PermissionResultReceiver( - private val callback: (Boolean) -> Unit -) : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - val granted = intent?.getBooleanExtra("PERMISSION_GRANTED", false) ?: false - callback(granted) - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/bkp_files/CustomFlutterHmsMessageService.java b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/bkp_files/CustomFlutterHmsMessageService.java deleted file mode 100644 index c96a60af..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/bkp_files/CustomFlutterHmsMessageService.java +++ /dev/null @@ -1,56 +0,0 @@ -/* -* --------------- -* Note: Todo -* --------------- -* Need to be place in huawei_push (package com.huawei.hms.flutter.push.hms) and define in huawei_push manifest.xml -* */ - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.util.Log; - -import com.huawei.hms.flutter.push.hms.FlutterHmsMessageService; -import com.huawei.hms.flutter.push.utils.ApplicationUtils; - -import org.json.JSONObject; - -//package com.huawei.hms.flutter.push.hms -// -// -//import android.content.Context; -//import android.content.Intent; -//import android.content.SharedPreferences; -// -//import com.huawei.hms.flutter.push.hms.FlutterHmsMessageService; -//import com.huawei.hms.flutter.push.utils.ApplicationUtils; -//import com.huawei.hms.push.RemoteMessage; -// -//import org.json.JSONObject; -// -//public class CustomFlutterHmsMessageService extends FlutterHmsMessageService { -// @Override -// public void onMessageReceived(RemoteMessage remoteMessage) { -// super.onMessageReceived(remoteMessage); -// try { -// String jsonStr = remoteMessage.getData(); -// JSONObject json_data = new JSONObject(jsonStr); -// JSONObject json_data_data = new JSONObject(json_data.getString("data")); -// if(json_data_data.getString("is_call").equalsIgnoreCase("true")){ -// boolean isApplicationInForeground = ApplicationUtils.isApplicationInForeground(this); -// if(!isApplicationInForeground){ -// SharedPreferences preferences = getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE); -// preferences.edit().putString("flutter.call_data", json_data.getString("data")).apply(); -// -// Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName()); -// intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); -// startActivity(intent); -// Log.v("onMessageReceived", "startActivity(intent) called"); -// } -// } -// -// } catch (Exception e) { -// e.printStackTrace(); -// } -// } -//} 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 deleted file mode 100644 index 16ed0939..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt +++ /dev/null @@ -1,58 +0,0 @@ -package com.ejada.hmg.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){ - - val loiteringDelayMinutes:Int = 2 // in Minutes - return Geofence.Builder() - .setRequestId(identifier()) - .setCircularRegion( - lat, - long, - rad - ) - .setTransitionTypes(GeofenceTransition.ENTER_EXIT.value) - .setNotificationResponsiveness(0) - .setLoiteringDelay(loiteringDelayMinutes * 60 * 1000) - .setExpirationDuration(Geofence.NEVER_EXPIRE) - .build() - } - } - return null - } - -} 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 deleted file mode 100644 index 8452a083..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt +++ /dev/null @@ -1,291 +0,0 @@ -package com.ejada.hmg.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 android.location.Location -import androidx.core.content.ContextCompat -import com.ejada.hmg.geofence.intent_receivers.GeofenceBroadcastReceiver -import com.ejada.hmg.geofence.intent_receivers.ReregisterGeofenceJobService -import com.ejada.hmg.utils.* -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), - DWELL(4), - - ENTER_EXIT((ENTER.value or EXIT.value)), - DWELL_EXIT((DWELL.value or EXIT.value)); - - 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 == 4) return "dWell" - if (value == (ENTER.value or EXIT.value)) return "Enter or Exit" - if (value == (DWELL.value or EXIT.value)) return "DWell or Exit" - return "unknown" - } -} - -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_IMMUTABLE - ) - } - - 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!! - } - } - - private fun limitize(zones: List): List { - var geoZones_ = zones - if (zones.size > 100) - geoZones_ = zones.subList(0, 99) - return geoZones_ - } - - - fun register(completion: ((Boolean, java.lang.Exception?) -> Unit)) { - unRegisterAll { status, exception -> - val geoZones = getGeoZonesFromPreference(context) - doRegister(geoZones) { status_, error -> - completion.let { it(status_, error) } - } - } - } - - fun unRegisterAll(completion: (status: Boolean, exception: Exception?) -> Unit) { - getActiveGeofences({ success -> - removeActiveGeofences() - if (success.isNotEmpty()) - geofencingClient - .removeGeofences(success) - .addOnSuccessListener { - completion(true, null) - } - .addOnFailureListener { - completion(false, it) - saveLog(context, "error:REMOVE_GEOFENCES", it.localizedMessage) - } - else - completion(true, null) - - }, { failed -> - // Nothing to do with failed geofences. - }) - } - - private fun doRegister( - geoZones: List, - completion: ((Boolean, java.lang.Exception?) -> Unit)? = null - ) { - if (geoZones.isEmpty()) - return - - val geoZones_ = limitize(geoZones) - - fun buildGeofencingRequest(geofences: List): GeofencingRequest { - return GeofencingRequest.Builder() - .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL) - .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 { - Logs.RegisterGeofence.save( - context, - "SUCCESS", - "Successfuly registered the geofences", - Logs.STATUS.SUCCESS - ) - saveActiveGeofence(geofences.map { it.requestId }, listOf()) - completion?.let { it(true, null) } - } - .addOnFailureListener { exc -> - Logs.RegisterGeofence.save( - context, - "FAILED_TO_REGISTER", - "Failed to register geofence", - Logs.STATUS.ERROR - ) - completion?.let { it(false, exc) } - } - - // Schedule the job to register after specified duration (due to: events not calling after long period.. days or days [Needs to register fences again]) - HMGUtils.scheduleJob( - context, - ReregisterGeofenceJobService::class.java, - ReregisterGeofenceJobService.JobID, - ReregisterGeofenceJobService.TriggerIntervalDuration - ) - } - - }, null) - - } - - fun getGeoZonesFromPreference(context: Context): List { - val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - val json = pref.getString(PREF_KEY_HMG_ZONES, "[]") - - val geoZones = GeoZoneModel().listFrom(json!!) - return geoZones - } - - fun saveActiveGeofence(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 removeActiveGeofences() { - preferences.edit().putString(PREF_KEY_SUCCESS, "[]").apply() - preferences.edit().putString(PREF_KEY_FAILED, "[]").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? { - var profileJson = preferences.getString("flutter.imei-user-data", null) - if (profileJson == null) - profileJson = preferences.getString("flutter.user-profile", null) - - val type = object : TypeToken?>() {}.type - return gson.fromJson?>(profileJson, type) - ?.get("PatientID") - .toString() - .toDoubleOrNull() - ?.toInt() - } - - - fun handleEvent( - triggerGeofences: List, - 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( - "PointsID" to pointID.toIntOrNull(), - "GeoType" to transition.value, - "PatientID" to patientId - ) - body.putAll(HMGUtils.defaultHTTPParams(context)) - - httpPost>(API.LOG_GEOFENCE, body, { response -> - saveLog( - context, - "HMG_GEOFENCE_NOTIFY", - "Success: Notified to server\uD83D\uDE0E." - ) - sendNotification( - context, - transition.named(), - geofence.requestId, - "Notified to server.😎" - ) - }, { exception -> - val errorMessage = "${transition.named()}, ${geofence.requestId}" - saveLog( - context, - "HMG_GEOFENCE_NOTIFY", - "failed: $errorMessage | error: ${exception.localizedMessage}" - ) - sendNotification( - context, - transition.named(), - geofence.requestId, - "Failed to notify server😔 -> ${exception.localizedMessage}" - ) - }) - - } - } - - }, null) - } - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt deleted file mode 100644 index 2ed2daf4..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt +++ /dev/null @@ -1,71 +0,0 @@ -package com.ejada.hmg.geofence.intent_receivers - -import android.annotation.SuppressLint -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.util.Log -import com.ejada.hmg.geofence.GeofenceTransition -import com.ejada.hmg.geofence.HMG_Geofence -import com.ejada.hmg.utils.Logs -import com.google.android.gms.location.GeofenceStatusCodes -import com.google.android.gms.location.GeofencingEvent - -class GeofenceBroadcastReceiver : BroadcastReceiver() { - private val LOG_TAG = "GeofenceBroadcastReceiver" - - @SuppressLint("LongLogTag") - override fun onReceive(context: Context, intent: Intent) { - - val geofencingEvent = GeofencingEvent.fromIntent(intent) - if (geofencingEvent != null) { - if (geofencingEvent.hasError()) { - val errorMessage = - GeofenceErrorMessages.getErrorString(context, geofencingEvent.errorCode) - Log.e(LOG_TAG, errorMessage) - - Logs.GeofenceEvent.save( - context, - LOG_TAG, - "Error while triggering geofence event", - Logs.STATUS.ERROR - ) - doReRegisterIfRequired(context, geofencingEvent.errorCode) - - return - } - } - if (geofencingEvent != null) { - Logs.GeofenceEvent.save( - context, - LOG_TAG, - "Geofence event triggered: ${GeofenceTransition.fromInt(geofencingEvent.geofenceTransition).value} for ${geofencingEvent.triggeringGeofences?.map { it.requestId }}", - Logs.STATUS.SUCCESS - ) - geofencingEvent.triggeringLocation?.let { - geofencingEvent.triggeringGeofences?.let { it1 -> - HMG_Geofence.shared(context).handleEvent( - it1, - it, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition) - ) - } - } - }; - - } - - fun doReRegisterIfRequired(context: Context, errorCode: Int) { - val errorRequiredReregister = listOf( - GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE, - GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES, - GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS, - GeofenceStatusCodes.GEOFENCE_REQUEST_TOO_FREQUENT - ) - - if (errorRequiredReregister.contains(errorCode)) - HMG_Geofence.shared(context).register() { status, error -> - - } - - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt deleted file mode 100644 index 4e4f19ff..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt +++ /dev/null @@ -1,16 +0,0 @@ - - -package com.ejada.hmg.geofence.intent_receivers - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import com.ejada.hmg.geofence.HMG_Geofence -import com.google.android.gms.location.GeofenceStatusCodes - -class GeofenceBroadcastReceiverWithJobService : 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/intent_receivers/GeofenceErrorMessages.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt deleted file mode 100644 index 94ceaa3d..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt +++ /dev/null @@ -1,43 +0,0 @@ - - -package com.ejada.hmg.geofence.intent_receivers - -import android.content.Context -import com.ejada.hmg.R -import com.ejada.hmg.geofence.HMG_Geofence -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 - val errorMessage = 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) - - GeofenceStatusCodes.GEOFENCE_INSUFFICIENT_LOCATION_PERMISSION -> - resources.getString(R.string.GEOFENCE_INSUFFICIENT_LOCATION_PERMISSION) - - GeofenceStatusCodes.GEOFENCE_REQUEST_TOO_FREQUENT -> - resources.getString(R.string.GEOFENCE_REQUEST_TOO_FREQUENT) - - else -> resources.getString(R.string.geofence_unknown_error) - } - - return errorMessage - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt deleted file mode 100644 index b083e04e..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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.ejada.hmg.geofence.intent_receivers - -import android.content.Context -import android.content.Intent -import android.util.Log -import androidx.core.app.JobIntentService -import com.ejada.hmg.geofence.GeofenceTransition -import com.ejada.hmg.geofence.HMG_Geofence -import com.ejada.hmg.utils.saveLog -import com.google.android.gms.location.GeofenceStatusCodes -import com.google.android.gms.location.GeofencingEvent - -class GeofenceTransitionsJobIntentService : JobIntentService() { - - companion object { - private const val LOG_TAG = "GeoTrIntentService" - - private const val JOB_ID = 95902 - var context_: Context? = null - fun enqueueWork(context: Context, intent: Intent) { - context_ = context - enqueueWork( - context, - GeofenceTransitionsJobIntentService::class.java, JOB_ID, - intent) - } - } - - override fun onHandleWork(intent: Intent) { - val geofencingEvent = GeofencingEvent.fromIntent(intent) - if (geofencingEvent != null) { - if (geofencingEvent.hasError()) { - val errorMessage = GeofenceErrorMessages.getErrorString(context_!!, geofencingEvent.errorCode) - Log.e(LOG_TAG, errorMessage) - - - saveLog(context_!!,LOG_TAG,errorMessage) - doReRegisterIfRequired(context_!!, geofencingEvent.errorCode) - - return - } - } - - if (geofencingEvent != null) { - geofencingEvent.triggeringGeofences?.let { geofencingEvent.triggeringLocation?.let { it1 -> - HMG_Geofence.shared(context_!!).handleEvent(it, - it1, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)) - } } - }; - - } - - - fun doReRegisterIfRequired(context: Context, errorCode: Int){ - val errorRequiredReregister = listOf( - GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE, - GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES, - GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS, - GeofenceStatusCodes.GEOFENCE_REQUEST_TOO_FREQUENT - ) - - if(errorRequiredReregister.contains(errorCode)) - HMG_Geofence.shared(context).register(){ status, exc -> } - - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt deleted file mode 100644 index 809f92bc..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt +++ /dev/null @@ -1,23 +0,0 @@ - - -package com.ejada.hmg.geofence.intent_receivers - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import com.ejada.hmg.geofence.HMG_Geofence -import com.ejada.hmg.utils.PREFS_STORAGE - -class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ - override fun onReceive(context: Context, intent: Intent) { - - 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() - - HMG_Geofence.shared(context).register(){ status, error -> } - } - } - -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt deleted file mode 100644 index 8c34dedb..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt +++ /dev/null @@ -1,25 +0,0 @@ - - -package com.ejada.hmg.geofence.intent_receivers - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.location.LocationManager -import com.ejada.hmg.geofence.HMG_Geofence -import com.ejada.hmg.utils.HMGUtils -import com.ejada.hmg.utils.PREFS_STORAGE - -class LocationProviderChangeReceiver : BroadcastReceiver() { - private val LOG_TAG = "LocationProviderChangeReceiver" - override fun onReceive(context: Context, intent: Intent) { - - if (LocationManager.PROVIDERS_CHANGED_ACTION.equals(intent.action)) { - val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - pref.edit().putString("LOCATION_PROVIDER_CHANGE","YES").apply() - - HMG_Geofence.shared(context).register(){ s, e -> } - } - } - -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt deleted file mode 100644 index e7c0a82d..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.ejada.hmg.geofence.intent_receivers - -import android.app.job.JobParameters -import android.app.job.JobService -import com.ejada.hmg.geofence.HMG_Geofence -import com.ejada.hmg.utils.Logs - -class ReregisterGeofenceJobService : JobService(){ - companion object{ - val TriggerIntervalDuration:String = "06:00:00" - val JobID = 918273 - } - override fun onStartJob(params: JobParameters?): Boolean { - Logs.save(applicationContext,"ReregisterGeofenceJobService.onStartJob", "triggered to re-register the geofences after $TriggerIntervalDuration >> [HH:mm:ss]") - HMG_Geofence.shared(applicationContext).register(){ status, error -> - jobFinished(params, true) - } - return true - } - - override fun onStopJob(params: JobParameters?): Boolean { - return true - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt deleted file mode 100644 index 7b3cc2d1..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt +++ /dev/null @@ -1,257 +0,0 @@ -package com.ejada.hmg.hmgwifi - -import android.annotation.SuppressLint -import android.content.Context -import android.content.Intent -import android.net.* -import android.net.wifi.* -import android.os.Build -import android.os.PatternMatcher -import android.provider.Settings -import android.util.Log -import androidx.annotation.RequiresApi -import com.ejada.hmg.MainActivity -import com.ejada.hmg.utils.HMGUtils - - - - - -class HMG_Guest(private var context: MainActivity, ssid: String) { - private val TAG = "HMG_Guest" - private val TEST = false - private var SSID = ssid -// private var SSID = "HMG-MOHEMM" - - val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager? - - private lateinit var completionListener: ((status: Boolean, message: String) -> Unit) - - fun completionOnUiThread(status: Boolean, message: String){ - completionListener(status, message) - } - - fun enableWifi(){ - if(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q){ - wifiManager?.setWifiEnabled(true) - HMGUtils.popFlutterText(context,"enablingWifi"); - HMGUtils.timer(2000,false){ - connectApiLessThen29() - } - }else { - val panelIntent = Intent(Settings.Panel.ACTION_WIFI) - context.startActivityForResult(panelIntent, 1) - } - } - /* - * Helpful: - * http://stackoverflow.com/questions/8818290/how-to-connect-to-a-specific-wifi-network-in-android-programmatically - */ - fun connectToHMGGuestNetwork(completion: (status: Boolean, message: String) -> Unit) { - completionListener = completion - wifiManager?.let { wm -> - if (!wm.isWifiEnabled){ - enableWifi() - }else{ - connectWifi() - } - } - - } - - private fun errorConnecting(){ - completionOnUiThread(false, "errorConnectingHmgNetwork") - } - - fun connectWifi(){ - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){ - connectApiGreaterThen28() - }else { - connectApiLessThen29() - } - } - - // I }else{f CompileSDK is greater and equals to APILevel 29 - @RequiresApi(Build.VERSION_CODES.Q) - private fun connectApiGreaterThen28(){ - Log.e(TAG, "connection wifi with Android Q+") - - val networkRequest: NetworkRequest = NetworkRequest.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) - .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) //removeCapability added for hotspots without internet - .setNetworkSpecifier( - WifiNetworkSpecifier.Builder() - .setSsid(SSID) - .build() - - ).build() - - val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - val networkCallback = object : ConnectivityManager.NetworkCallback() { - override fun onAvailable(network: Network) { - super.onAvailable(network) - connectivityManager.bindProcessToNetwork(network) - HMGUtils.timer(2000,false){ - completionListener(true, "Success") - } - Log.e(TAG, "onAvailable") - } - - override fun onLosing(network: Network, maxMsToLive: Int) { - super.onLosing(network, maxMsToLive) - Log.e(TAG, "onLosing") - completionListener(false, "fail") - } - - override fun onLost(network: Network) { - super.onLost(network) - Log.e(TAG, "onLosing") - Log.e(TAG, "losing active connection") - completionListener(false, "fail") - } - - override fun onUnavailable() { - super.onUnavailable() - Log.e(TAG, "onUnavailable") - completionListener(false, "fail") - } - - } - - //timeout add because "No devices found" wasn't handled correct and doesn't throw Unavailable - connectivityManager.requestNetwork(networkRequest, networkCallback, 30000) - } - - - - fun connectApiLessThen29(){ - val wifi = WifiConfiguration() - wifi.SSID = """"$SSID"""" - wifi.status = WifiConfiguration.Status.ENABLED - wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE) - - wifi.networkId = ssidToNetworkId(wifi.SSID) - if (wifi.networkId == -1) { - wifiManager?.addNetwork(wifi) - } else { - Log.v(TAG, "WiFi found - updating it.\n") - wifiManager?.updateNetwork(wifi) - } - - Log.v(TAG, "saving config.\n") - wifiManager?.saveConfiguration() - - wifi.networkId = ssidToNetworkId(wifi.SSID) - - Log.v(TAG, "wifi ID in device = " + wifi.networkId) - - var supState: SupplicantState - val networkIdToConnect = wifi.networkId - if (networkIdToConnect >= 0) { - Log.v(TAG, "Start connecting...\n") - - // We disable the network before connecting, because if this was the last connection before - // a disconnect(), this will not reconnect. - wifiManager?.disableNetwork(networkIdToConnect) - wifiManager?.enableNetwork(networkIdToConnect, true) - - val wifiInfo: WifiInfo = wifiManager!!.connectionInfo - - HMGUtils.timer(5000,false){ - supState = wifiInfo.supplicantState - Log.i(TAG, "Done connect to network : status = $supState") - val successStates = listOf(SupplicantState.COMPLETED, SupplicantState.ASSOCIATED) - if (successStates.contains(supState)) - completionListener(true,"Connected to internet Wifi") - else - completionListener(false,"errorConnectingHmgNetwork") - } - - } else { - Log.v(TAG, "WifiWizard: cannot connect to network") - completionListener(false,"errorConnectingHmgNetwork") - } - -// val wifi = WifiConfiguration() -// wifi.SSID = SSID -// wifi.status = WifiConfiguration.Status.ENABLED -// wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); -// -// wifi.networkId = ssidToNetworkId(SSID) -// -// // Set network to highest priority (deprecated in API >= 26) -// if(Build.VERSION.SDK_INT < 26) { -// wifi.priority = getMaxWifiPriority(wifiManager!!) + 1; -// } -// -// // After processing authentication types, add or update network -// if(wifi.networkId == -1) { // -1 means SSID configuration does not exist yet -// -// val newNetId = wifiManager?.addNetwork(wifi)!! -// if( newNetId > -1 ){ -// completionListener(true,"Success") -// } else { -// completionListener(false, "ERROR_ADDING_NETWORK" ) -// } -// -// } else { -// -// var updatedNetID = wifiManager?.updateNetwork(wifi) -// -// if(updatedNetID == -1) -// updatedNetID = wifiManager?.addNetwork(wifi) -// -// if(updatedNetID > -1) { -// callbackContext.success( updatedNetID ) -// } else { -// callbackContext.error("ERROR_UPDATING_NETWORK") -// } -// -// } -// -// // WifiManager configurations are presistent for API 26+ -// if(Build.VERSION.SDK_INT < 26) { -// wifiManager?.saveConfiguration(); // Call saveConfiguration for older < 26 API -// } - } - - - /** - * This method takes a given String, searches the current list of configured WiFi - * networks, and returns the networkId for the network if the SSID matches. If not, - * it returns -1. - */ - @SuppressLint("MissingPermission") - private fun ssidToNetworkId(ssid: String): Int { - val currentNetworks = wifiManager!!.configuredNetworks - var networkId = -1 - - // For each network in the list, compare the SSID with the given one - for (test in currentNetworks) { - if (test.SSID == ssid) { - networkId = test.networkId - break - } - } - return networkId - } - - companion object{ - - /** - * Figure out what the highest priority network in the network list is and return that priority - */ - @RequiresApi(Build.VERSION_CODES.S) - fun getMaxWifiPriority(wifiManager:WifiManager) : Int { - val configurations = wifiManager.callerConfiguredNetworks - var maxPriority = 0 - configurations.forEach { - if (it.priority > maxPriority) { - maxPriority = it.priority; - } - } - return maxPriority; - } - } -} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt deleted file mode 100644 index dcfa5488..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt +++ /dev/null @@ -1,120 +0,0 @@ -package com.ejada.hmg.hmgwifi - -import android.annotation.SuppressLint -import com.ejada.hmg.utils.API -import com.ejada.hmg.MainActivity -import com.github.kittinunf.fuel.core.extensions.jsonBody -import com.github.kittinunf.fuel.httpGet -import com.github.kittinunf.fuel.httpPost -import org.json.JSONObject -import java.util.* - - -@SuppressLint("MissingPermission") -class HMG_Internet(flutterMainActivity: MainActivity) { - private val TAG = "HMG_Wifi" - private val TEST = true - - private var context = flutterMainActivity; - - private lateinit var completionListener: ((status: Boolean, message: String) -> Unit) - - private var SSID = "GUEST-POC" - - fun completionOnUiThread(status: Boolean, message: String){ - completionListener(status, message) -// context.runOnUiThread { -// .with(message){localized -> -// completionListener(status, localized) -// } -// } - } - - /* - * Helpful: - * http://stackoverflow.com/questions/8818290/how-to-connect-to-a-specific-wifi-network-in-android-programmatically - */ - fun connectToHMGGuestNetwork(username: String, password: String, completion: (status: Boolean, message: String) -> Unit): HMG_Internet { - completionListener = completion - WpaEnterprise(context,SSID).connect(username,username) { status, message -> - completionOnUiThread(status,message) - } - return this - } - - private fun haveInternet(completion: ((status: Boolean) -> Unit)){ - if (TEST) - completion(true) - - "https://captive.apple.com".httpGet().response { request, response, result -> - result.fold(success = { - val html = String(it).toLowerCase(Locale.ENGLISH) - .replace(" ", "", true) - .replace("\n","",true) - val have = html.contains("success", true) - completion(have) - - },failure = { - completion(false) - }) - } - } - - private fun getWifiCredentials(patientId:String, success: ((String?,String?) -> Unit)){ - if (TEST){ - SSID = "GUEST-POC" - success("2300", "0000") - return - } - - val jsonBody = """{ - "PatientID":$patientId - "VersionID": 8.8, - "Channel": 3, - "LanguageID": 2, - "IPAdress": "10.20.10.20", - "generalid": "Cs2020@2016$2958", - "PatientOutSA": 0, - "SessionID": "@admin", - "isDentalAllowedBackend": false, - "DeviceTypeID": 2, - "TokenID": "@admin", - "PatientTypeID": 1, - "PatientType": 1 - }""".trimMargin() - API.WIFI_CREDENTIALS. - httpPost() - .jsonBody(jsonBody, Charsets.UTF_8) - .response { request, response, result -> - - result.fold(success = { data -> - val jsonString = String(data) - val jsonObject = JSONObject(jsonString) - if(!jsonObject.getString("ErrorMessage").equals("null")){ - val errorMsg = jsonObject.getString("ErrorMessage") - completionOnUiThread(false, errorMsg) - - }else{ - jsonObject.getJSONArray("Hmg_SMS_Get_By_ProjectID_And_PatientIDList").let { array -> - array.getJSONObject(0).let { object_ -> - if (object_.has("UserName") && object_.has("UserName")){ - try { - val userName = object_.getString("UserName") - val password = object_.getString("Password") - success(userName, password) - }catch (e:Exception){ - success(null, null) - } - }else{ - completionOnUiThread(false, "somethingWentWrong") - } - } - } - } - - },failure = { error -> - completionOnUiThread(false, "somethingWentWrong" ) - }) - } - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WPA.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WPA.kt deleted file mode 100644 index 61cc4f9f..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WPA.kt +++ /dev/null @@ -1,105 +0,0 @@ -package com.ejada.hmg.hmgwifi - -import android.annotation.SuppressLint -import android.content.Context -import android.net.ConnectivityManager -import android.net.wifi.* -import android.net.wifi.SupplicantState.ASSOCIATED -import android.net.wifi.SupplicantState.COMPLETED -import android.util.Log -import com.ejada.hmg.MainActivity -import com.ejada.hmg.utils.HMGUtils - -class WPA(mainActivity: MainActivity, SSID:String) { - private var TAG = "WPA" - private var SSID = "GUEST-POC" - private var wifiManager_: WifiManager? = null - private var connectivityManager_: ConnectivityManager? = null - - init { - wifiManager_ = mainActivity.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager? - connectivityManager_ = mainActivity.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager? - } - - fun connect(identity:String, password:String, completion: (status: Boolean, message: String) -> Unit) { - if(wifiManager_ == null || connectivityManager_ == null){ - completion(false,"errorConnectingHmgNetwork") - return - } - - val wifiManager = wifiManager_!! - val connectivityManager = connectivityManager_!! - - // Initialize the WifiConfiguration object - val enterpriseConfig = WifiEnterpriseConfig() - val wifi = WifiConfiguration() - wifi.SSID = """"$SSID"""" - wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP) - wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X) - enterpriseConfig.eapMethod = WifiEnterpriseConfig.Eap.PEAP - enterpriseConfig.identity = identity - enterpriseConfig.password = password - wifi.enterpriseConfig = enterpriseConfig - wifi.networkId = ssidToNetworkId(wifi.SSID) - if (wifi.networkId == -1) { - wifiManager.addNetwork(wifi) - } else { - Log.v(TAG, "WiFi found - updating it.\n") - wifiManager.updateNetwork(wifi) - } - Log.v(TAG, "saving config.\n") - wifiManager.saveConfiguration() - wifi.networkId = ssidToNetworkId(wifi.SSID) - - Log.v(TAG, "wifi ID in device = " + wifi.networkId) - - var supState: SupplicantState - val networkIdToConnect = wifi.networkId - if (networkIdToConnect >= 0) { - Log.v(TAG, "Start connecting...\n") - - // We disable the network before connecting, because if this was the last connection before - // a disconnect(), this will not reconnect. - wifiManager.disableNetwork(networkIdToConnect) - wifiManager.enableNetwork(networkIdToConnect, true) - - val wifiInfo: WifiInfo = wifiManager.connectionInfo - - HMGUtils.timer(5000,false){ - supState = wifiInfo.supplicantState - Log.i(TAG, "WifiWizard: Done connect to network : status = $supState") - val successStates = listOf(COMPLETED, ASSOCIATED) - if (successStates.contains(COMPLETED /*supState*/)) - - completion(true,"Connected to internet Wifi") - - else - completion(false,"errorConnectingHmgNetwork") - } - - } else { - Log.v(TAG, "WifiWizard: cannot connect to network") - completion(false,"errorConnectingHmgNetwork") - } - } - - /** - * This method takes a given String, searches the current list of configured WiFi - * networks, and returns the networkId for the network if the SSID matches. If not, - * it returns -1. - */ - @SuppressLint("MissingPermission") - private fun ssidToNetworkId(ssid: String): Int { - val currentNetworks = wifiManager_!!.configuredNetworks - var networkId = -1 - - // For each network in the list, compare the SSID with the given one - for (test in currentNetworks) { - if (test.SSID == ssid) { - networkId = test.networkId - break - } - } - return networkId - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt deleted file mode 100644 index e8e39344..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt +++ /dev/null @@ -1,166 +0,0 @@ -package com.ejada.hmg.hmgwifi - -import android.annotation.SuppressLint -import android.content.Context -import android.net.ConnectivityManager -import android.net.Network -import android.net.NetworkCapabilities -import android.net.NetworkRequest -import android.net.wifi.* -import android.net.wifi.SupplicantState.ASSOCIATED -import android.net.wifi.SupplicantState.COMPLETED -import android.os.Build -import android.util.Log -import androidx.annotation.RequiresApi -import com.ejada.hmg.MainActivity -import com.ejada.hmg.utils.HMGUtils -import java.security.cert.X509Certificate - -class WpaEnterprise(private val mainActivity: MainActivity, private var SSID: String) { - private var TAG = "WpaEnterprise" - - private lateinit var identity:String - private lateinit var password:String - private lateinit var completion:((status: Boolean, message: String) -> Unit) - - fun connect(identity:String, password:String, completion: (status: Boolean, message: String) -> Unit) { - this.password = password - this.identity = identity - this.completion = completion - - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){ - apiGreaterThen28() - }else if(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q){ - apiLessThen29() - } - } - - @RequiresApi(Build.VERSION_CODES.LOLLIPOP) - fun apiLessThen29(){ - val wifiManager = mainActivity.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager - - val wifi = WifiConfiguration() - wifi.SSID = """"$SSID"""" - wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP) - wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X) - wifi.enterpriseConfig = enterpriseConfig() - wifi.networkId = ssidToNetworkId(wifi.SSID, wifiManager) - if (wifi.networkId == -1) { - wifiManager.addNetwork(wifi) - } else { - Log.v(TAG, "WiFi found - updating it.\n") - wifiManager.updateNetwork(wifi) - } - Log.v(TAG, "saving config.\n") - wifiManager.saveConfiguration() - wifi.networkId = ssidToNetworkId(wifi.SSID, wifiManager) - - Log.v(TAG, "wifi ID in device = " + wifi.networkId) - - var supState: SupplicantState - val networkIdToConnect = wifi.networkId - if (networkIdToConnect >= 0) { - Log.v(TAG, "Start connecting...\n") - - // We disable the network before connecting, because if this was the last connection before - // a disconnect(), this will not reconnect. - wifiManager.disableNetwork(networkIdToConnect) - wifiManager.enableNetwork(networkIdToConnect, true) - - val wifiInfo: WifiInfo = wifiManager.connectionInfo - - HMGUtils.timer(5000,false){ - supState = wifiInfo.supplicantState - Log.i(TAG, "Done connect to network : status = $supState") - val successStates = listOf(COMPLETED, ASSOCIATED) - if (successStates.contains(supState)) - completion(true,"Connected to internet Wifi") - else - completion(false,"errorConnectingHmgNetwork") - } - - } else { - Log.v(TAG, "WifiWizard: cannot connect to network") - completion(false,"errorConnectingHmgNetwork") - } - } - - /** - * This method takes a given String, searches the current list of configured WiFi - * networks, and returns the networkId for the network if the SSID matches. If not, - * it returns -1. - */ - @SuppressLint("MissingPermission") - private fun ssidToNetworkId(ssid: String, wifiManager: WifiManager): Int { - val currentNetworks = wifiManager.configuredNetworks - var networkId = -1 - // For each network in the list, compare the SSID with the given one - for (test in currentNetworks) { - if (test.SSID == ssid) { - networkId = test.networkId - break - } - } - return networkId - } - - - @RequiresApi(Build.VERSION_CODES.Q) - fun apiGreaterThen28(){ - val connectivityManager = mainActivity.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - - Log.e(TAG, "connection wifi with Android Q+") - val wifiNetworkSpecifier: WifiNetworkSpecifier = WifiNetworkSpecifier.Builder() - .setSsid(SSID) - .setWpa2EnterpriseConfig(enterpriseConfig()) - .build() - - val networkRequest: NetworkRequest = NetworkRequest.Builder() - .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) - .setNetworkSpecifier(wifiNetworkSpecifier) - .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) //removeCapability added for hotspots without internet - .build() - - val networkCallback = object : ConnectivityManager.NetworkCallback() { - override fun onAvailable(network: Network) { - super.onAvailable(network) - connectivityManager.bindProcessToNetwork(network) - completion(true, "200") - Log.e(TAG, "onAvailable") - } - - override fun onLosing(network: Network, maxMsToLive: Int) { - super.onLosing(network, maxMsToLive) - Log.e(TAG, "onLosing") - } - - override fun onLost(network: Network) { - super.onLost(network) - Log.e(TAG, "onLosing") - Log.e(TAG, "losing active connection") - } - - override fun onUnavailable() { - super.onUnavailable() - completion(false, "401") - Log.e(TAG, "onUnavailable") - } - - } - - //timeout add because "No devices found" wasn't handled correct and doesn't throw Unavailable - connectivityManager.requestNetwork(networkRequest, networkCallback, 30000) - } - - fun enterpriseConfig() : WifiEnterpriseConfig{ - // Initialize the WifiConfiguration object - val enterpriseConfig = WifiEnterpriseConfig() - enterpriseConfig.eapMethod = WifiEnterpriseConfig.Eap.PEAP - enterpriseConfig.identity = identity - enterpriseConfig.password = password - enterpriseConfig.phase2Method = WifiEnterpriseConfig.Phase2.NONE -// enterpriseConfig.caCertificates = WifiEnterpriseConfig.Phase2. - return enterpriseConfig; - } - -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/LocalVideo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/LocalVideo.kt deleted file mode 100644 index cfebfe65..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/LocalVideo.kt +++ /dev/null @@ -1,58 +0,0 @@ -package com.ejada.hmg.opentok - -import android.content.Context -import android.util.AttributeSet -import android.view.LayoutInflater -import android.view.View -import android.widget.FrameLayout -import android.widget.LinearLayout -import com.ejada.hmg.R -import io.flutter.plugin.common.StandardMessageCodec -import io.flutter.plugin.platform.PlatformView -import io.flutter.plugin.platform.PlatformViewFactory - -class LocalVideoFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) { - - companion object { - private lateinit var view: LocalVideoPlatformView - - fun getViewInstance(context: Context): LocalVideoPlatformView { - if(!this::view.isInitialized) { - view = LocalVideoPlatformView(context) - } - - return view - } - } - - override fun create(context: Context, viewId: Int, args: Any?): PlatformView { - return getViewInstance(context) - } -} - -class LocalVideoPlatformView(context: Context) : PlatformView { - private val videoContainer: LocalVideoContainer = LocalVideoContainer(context) - - val container get() = videoContainer.publisherContainer - - override fun getView(): View { - return videoContainer - } - - override fun dispose() {} -} - -class LocalVideoContainer @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyle: Int = 0, - defStyleRes: Int = 0 -) : LinearLayout(context, attrs, defStyle, defStyleRes) { - - var publisherContainer: FrameLayout private set - - init { - val view = LayoutInflater.from(context).inflate(R.layout.local_video, this, true) - publisherContainer = view.findViewById(R.id.publisher_container) - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt deleted file mode 100644 index 5142702a..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/OpenTok.kt +++ /dev/null @@ -1,181 +0,0 @@ -package com.ejada.hmg.opentok - -import android.content.Context -import android.os.Handler -import android.os.Looper -import android.util.Log -import android.view.ViewGroup -import com.facebook.stetho.urlconnection.StethoURLConnectionManager -import com.opentok.android.* -import io.flutter.embedding.engine.FlutterEngine -import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel - - -enum class OpenTokSDKState { - LOGGED_OUT, - LOGGED_IN, - WAIT, - ERROR -} - -class OpenTok(private var context: Context, private var flutterEngine: FlutterEngine){ - private lateinit var remoteVideoPlatformView: RemoteVideoPlatformView - private lateinit var localVideoPlatformView: LocalVideoPlatformView - - init { - remoteVideoPlatformView = RemoteVideoFactory.getViewInstance(context) - flutterEngine - .platformViewsController - .registry - .registerViewFactory("remote-video-container", RemoteVideoFactory()) - - localVideoPlatformView = LocalVideoFactory.getViewInstance(context) - flutterEngine - .platformViewsController - .registry - .registerViewFactory("local-video-container", LocalVideoFactory()) - } - - private var session: Session? = null - private var publisher: Publisher? = null - private var subscriber: Subscriber? = null - - - - private val sessionListener: Session.SessionListener = object: Session.SessionListener { - override fun onConnected(session: Session) { - // Connected to session - Log.d("MainActivity", "Connected to session ${session.sessionId}") - - publisher = Publisher.Builder(context).build().apply { - setPublisherListener(publisherListener) - renderer?.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL) - - view.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) - localVideoPlatformView.container.addView(view) - } - - notifyFlutter(OpenTokSDKState.LOGGED_IN) - session.publish(publisher) - } - - override fun onDisconnected(session: Session) { - notifyFlutter(OpenTokSDKState.LOGGED_OUT) - } - - override fun onStreamReceived(session: Session, stream: Stream) { - Log.d( - "MainActivity", - "onStreamReceived: New Stream Received " + stream.streamId + " in session: " + session.sessionId - ) - if (subscriber == null) { - subscriber = Subscriber.Builder(context, stream).build().apply { - renderer?.setStyle(BaseVideoRenderer.STYLE_VIDEO_SCALE, BaseVideoRenderer.STYLE_VIDEO_FILL) - setSubscriberListener(subscriberListener) - session.subscribe(this) - - remoteVideoPlatformView.container.addView(view) - } - } - } - - override fun onStreamDropped(session: Session, stream: Stream) { - Log.d( - "MainActivity", - "onStreamDropped: Stream Dropped: " + stream.streamId + " in session: " + session.sessionId - ) - - if (subscriber != null) { - subscriber = null - - remoteVideoPlatformView.container.removeAllViews() - } - } - - override fun onError(session: Session, opentokError: OpentokError) { - Log.d("MainActivity", "Session error: " + opentokError.message) - notifyFlutter(OpenTokSDKState.ERROR) - } - } - - private val publisherListener: PublisherKit.PublisherListener = object : PublisherKit.PublisherListener { - override fun onStreamCreated(publisherKit: PublisherKit, stream: Stream) { - Log.d("MainActivity", "onStreamCreated: Publisher Stream Created. Own stream " + stream.streamId) - } - - override fun onStreamDestroyed(publisherKit: PublisherKit, stream: Stream) { - Log.d("MainActivity", "onStreamDestroyed: Publisher Stream Destroyed. Own stream " + stream.streamId) - } - - override fun onError(publisherKit: PublisherKit, opentokError: OpentokError) { - Log.d("MainActivity", "PublisherKit onError: " + opentokError.message) - notifyFlutter(OpenTokSDKState.ERROR) - } - } - - var subscriberListener: SubscriberKit.SubscriberListener = object : SubscriberKit.SubscriberListener { - override fun onConnected(subscriberKit: SubscriberKit) { - Log.d("MainActivity", "onConnected: Subscriber connected. Stream: " + subscriberKit.stream.streamId) - } - - override fun onDisconnected(subscriberKit: SubscriberKit) { - Log.d("MainActivity", "onDisconnected: Subscriber disconnected. Stream: " + subscriberKit.stream.streamId) - notifyFlutter(OpenTokSDKState.LOGGED_OUT) - } - - override fun onError(subscriberKit: SubscriberKit, opentokError: OpentokError) { - Log.d("MainActivity", "SubscriberKit onError: " + opentokError.message) - notifyFlutter(OpenTokSDKState.ERROR) - } - } - - fun initSession(call: MethodCall, result: MethodChannel.Result) { - - val apiKey = requireNotNull(call.argument("apiKey")) - val sessionId = requireNotNull(call.argument("sessionId")) - val token = requireNotNull(call.argument("token")) - - notifyFlutter(OpenTokSDKState.WAIT) - session = Session.Builder(context, apiKey, sessionId).build() - session?.setSessionListener(sessionListener) - session?.connect(token) - result.success("") - } - - fun swapCamera(call: MethodCall, result: MethodChannel.Result) { - publisher?.cycleCamera() - result.success(true) - } - - fun toggleAudio(call: MethodCall, result: MethodChannel.Result) { - if (publisher != null) { - publisher?.publishAudio = !(publisher!!.publishAudio) - result.success(true) - }else{ - result.success(false) - } - } - - fun toggleVideo(call: MethodCall, result: MethodChannel.Result) { - if (publisher != null) { - publisher?.publishVideo = !(publisher!!.publishVideo) - result.success(true) - }else{ - result.success(false) - } - } - - fun hangupCall(call: MethodCall, result: MethodChannel.Result) { - session?.disconnect() - result.success(true) - } - - private fun notifyFlutter(state: OpenTokSDKState) { - Handler(Looper.getMainLooper()).post { - MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "OpenTok-Platform-Bridge") - .invokeMethod("updateState", state.toString()) - } - } -} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/RemoteVideo.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/RemoteVideo.kt deleted file mode 100644 index 9116a1e8..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/opentok/RemoteVideo.kt +++ /dev/null @@ -1,58 +0,0 @@ -package com.ejada.hmg.opentok - -import android.content.Context -import android.util.AttributeSet -import android.view.LayoutInflater -import android.view.View -import android.widget.FrameLayout -import android.widget.LinearLayout -import com.ejada.hmg.R -import io.flutter.plugin.common.StandardMessageCodec -import io.flutter.plugin.platform.PlatformView -import io.flutter.plugin.platform.PlatformViewFactory - -class RemoteVideoFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) { - - companion object { - private lateinit var view: RemoteVideoPlatformView - - fun getViewInstance(context: Context): RemoteVideoPlatformView { - if(!this::view.isInitialized) { - view = RemoteVideoPlatformView(context) - } - - return view - } - } - - override fun create(context: Context, viewId: Int, args: Any?): PlatformView { - return getViewInstance(context) - } -} - -class RemoteVideoPlatformView(context: Context) : PlatformView { - private val videoContainer: RemoteVideoContainer = RemoteVideoContainer(context) - - val container get() = videoContainer.subscriberContainer - - override fun getView(): View { - return videoContainer - } - - override fun dispose() {} -} - -class RemoteVideoContainer @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyle: Int = 0, - defStyleRes: Int = 0 -) : LinearLayout(context, attrs, defStyle, defStyleRes) { - - var subscriberContainer: FrameLayout private set - - init { - val view = LayoutInflater.from(context).inflate(R.layout.remote_video, this, true) - subscriberContainer = view.findViewById(R.id.subscriber_container) - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinMethod.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinMethod.kt deleted file mode 100644 index c76f9784..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinMethod.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.cloud.diplomaticquarterapp.penguin - -enum class PenguinMethod { - // initializePenguin("initializePenguin"), - // configurePenguin("configurePenguin"), - // showPenguinUI("showPenguinUI"), - // onPenNavUIDismiss("onPenNavUIDismiss"), - // onReportIssue("onReportIssue"), - // onPenNavSuccess("onPenNavSuccess"), - onPenNavInitializationError // onLocationOffCampus("onLocationOffCampus"), - // navigateToPOI("navigateToPOI"), - // openSharedLocation("openSharedLocation"); -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinNavigator.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinNavigator.kt deleted file mode 100644 index 98245cc9..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinNavigator.kt +++ /dev/null @@ -1,97 +0,0 @@ -package com.cloud.diplomaticquarterapp.penguin - -import android.content.Context -import com.google.gson.Gson -import com.peng.pennavmap.PlugAndPlaySDK -import com.peng.pennavmap.connections.ApiController -import com.peng.pennavmap.interfaces.RefIdDelegate -import com.peng.pennavmap.models.TokenModel -import com.peng.pennavmap.models.postmodels.PostToken -import com.peng.pennavmap.utils.AppSharedData -import okhttp3.ResponseBody -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response -import android.util.Log - - -class PenguinNavigator() { - - fun navigateTo(mContext: Context, refID: String, delegate: RefIdDelegate,clientID : String,clientKey : String ) { - val postToken = PostToken(clientID, clientKey) - getToken(mContext, postToken, object : RefIdDelegate { - override fun onRefByIDSuccess(PoiId: String?) { - Log.e("navigateTo", "PoiId is+++++++ $PoiId") - - PlugAndPlaySDK.navigateTo(mContext, refID, object : RefIdDelegate { - override fun onRefByIDSuccess(PoiId: String?) { - Log.e("navigateTo", "PoiId 2is+++++++ $PoiId") - - delegate.onRefByIDSuccess(refID) - - } - - override fun onGetByRefIDError(error: String?) { - delegate.onRefByIDSuccess(error) - } - - }) - - - } - - override fun onGetByRefIDError(error: String?) { - delegate.onRefByIDSuccess(error) - } - - }) - - } - - fun getToken(mContext: Context, postToken: PostToken?, apiTokenCallBack: RefIdDelegate) { - try { - // Create the API call - val purposesCall: Call = ApiController.getInstance(mContext) - .apiMethods - .getToken(postToken) - - // Enqueue the call for asynchronous execution - purposesCall.enqueue(object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - if (response.isSuccessful() && response.body() != null) { - try { - response.body()?.use { responseBody -> - val responseBodyString: String = responseBody.string() // Use `string()` to get the actual response content - if (responseBodyString.isNotEmpty()) { - val tokenModel = Gson().fromJson(responseBodyString, TokenModel::class.java) - if (tokenModel != null && tokenModel.token != null) { - AppSharedData.apiToken = tokenModel.token - apiTokenCallBack.onRefByIDSuccess(tokenModel.token) - } else { - apiTokenCallBack.onGetByRefIDError("Failed to parse token model") - } - } else { - apiTokenCallBack.onGetByRefIDError("Response body is empty") - } - } - } catch (e: Exception) { - apiTokenCallBack.onGetByRefIDError("An error occurred: ${e.message}") - } - } else { - apiTokenCallBack.onGetByRefIDError("Unsuccessful response: " + response.code()) - } - } - - override fun onFailure(call: Call, t: Throwable) { - apiTokenCallBack.onGetByRefIDError(t.message) - } - }) - } catch (error: Exception) { - apiTokenCallBack.onGetByRefIDError("Exception during API call: $error") - } - } - -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinView.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinView.kt deleted file mode 100644 index 9f74103f..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/penguin/PenguinView.kt +++ /dev/null @@ -1,321 +0,0 @@ -package com.cloud.diplomaticquarterapp.penguin - -import android.app.Activity -import android.content.Context -import android.content.Context.RECEIVER_EXPORTED -import android.content.IntentFilter -import android.graphics.Color -import android.os.Build -import android.util.Log -import android.view.View -import android.view.ViewGroup -import android.widget.RelativeLayout -import android.widget.Toast -import androidx.annotation.RequiresApi -import com.cloud.diplomaticquarterapp.PermissionManager.PermissionHelper -import com.cloud.diplomaticquarterapp.PermissionManager.PermissionManager -import com.cloud.diplomaticquarterapp.PermissionManager.PermissionResultReceiver -import com.ejada.hmg.MainActivity -import com.peng.pennavmap.PlugAndPlayConfiguration -import com.peng.pennavmap.PlugAndPlaySDK -import com.peng.pennavmap.enums.InitializationErrorType -import com.peng.pennavmap.interfaces.PenNavUIDelegate -import com.peng.pennavmap.utils.Languages -import io.flutter.plugin.common.BinaryMessenger -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.platform.PlatformView -import com.cloud.diplomaticquarterapp.penguin.PenguinNavigator -import com.peng.pennavmap.interfaces.PIEventsDelegate -import com.peng.pennavmap.interfaces.PILocationDelegate -import com.peng.pennavmap.interfaces.RefIdDelegate -import com.peng.pennavmap.models.PIReportIssue -/** - * Custom PlatformView for displaying Penguin UI components within a Flutter app. - * Implements `PlatformView` for rendering the view, `MethodChannel.MethodCallHandler` for handling method calls, - * and `PenNavUIDelegate` for handling SDK events. - */ -@RequiresApi(Build.VERSION_CODES.O) -internal class PenguinView( - context: Context, - id: Int, - val creationParams: Map, - messenger: BinaryMessenger, - activity: MainActivity, - val channel: MethodChannel -) : PlatformView, MethodChannel.MethodCallHandler, PenNavUIDelegate { - // The layout for displaying the Penguin UI - private val mapLayout: RelativeLayout = RelativeLayout(context) - private val _context: Context = context - - private val permissionResultReceiver: PermissionResultReceiver - private val permissionIntentFilter = IntentFilter("PERMISSION_RESULT_ACTION") - - private companion object { - const val PERMISSIONS_REQUEST_CODE = 1 - } - - private lateinit var permissionManager: PermissionManager - - // Reference to the main activity - private var _activity: Activity = activity - - private lateinit var mContext: Context - - lateinit var navigator: PenguinNavigator - - init { - // Set layout parameters for the mapLayout - mapLayout.layoutParams = ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT - ) - - mContext = context - - - permissionResultReceiver = PermissionResultReceiver { granted -> - if (granted) { - onPermissionsGranted() - } else { - onPermissionsDenied() - } - } - if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - mContext.registerReceiver( - permissionResultReceiver, - permissionIntentFilter, - RECEIVER_EXPORTED - ) - } else { - mContext.registerReceiver( - permissionResultReceiver, - permissionIntentFilter, - ) - } - - // Set the background color of the layout - mapLayout.setBackgroundColor(Color.RED) - - permissionManager = PermissionManager( - context = mContext, - listener = object : PermissionManager.PermissionListener { - override fun onPermissionGranted() { - // Handle permissions granted - onPermissionsGranted() - } - - override fun onPermissionDenied() { - // Handle permissions denied - onPermissionsDenied() - } - }, - requestCode = PERMISSIONS_REQUEST_CODE, - *PermissionHelper.getRequiredPermissions() - ) - - if (!permissionManager.arePermissionsGranted()) { - permissionManager.requestPermissions(_activity) - } else { - // Permissions already granted - permissionManager.listener.onPermissionGranted() - } - - - } - - private fun onPermissionsGranted() { - // Handle the actions when permissions are granted - Log.d("PermissionsResult", "onPermissionsGranted") - // Register the platform view factory for creating custom views - - // Initialize the Penguin SDK - initPenguin() - - - } - - private fun onPermissionsDenied() { - // Handle the actions when permissions are denied - Log.d("PermissionsResult", "onPermissionsDenied") - - } - - /** - * Returns the view associated with this PlatformView. - * - * @return The main view for this PlatformView. - */ - override fun getView(): View { - return mapLayout - } - - /** - * Cleans up resources associated with this PlatformView. - */ - override fun dispose() { - // Cleanup code if needed - } - - /** - * Handles method calls from Dart code. - * - * @param call The method call from Dart. - * @param result The result callback to send responses back to Dart. - */ - override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { - // Handle method calls from Dart code here - } - - /** - * Initializes the Penguin SDK with custom configuration and delegates. - */ - private fun initPenguin() { - navigator = PenguinNavigator() - // Configure the PlugAndPlaySDK - val language = when (creationParams["languageCode"] as String) { - "ar" -> Languages.ar - "en" -> Languages.en - else -> { - Languages.en - } - } - Log.d( - "TAG", - "initPenguin: ${Languages.getLanguageEnum(creationParams["languageCode"] as String)}" - ) - PlugAndPlaySDK.configuration = PlugAndPlayConfiguration.Builder() - .setBaseUrl( - creationParams["dataURL"] as String, - creationParams["positionURL"] as String - ) - .setServiceName( - creationParams["dataServiceName"] as String, - creationParams["positionServiceName"] as String - ) - .setClientData( - creationParams["clientID"] as String, - creationParams["clientKey"] as String - ) - .setUserName(creationParams["username"] as String) -// .setLanguageID(Languages.en) - .setLanguageID(language) - .setSimulationModeEnabled(creationParams["isSimulationModeEnabled"] as Boolean) - .setEnableBackButton(true) -// .setDeepLinkData("deeplink") - .setCustomizeColor("#2CA0AF") - .setDeepLinkSchema("") - .setIsEnableReportIssue(true) - .build() - - // Set location delegate to handle location updates -// PlugAndPlaySDK.setPiLocationDelegate { - // Example code to handle location updates - // Uncomment and modify as needed - // if (location.size() > 0) - // Toast.makeText(_context, "Location Info Latitude: ${location[0]}, Longitude: ${location[1]}", Toast.LENGTH_SHORT).show() -// } - - // Set events delegate for reporting issues -// PlugAndPlaySDK.setPiEventsDelegate(new PIEventsDelegate() { -// @Override -// public void onReportIssue(PIReportIssue issue) { -// Log.e("Issue Reported: ", issue.getReportType()); -// } -// // Implement issue reporting logic here } -// @Override -// public void onSharedLocation(String link) { -// // Implement Shared location logic here -// } -// }) - - // Start the Penguin SDK - PlugAndPlaySDK.start(mContext, this) - } - - - /** - * Navigates to the specified reference ID. - * - * @param refID The reference ID to navigate to. - */ - fun navigateTo(refID: String) { - try { - if (refID.isBlank()) { - Log.e("navigateTo", "Invalid refID: The reference ID is blank.") - } -// referenceId = refID - navigator.navigateTo(mContext, refID,object : RefIdDelegate { - override fun onRefByIDSuccess(PoiId: String?) { - Log.e("navigateTo", "PoiId is penguin view+++++++ $PoiId") - -// channelFlutter.invokeMethod( -// PenguinMethod.navigateToPOI.name, -// "navigateTo Success" -// ) - } - - override fun onGetByRefIDError(error: String?) { - Log.e("navigateTo", "error is penguin view+++++++ $error") - -// channelFlutter.invokeMethod( -// PenguinMethod.navigateToPOI.name, -// "navigateTo Failed: Invalid refID" -// ) - } - } , creationParams["clientID"] as String, creationParams["clientKey"] as String ) - - } catch (e: Exception) { - Log.e("navigateTo", "Exception occurred during navigation: ${e.message}", e) -// channelFlutter.invokeMethod( -// PenguinMethod.navigateToPOI.name, -// "Failed: Exception - ${e.message}" -// ) - } - } - - /** - * Called when Penguin UI setup is successful. - * - * @param warningCode Optional warning code received from the SDK. - */ - override fun onPenNavSuccess(warningCode: String?) { - val clinicId = creationParams["clinicID"] as String - - if(clinicId.isEmpty()) return - - navigateTo(clinicId) - } - - /** - * Called when there is an initialization error with Penguin UI. - * - * @param description Description of the error. - * @param errorType Type of initialization error. - */ - override fun onPenNavInitializationError( - description: String?, - errorType: InitializationErrorType? - ) { - val arguments: Map = mapOf( - "description" to description, - "type" to errorType?.name - ) - - channel.invokeMethod(PenguinMethod.onPenNavInitializationError.name, arguments) - Toast.makeText(mContext, "Navigation Error: $description", Toast.LENGTH_SHORT).show() - } - - /** - * Called when Penguin UI is dismissed. - */ - override fun onPenNavUIDismiss() { - // Handle UI dismissal if needed - try { - mContext.unregisterReceiver(permissionResultReceiver) - dispose(); - } catch (e: IllegalArgumentException) { - Log.e("PenguinView", "Receiver not registered: $e") - } - } -} - 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 deleted file mode 100644 index 18338e23..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.ejada.hmg.utils - -class API { - companion object{ - private val BASE = "https://hmgwebservices.com" - 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/Constants.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt deleted file mode 100644 index 86df85f4..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.ejada.hmg.utils - - -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" \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/FlutterText.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/FlutterText.kt deleted file mode 100644 index 1a650074..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/FlutterText.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.ejada.hmg.utils - -import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.common.MethodChannel.Result - -class FlutterText{ - - companion object{ - fun with(key:String, completion:(String)->Unit){ - HMGUtils.getPlatformChannel().invokeMethod("localizedValue",key, object:MethodChannel.Result{ - override fun success(result: Any?) { - val localized = result as String? - if (localized != null){ - completion(localized) - }else{ - completion(key) - } - } - - override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) { - completion(key) - require(false){ - "'localizedValue' $errorMessage" - } - } - - override fun notImplemented() { - require(false){ - "'localizedValue' method not implemented at flutter" - } - } - - }) - } - } -} \ 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 deleted file mode 100644 index 57da2eb8..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt +++ /dev/null @@ -1,224 +0,0 @@ -package com.ejada.hmg.utils - -import android.app.NotificationChannel -import android.app.NotificationManager -import android.app.PendingIntent -import android.app.job.JobInfo -import android.app.job.JobScheduler -import android.content.ComponentName -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.ejada.hmg.BuildConfig -import com.ejada.hmg.MainActivity -import com.ejada.hmg.R -import com.ejada.hmg.geofence.GeoZoneModel -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.jetbrains.anko.doAsyncResult -import org.json.JSONArray -import org.json.JSONException -import org.json.JSONObject -import java.text.SimpleDateFormat -import java.util.* -import kotlin.concurrent.timerTask - - -class HMGUtils { - - companion object{ - private lateinit var platformChannel: MethodChannel - fun getPlatformChannel():MethodChannel{ - return platformChannel - } - fun setPlatformChannel(channel: MethodChannel){ - platformChannel = channel - } - - fun timer(delay: Long, repeat: Boolean, tick: (Timer) -> Unit) : Timer{ - val timer = Timer() - if(repeat) - timer.schedule(timerTask { - tick(timer) - }, delay, delay) - else - timer.schedule(timerTask { - tick(timer) - }, delay) - - return timer - } - - fun popMessage(context: MainActivity, message: String){ - context.runOnUiThread { - Toast.makeText(context, message, Toast.LENGTH_LONG).show() - } - } - - fun popFlutterText(context: MainActivity, key: String){ - context.runOnUiThread { - FlutterText.with(key){ - Toast.makeText(context, it, Toast.LENGTH_LONG).show() - } - } - } - - 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{ - return mapOf( - "ZipCode" to "966", - "VersionID" to 5.8, - "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) - } - - - fun scheduleJob(context: Context, pendingIntentClassType:Class, jobId:Int, intervalDuration:String, deadlineMillis:Long = (30 * 1000)) { // default deadline: 30 Seconds - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { - val jobScheduler: JobScheduler = context.getSystemService(JobScheduler::class.java) - - val serviceComponent = ComponentName(context, pendingIntentClassType) - val builder = JobInfo.Builder(jobId, serviceComponent) - builder.setPersisted(true) - builder.setBackoffCriteria(30000, JobInfo.BACKOFF_POLICY_LINEAR) - - val intervalMillis = timeToMillis(intervalDuration,"HH:mm:ss") - builder.setMinimumLatency(intervalMillis) // wait at least - builder.setOverrideDeadline((intervalMillis + deadlineMillis)) // maximum delay - if (jobScheduler.schedule(builder.build()) == JobScheduler.RESULT_SUCCESS){ - Logs.save(context,"ScheduleJob", "${pendingIntentClassType.simpleName}: Job scheduled to trigger after duration $intervalDuration >> HH:mm:ss --('MinimumLatency:$intervalMillis Deadline:${(intervalMillis + deadlineMillis)}')--",Logs.STATUS.SUCCESS) - }else{ - Logs.save(context,"ScheduleJob", "${pendingIntentClassType.simpleName}: Failed to scheduled Job",Logs.STATUS.ERROR) - } - - } else { - Logs.save(context,"ScheduleJob", "${pendingIntentClassType.simpleName}: Failed to scheduled Job on VERSION.SDK_INT < ${android.os.Build.VERSION_CODES.M}",Logs.STATUS.ERROR) - } - } - - } - -} - - -private const val NOTIFICATION_CHANNEL_ID = BuildConfig.APPLICATION_ID + ".channel" - - -fun timeToMillis(time:String, format:String):Long{ - val sdf = SimpleDateFormat(format, Locale.US) - val millis = sdf.parse(time).time + TimeZone.getDefault().rawOffset - return millis -} - -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_local) - .setContentIntent(notificationPendingIntent) - .setAutoCancel(true) - .setContentTitle(title) - - subtitle.let { notification.setContentText(it) } - message.let { notification.setSubText(it) } - - notificationManager.notify(getUniqueId(), notification.build()) -} - -//------------------------- -// Open Helper Methods -//------------------------- -fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt()) - -object DateUtils { - @JvmStatic - fun dateTimeNow() : String { - val format = SimpleDateFormat("dd-MMM-yyy hh:mm:ss") - return format.format(Date()) - } -} - -fun isJSONValid(jsonString: String?): Boolean { - try { JSONObject(jsonString) } catch (ex: JSONException) { - try { JSONArray(jsonString) } catch (ex1: JSONException) { - return false - } - } - return true -} - -fun saveLog(context: Context, tag: String, message: String){ - val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - var logs = pref.getString("LOGS", "") - logs += "$tag -> $message \n" - pref.edit().putString("LOGS", logs).apply(); -} - -fun getLogs(context: Context) : String?{ - val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - return pref.getString("LOGS", "") -} - -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) - }) - - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMG_Wifi_.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMG_Wifi_.kt deleted file mode 100644 index c01bb96a..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMG_Wifi_.kt +++ /dev/null @@ -1,351 +0,0 @@ -//package com.ejada.hmg.utils -// -//import android.annotation.SuppressLint -//import android.content.Context -//import android.net.ConnectivityManager -//import android.net.Network -//import android.net.NetworkCapabilities -//import android.net.NetworkRequest -//import android.net.wifi.ScanResult -//import android.net.wifi.WifiConfiguration -//import android.net.wifi.WifiManager -//import android.util.Log -//import com.ejada.hmg.utils.API -//import com.ejada.hmg.FlutterMainActivity -//import com.github.kittinunf.fuel.core.extensions.jsonBody -//import com.github.kittinunf.fuel.httpGet -//import com.github.kittinunf.fuel.httpPost -//import org.json.JSONObject -//import java.util.* -// -// -//@SuppressLint("MissingPermission") -//class HMG_Wifi_(flutterMainActivity: FlutterMainActivity) { -// val TAG = "WIFI" -// val TEST = true -// -// var context = flutterMainActivity; -// var completionListener: ((status: Boolean, message: String) -> Unit)? = null -// -// -// private var SSID = "HMG-GUEST" -// private var USER_NAME = "" -// private var PASSWORD = "" -// var NETWORK_ID = -1 // HMG-GUEST Assigned Network ID by Android -// private lateinit var PATIENT_ID:String -// /* -// * Helpful: -// * http://stackoverflow.com/questions/5452940/how-can-i-get-android-wifi-scan-results-into-a-list -// */ -// fun triggerWifiScan(context: Context) { -// val wifi = context.getSystemService(Context.WIFI_SERVICE) as WifiManager -// wifi.startScan() -// } -// -// /* -// * Helpful: -// * http://stackoverflow.com/questions/8818290/how-to-connect-to-a-specific-wifi-network-in-android-programmatically -// */ -// fun connectToWifiNetworkWith(patientId: String): HMG_Wifi_ { -// -// val connectivityManager = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager -// -// PATIENT_ID = patientId -// -// val security = "OPEN" -// val networkPass = "" -// Log.d(TAG, "Connecting to SSID \"$SSID\" with password \"$networkPass\" and with security \"$security\" ...") -// -// // You need to create WifiConfiguration instance like this: -// val conf = WifiConfiguration() -// conf.SSID = "\"" + SSID + "\"" -// -// if (security == "OPEN") { -// conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE) -// } else if (security == "WEP") { -// conf.wepKeys[0] = "\"" + networkPass + "\"" -// conf.wepTxKeyIndex = 0 -// conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE) -// conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40) -// } else { -// conf.preSharedKey = "\"" + networkPass + "\"" -// } -// -// // Then, you need to add it to Android wifi manager settings: -// val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager -// -// NETWORK_ID = wifiManager.addNetwork(conf) -// Log.d(TAG, "Network ID: $NETWORK_ID") -// -// //wifiManager.disconnect(); -// val result = wifiManager.enableNetwork(NETWORK_ID, true) -// //wifiManager.reconnect(); -// wifiManager.saveConfiguration() -// -// if(result == true){ -// authNetworkConnection(NETWORK_ID); -// }else{ -// completionListener?.let { it(false, "Error connecting to HMG network") } -// } -// return this -// } -// -// private var authTimer:Timer? = null -// fun authNetworkConnection(networkId: Int){ -// authTimer = Timer() -// authTimer?.scheduleAtFixedRate(object : TimerTask() { -// override fun run() { -// if (connectedNetworkId() == networkId && connectedNetworkIPAddress() > 0) { -// authServerCall() -// authTimer?.cancel() -// } -// } -// -// }, 2000, 1000) -// -// // If wifi not connected in 5 sec terminate with fail status -// Timer().schedule(object : TimerTask() { -// override fun run() { -// if (null != authTimer) { -// authTimer?.cancel() -// completionListener?.let { it(false, "Error connecting to HMG network") } -// } -// } -// }, 5000) -// -// } -// -// fun authServerCall(){ -// -// fun call(){ -// -// forceNetworkCallOverWifi() -// -// val params = listOf("cmd" to "authenticate", "password" to PASSWORD, "user" to USER_NAME) -// val serverUrl = "https://captiveportal-login.hmg.com/cgi-bin/login" -//// val serverUrl = "http://192.168.102.223/cgi-bin/login" -// serverUrl -// .httpPost(params) -// .timeout(10000) -// .response { request, response, result -> -// Log.v(TAG, response.statusCode.toString()) -// -// haveInternet { have -> -// if(have){ -// Log.v(TAG, "Connected to internet via $SSID network at HMG") -// completionListener?.let { it(true, "Successfully connected to the internet") } -// }else{ -// Log.e(TAG, "failed to connect to internet via $SSID network at HMG") -// completionListener?.let { it(false, "Authentication failed or you are already using your credentials on another device") } -// } -// } -// } -// } -// -// haveInternet { has -> -// if (has){ -// getAuthCredentials { -// call() -// } -// }else{ -// completionListener?.let { it(false, "You must have active internet connection to connect with HMG Network") } -// } -// } -// } -// -// fun haveInternet(completion: ((status: Boolean) -> Unit)){ -// if (TEST) -// completion(true) -// -// "https://captive.apple.com".httpGet().response { request, response, result -> -// val have = response.statusCode == 200 && String(response.data).contains("Success", true) -// completion(have) -// } -// } -// -// fun getAuthCredentials(completion: (() -> Unit)){ -// if (TEST){ -// USER_NAME = "2300" -// PASSWORD = "1820" -// completion() -// return -// } -// -// val jsonBody = """{"PatientID":$PATIENT_ID}""" -// API.WIFI_CREDENTIALS -// .httpPost() -// .jsonBody(jsonBody, Charsets.UTF_8) -// .response { request, response, result -> -// val jsonString = String(response.data) -// Log.d(TAG, "JSON $jsonString") -// -// if (response.statusCode == 200){ -// -// val jsonObject = JSONObject(jsonString) -// if(!jsonObject.getString("ErrorMessage").equals("null")){ -// val errorMsg = jsonObject.getString("ErrorMessage") -// completionListener?.let { it(false, errorMsg) } -// -// }else{ -// jsonObject.getJSONArray("Hmg_SMS_Get_By_ProjectID_And_PatientIDList").let { array -> -// array.getJSONObject(0).let { object_ -> -// if (object_.has("UserName") && object_.has("UserName")){ -// USER_NAME = object_.getString("UserName") -// PASSWORD = object_.getString("Password") -// completion() -// }else{ -// completionListener?.let { it(false, "Failed to get your internet credentials") } -// } -// } -// } -// } -// -// }else{ -// completionListener?.let { it(false, "Failed to get your internet credentials") } -// } -// } -// } -// -// fun forceNetworkCallOverWifi(){ -// val connectivityManager = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager -//// val network = Network -//// connectivityManager.activeNetwork -// // Exit app if Network disappears. -// // Exit app if Network disappears. -//// val networkCapabilities: NetworkCapabilities = ConnectivityManager.from(context).getNetworkCapabilities(network) -//// val networkCapabilities: NetworkCapabilities = connectivityManager.getNetworkCapabilities(network) -// -//// if (networkCapabilities == null) { -//// return -//// } -// -// val mNetworkCallback = object : ConnectivityManager.NetworkCallback() { -// override fun onLost(lostNetwork: Network?) { -//// if (network.equals(lostNetwork)){ -//// //GlyphLayout.done(false) -//// } -// } -// } -// val builder: NetworkRequest.Builder = NetworkRequest.Builder() -//// for (transportType in networkCapabilities.getTransportTypes()) { -//// builder.addTransportType(transportType) -//// } -// connectivityManager.registerNetworkCallback(builder.build(), mNetworkCallback) -// } -// -// /* -// * Helpful: -// * http://stackoverflow.com/questions/6517314/android-wifi-connection-programmatically -// */ -// fun getScanResultSecurity(result: ScanResult): String? { -// val capabilities: String = result.capabilities -// val securityModes = arrayOf("WEP", "PSK", "EAP") -// for (securityMode in securityModes) { -// if (capabilities.contains(securityMode)) { -// return securityMode -// } -// } -// return "OPEN" -// } -// -// //connects to the given ssid -// fun connectToWPAWiFi(ssid: String, password: String){ -// -// WifiUtils.withContext(context) -// .connectWith(ssid, "") -// .setTimeout(40000) -// .onConnectionResult(object : ConnectionSuccessListener { -// override fun success() { -// Log.v(TAG,"Success") -// } -// -// override fun failed(@NonNull errorCode: ConnectionErrorCode) { -// Log.v(TAG,"Failed") -// } -// }) -// .start() -// if(isConnectedTo(ssid)){ //see if we are already connected to the given ssid -// return -// } -// -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { -// Log.e(TAG, "connection wifi Q") -// -// val wifiNetworkSpecifier: WifiNetworkSpecifier = WifiNetworkSpecifier.Builder() -// .setSsid(ssid) -// .setWpa2Passphrase(password) -// .build() -// -// val networkRequest: NetworkRequest = NetworkRequest.Builder() -// .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) -// .setNetworkSpecifier(wifiNetworkSpecifier) -// .build() -// -// var connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager -// var networkCallback = object : ConnectivityManager.NetworkCallback() { -// override fun onAvailable(network: Network) { -// super.onAvailable(network) -// connectivityManager.bindProcessToNetwork(network) -// Log.e(TAG, "onAvailable") -// } -// -// override fun onLosing(network: Network, maxMsToLive: Int) { -// super.onLosing(network, maxMsToLive) -// Log.e(TAG, "onLosing") -// } -// -// override fun onLost(network: Network) { -// super.onLost(network) -// Log.e(TAG, "onLosing") -// Log.e(TAG, "losing active connection") -// } -// -// override fun onUnavailable() { -// super.onUnavailable() -// Log.e(TAG, "onUnavailable") -// } -// } -// connectivityManager.requestNetwork(networkRequest, networkCallback) -// -// }else{ -// -// try { -// val wm:WifiManager= context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager -// -// Log.e(TAG, "connection wifi pre Q") -// -// var netId: Int = wm.addNetwork(getWifiConfig(ssid)) -// if (netId == -1) netId = getExistingNetworkId(ssid); -// wm.saveConfiguration() -// if(wm.enableNetwork(netId, true)){ -// Log.v(TAG,"HMG-GUEST Connected") -// }else{ -// Log.v(TAG,"HMG-GUEST failed to connect") -// } -// } catch (e: Exception) { -// e.printStackTrace() -// Log.v(TAG,"HMG-GUEST failed to connect") -// } -// } -// -// } -// -// fun connectedNetworkId():Int{ -// val wm:WifiManager= context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager -// return wm.connectionInfo.networkId -// } -// -// fun connectedNetworkIPAddress():Int{ -// val wm:WifiManager= context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager -// return wm.connectionInfo.ipAddress -// } -// -// fun isConnectedTo(bssid: String):Boolean{ -// val wm:WifiManager= context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager -// if(wm.connectionInfo.bssid == bssid){ -// return true -// } -// return false -// } -// -//} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt deleted file mode 100644 index d9dc209e..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt +++ /dev/null @@ -1,145 +0,0 @@ -package com.ejada.hmg.utils - -import android.content.Context -import android.content.SharedPreferences -import android.os.Build -import com.ejada.hmg.BuildConfig -import com.google.gson.Gson - -class Logs { - - enum class STATUS{ - SUCCESS, - ERROR; - } - class GeofenceEvent{ - companion object{ - fun save(context: Context, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){ - Logs.Common.save(context,"GeofenceEvent", tag, message, status) - } - - fun list(context: Context, tag:String? = null, status:Logs.STATUS? = null):List{ - return Logs.Common.list(context,"GeofenceEvent", tag, status) - } - - fun raw(context: Context):String{ - return Logs.Common.raw(context,"GeofenceEvent") - } - } - } - - class RegisterGeofence{ - companion object{ - fun save(context: Context, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){ - Logs.Common.save(context,"RegisterGeofence", tag, message, status) - } - - fun list(context: Context, tag:String? = null, status:Logs.STATUS? = null):List{ - return Logs.Common.list(context,"RegisterGeofence", tag, status) - } - - fun raw(context: Context):String{ - return Logs.Common.raw(context,"RegisterGeofence"); - } - } - } - - - companion object{ - private var pref:SharedPreferences? = null - fun save(context: Context, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){ - Logs.Common.save(context,"Logs", tag, message, status) - } - - fun list(context: Context, tag:String? = null, status:Logs.STATUS? = null):List{ - return Logs.Common.list(context,"Logs", tag, status) - } - - fun raw(context: Context):String{ - return Logs.Common.raw(context,"Logs"); - } - - private fun storage(context: Context):SharedPreferences{ - if(pref == null) { - pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - } - return pref!! - } - } - - private class Common{ - companion object{ - private val gson = Gson() - - fun save(context: Context, key:String, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){ - if(!BuildConfig.DEBUG) - return - - val pref = Logs.storage(context) - - val string = pref.getString(key,"{}") - val json = gson.fromJson(string,LogsContainerModel::class.java) - json.add( - LogModel().apply { - this.TAG = tag - this.MESSAGE = message - this.STATUS = status.name - this.DATE = DateUtils.dateTimeNow() - } - ) - - pref.edit().putString(key,gson.toJson(json)).apply() - } - - fun list(context: Context, key:String, tag:String? = null, status:Logs.STATUS? = null):List{ - val pref = Logs.storage(context) - val string = pref.getString(key,"{}") - val json = gson.fromJson(string,LogsContainerModel::class.java) - if(tag == null && status == null) { - return json.LOGS - }else if(tag != null && status != null){ - return json.LOGS.filter { (it.TAG == tag && it.STATUS == status.name) } - }else if(tag != null){ - return json.LOGS.filter { (it.TAG == tag) } - }else if(status != null){ - return json.LOGS.filter { (it.STATUS == status.name) } - } - return listOf() - } - - fun raw(context: Context, key:String):String{ - val pref = Logs.storage(context) - val string = pref.getString(key,"{}") - return string!! - } - - } - } - - class LogModel{ - lateinit var TAG:String - lateinit var MESSAGE:String - lateinit var STATUS:String - lateinit var DATE:String - - companion object{ - fun with(tag:String, message:String, status:String):LogModel{ - return LogModel().apply { - this.TAG = tag - this.MESSAGE = message - this.STATUS = status - this.DATE = DateUtils.dateTimeNow() - } - } - } - } - - class LogsContainerModel{ - var LOGS = mutableListOf() - fun add(log:LogModel){ - LOGS.add(log) - } - } - - -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt deleted file mode 100644 index ebb04456..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/OpenTokPlatformBridge.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.ejada.hmg.utils - -import com.ejada.hmg.MainActivity -import com.ejada.hmg.opentok.OpenTok -import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel - -class OpenTokPlatformBridge(private var flutterEngine: FlutterEngine, private var mainActivity: MainActivity) { - - private lateinit var channel: MethodChannel - private lateinit var openTok: OpenTok - - companion object { - private const val CHANNEL = "OpenTok-Platform-Bridge" - } - - fun create(){ - openTok = OpenTok(mainActivity, flutterEngine) - channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) - channel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -> - when (call.method) { - "initSession" -> { - openTok.initSession(call, result) - } - "swapCamera" -> { - openTok.swapCamera(call, result) - } - "toggleAudio" -> { - openTok.toggleAudio(call, result) - } - "toggleVideo" -> { - openTok.toggleVideo(call, result) - } - "hangupCall" -> { - openTok.hangupCall(call, result) - } - else -> { - result.notImplemented() - } - } - } - } - -} 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 deleted file mode 100644 index 9a66f4b3..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt +++ /dev/null @@ -1,199 +0,0 @@ -package com.ejada.hmg.utils - -import android.content.Context -import android.content.Intent -import android.content.Intent.getIntent -import android.net.Uri -import android.os.Build -import android.os.Bundle -import android.provider.Settings -import android.widget.Toast -import androidx.core.app.ActivityCompat.startActivityForResult -import android.net.wifi.WifiManager -import android.util.Log -import com.ejada.hmg.MainActivity -import com.ejada.hmg.hmgwifi.HMG_Guest -import com.ejada.hmg.geofence.GeoZoneModel -import com.ejada.hmg.geofence.HMG_Geofence -import com.ejada.hmg.hmgwifi.WpaEnterprise -import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel - -class PlatformBridge(private var flutterEngine: FlutterEngine, private var mainActivity: MainActivity) { - - private lateinit var channel: MethodChannel - - companion object { - private const val CHANNEL = "HMG-Platform-Bridge" - 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" - private const val IS_DRAW_OVER_APPS_PERMISSION_ALLOWED = "isDrawOverAppsPermissionAllowed" - private const val ASK_DRAW_OVER_APPS_PERMISSION = "askDrawOverAppsPermission" - private const val GET_INTENT = "getIntent" - } - - fun create() { - channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) - HMGUtils.setPlatformChannel(channel) - channel.setMethodCallHandler { methodCall: MethodCall, result: MethodChannel.Result -> - - if (methodCall.method == HMG_INTERNET_WIFI_CONNECT_METHOD) { - connectHMGInternetWifi(methodCall, result) - - } else if (methodCall.method == HMG_GUEST_WIFI_CONNECT_METHOD) { - connectHMGGuestWifi(methodCall, result) - - } 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 if (methodCall.method == IS_DRAW_OVER_APPS_PERMISSION_ALLOWED) { - isDrawOverAppsPermissionAllowed(methodCall, result) - } else if (methodCall.method == ASK_DRAW_OVER_APPS_PERMISSION) { - askDrawOverAppsPermission(methodCall, result) - } else if (methodCall.method == GET_INTENT) { - getIntentData(methodCall, result) - } else { - result.notImplemented() - } - - } - - val res = channel.invokeMethod("localizedValue", "errorConnectingHmgNetwork") - - } - - private fun connectHMGInternetWifi(methodCall: MethodCall, result: MethodChannel.Result) { - (methodCall.arguments as ArrayList<*>).let { - require(it.size == 3 && (it[0] is String) && (it[1] is String), lazyMessage = { - "Missing or invalid arguments (Must have three argument of 'String'" - }) - - val ssid = it[0].toString() - val username = it[1].toString() - val password = it[2].toString() - - WpaEnterprise(mainActivity,ssid).connect(username,password) { status, message -> - HMGUtils.timer(2000,false){ - mainActivity.runOnUiThread { - if(status) - result.success(if (status) 1 else 0) - else - result.error(message, null, null) - } - } - } - -// HMG_Internet(mainActivity) -// .connectToHMGGuestNetwork(username, password) { status, message -> -// mainActivity.runOnUiThread { -// result.success(if (status) 1 else 0) -// -// HMGUtils.popFlutterText(mainActivity, message) -// Log.v(this.javaClass.simpleName, "$status | $message") -// } -// -// } - } - } - - - private fun connectHMGGuestWifi(methodCall: MethodCall, result: MethodChannel.Result) { - (methodCall.arguments as ArrayList<*>).let { - require(it.size == 1 && (it[0] is String), lazyMessage = { - "Missing or invalid arguments (Must have one argument 'String at 0'" - }) - - val ssid = it[0].toString() - HMG_Guest(mainActivity, ssid).connectToHMGGuestNetwork { status, message -> - mainActivity.runOnUiThread { - result.success(if (status) 1 else 0) - - HMGUtils.popFlutterText(mainActivity, message) - Log.v(this.javaClass.simpleName, "$status | $message") - } - } - } - } - - private fun enableWifiIfNot(methodCall: MethodCall, result: MethodChannel.Result) { - val wm = mainActivity.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager? - if (wm != null) { - if (!wm.isWifiEnabled) - wm.isWifiEnabled = true - result.success(true) - } 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() { s, e -> } - } - } - - override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {} - override fun notImplemented() {} - }) - - } - - 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); - } - } - - private fun isDrawOverAppsPermissionAllowed(methodCall: MethodCall, result: MethodChannel.Result) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if ( - Settings.canDrawOverlays(mainActivity) - ) { - result.success(true) - } else { - result.success(false) - } - } else { - result.success(false) - } - } - - private fun askDrawOverAppsPermission(methodCall: MethodCall, result: MethodChannel.Result) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION) - val uri = Uri.parse("package:" + mainActivity.getPackageName()) - intent.setData(uri) - startActivityForResult(mainActivity, intent, 102, null) - result.success(true) - } else { - result.success(false) - } - } - - private fun getIntentData(methodCall: MethodCall, result: MethodChannel.Result) { - - val bundle: Bundle? = getIntent("").extras - if (bundle != null) { - val message = bundle.getString("notification") // 1 - System.out.println("BundleExtra:" + message) - Toast.makeText(this.mainActivity, message + "", Toast.LENGTH_SHORT).show() - } else { - Toast.makeText(this.mainActivity, "Bundle Null", Toast.LENGTH_SHORT).show(); - } - result.success(true); - } -} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/AppSignatureRetriever.java b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/AppSignatureRetriever.java deleted file mode 100644 index 83e6e917..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/AppSignatureRetriever.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.cloud.diplomaticquarterapp.whatsapp; - -import static java.sql.DriverManager.println; - -import android.content.Context; -import android.content.ContextWrapper; -import android.content.pm.PackageManager; -import android.content.pm.Signature; -import android.util.Base64; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; -import java.util.Collection; -import java.util.stream.Collectors; - -public class AppSignatureRetriever { - - private static final String HASH_TYPE = "SHA-256"; - public static final int NUM_HASHED_BYTES = 9; - public static final int NUM_BASE64_CHAR = 11; - - - public void logSignatures(Context context) { - Collection appSignatures = getAppSignatures(context); - appSignatures.forEach(signature -> println("Signature: " + signature)); - } - - /** - * Get all the app signatures for the current package. - * - * @return signatures for current app - */ - public Collection getAppSignatures(Context context) { - try { - // Get all package signatures for the current package - String packageName = context.getPackageName(); - println("Package name: " + packageName); - PackageManager packageManager = context.getPackageManager(); - Signature[] signatures = packageManager.getPackageInfo(packageName, - PackageManager.GET_SIGNATURES).signatures; - - // For each signature create a compatible hash - Collection appCodes = Arrays.stream(signatures) - .map(signature -> hash(packageName, signature.toCharsString())) - .collect(Collectors.toList()); - return appCodes; - } catch (PackageManager.NameNotFoundException e) { - println("Unable to find package to obtain hash."); - throw new RuntimeException("Unable to find package to obtain hash.", e); - } - - } - - private String hash(String packageName, String signature) { - String appInfo = packageName + " " + signature; - try { - MessageDigest messageDigest = MessageDigest.getInstance(HASH_TYPE); - messageDigest.update(appInfo.getBytes(StandardCharsets.UTF_8)); - byte[] hashSignature = messageDigest.digest(); - - // truncated into NUM_HASHED_BYTES - hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES); - // encode into Base64 - String base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING | Base64.NO_WRAP); - base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR); - - println(String.format("pkg: %s -- hash: %s", packageName, base64Hash)); - return base64Hash; - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException("Unable to generate hash for application", e); - } - } -} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsApp.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsApp.kt deleted file mode 100644 index 73452e6f..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsApp.kt +++ /dev/null @@ -1,31 +0,0 @@ - -package com.cloud.diplomaticquarterapp.whatsapp - -import android.content.Context -import android.content.Intent -import com.whatsapp.otp.android.sdk.WhatsAppOtpHandler -import com.whatsapp.otp.android.sdk.WhatsAppOtpIncomingIntentHandler -import java.lang.ref.WeakReference - -object WhatsApp { - val whatsAppOtpHandler = WhatsAppOtpHandler() - inline fun handleOTP ( intent: Intent, crossinline validateOTP:(code: String )-> Unit) = - WhatsAppOtpIncomingIntentHandler().processOtpCode( - intent, - // call your function to validate - {code -> validateOTP(code) }, - {error,exception-> - println("the error is ${error.name}") - println("the exception stacktrace is ${exception.message}") - println("the exception is cause ${exception.cause}") - }) - - - fun performHandShake(context : WeakReference) = whatsAppOtpHandler.sendOtpIntentToWhatsApp(context.get()!!) - - - - fun isWhatsAppInstalled(context : WeakReference) : Boolean = whatsAppOtpHandler.isWhatsAppInstalled(context.get()!!) - - -} diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsAppCodeActivity.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsAppCodeActivity.kt deleted file mode 100644 index 5739022e..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsAppCodeActivity.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.cloud.diplomaticquarterapp.whatsapp -import android.app.PendingIntent -import android.content.Intent -import android.os.Bundle -import com.cloud.diplomaticquarterapp.whatsapp.WhatsApp -import com.cloud.diplomaticquarterapp.whatsapp.WhatsAppOtpPlatformBridge -import io.flutter.embedding.android.FlutterFragmentActivity - -class WhatsAppCodeActivity : FlutterFragmentActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - WhatsApp.handleOTP(intent){code -> - WhatsAppOtpPlatformBridge.result?.success(code); - finish() - } - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsAppOtpPlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsAppOtpPlatformBridge.kt deleted file mode 100644 index 5493e8be..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/whatsapp/WhatsAppOtpPlatformBridge.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.cloud.diplomaticquarterapp.whatsapp - -import com.ejada.hmg.MainActivity -import io.flutter.embedding.engine.FlutterEngine -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel -import java.lang.ref.WeakReference - -class WhatsAppOtpPlatformBridge( - private var flutterEngine: FlutterEngine, - private var mainActivity: MainActivity -) { - - - private lateinit var channel: MethodChannel - - companion object { - private const val CHANNEL = "whats_app_otp" - var result: MethodChannel.Result? = null - } - - fun invoke() { - channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) - channel.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -> - when (call.method) { - "isWhatsAppInstalled" -> { - val isAppInstalled = - WhatsApp.isWhatsAppInstalled(WeakReference(mainActivity)) - result.success(isAppInstalled) - } - - "performHandShake" -> { - WhatsApp.performHandShake(WeakReference(mainActivity)) - } - - - "startListening" -> { - WhatsAppOtpPlatformBridge.result = result - } - - else -> { - result.notImplemented() - } - - } - } - } -} \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 03bc5150..7c04d8f0 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/android/settings.gradle b/android/settings.gradle index 884c688d..2a6c7699 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -8,21 +8,85 @@ pluginManagement { return flutterSdkPath }() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + // Get vital-sign-engine path +// def vitalSignEngine = { +// def properties = new Properties() +// file("local.properties").withInputStream { properties.load(it) } +// def vitalSignEnginePath = properties.getProperty("vital.sign.engine.path") +// assert vitalSignEnginePath != null, "vital.sign.engine.path not set in local.properties" +// return vitalSignEnginePath +// }() + repositories { google() mavenCentral() + maven { url 'https://developer.huawei.com/repo/' } gradlePluginPortal() } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "com.huawei.agconnect") { + useModule("com.huawei.agconnect:agcp:1.9.1.304") + } + } + } + + dependencyResolutionManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + flatDir { + dirs 'libs' + } + maven { + url 'https://developer.huawei.com/repo/' + } + maven { + url "https://artifactory.ess-dev.com/artifactory/gradle-dev-local" + } + maven { + url 'https://api.mapbox.com/downloads/v2/releases/maven' + credentials { + username = 'mapbox' + password = "sk.eyJ1IjoicndhaWQiLCJhIjoiY2x6NWo0bTMzMWZodzJrcGZpemYzc3Z4dSJ9.uSSZuwNSGCcCdPAiORECmg" + if (password == null || password == "") { + throw new GradleException("MAPBOX_DOWNLOADS_TOKEN isn't set. Set it to the project properties or to the environment variables.") + } + } + authentication { + basic(BasicAuthentication) + } + } + } + } } plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version '8.1.0' apply false - id "org.jetbrains.kotlin.android" version "1.8.22" apply false - id "com.google.protobuf" version "0.9.1" apply false + id "com.android.application" version '8.11.0' apply false + id("org.jetbrains.kotlin.android") version "2.2.0" apply false + id("com.google.gms.google-services") version "4.4.3" apply false + id("com.google.firebase.crashlytics") version "3.0.4" apply false + id('org.gradle.toolchains.foojay-resolver-convention') version '0.9.0' apply false + id "com.huawei.agconnect" version "1.9.1.304" apply false + } include ":app" + +//// Add the following to include vitalSignEngine as a module +//def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +//def properties = new Properties() +//assert localPropertiesFile.exists() +//localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } +//def vitalSignEnginePath = properties.getProperty('vital.sign.engine.path') +//assert vitalSignEnginePath != null : "vital.sign.engine.path not set in local.properties" +// +//include ':vitalSignEngine' +//project(':vitalSignEngine').projectDir = file(vitalSignEnginePath)