no message

merge-requests/236/head
Zohaib Kambrani 4 years ago
parent 1dc9400ffc
commit 0f64c45e67

@ -44,7 +44,7 @@ class GeoZoneModel {
long, long,
rad rad
) )
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT) .setTransitionTypes(GeofenceTransition.ENTER_EXIT.value)
// .setNotificationResponsiveness(0) // .setNotificationResponsiveness(0)
.setExpirationDuration(Geofence.NEVER_EXPIRE) .setExpirationDuration(Geofence.NEVER_EXPIRE)
.build() .build()

@ -37,7 +37,10 @@ import android.location.Location
import android.util.Log import android.util.Log
import androidx.core.app.JobIntentService import androidx.core.app.JobIntentService
import com.cloud.diplomaticquarterapp.utils.API import com.cloud.diplomaticquarterapp.utils.API
import com.cloud.diplomaticquarterapp.utils.httpPost
import com.cloud.diplomaticquarterapp.utils.sendNotification
import com.github.kittinunf.fuel.core.extensions.jsonBody import com.github.kittinunf.fuel.core.extensions.jsonBody
import com.github.kittinunf.fuel.core.isSuccessful
import com.github.kittinunf.fuel.httpPost import com.github.kittinunf.fuel.httpPost
import com.google.android.gms.location.Geofence import com.google.android.gms.location.Geofence
import com.google.android.gms.location.GeofencingEvent import com.google.android.gms.location.GeofencingEvent
@ -73,34 +76,31 @@ class GeofenceTransitionsJobIntentService : JobIntentService() {
private fun handleEvent(triggerGeofences: List<Geofence>, location:Location, transition:GeofenceTransition) { private fun handleEvent(triggerGeofences: List<Geofence>, location:Location, transition:GeofenceTransition) {
val hmg = HMG_Geofence.shared(this) val hmg = HMG_Geofence.shared(this)
if (hmg.getPatientID() != null){ hmg.getPatientID()?.let { patientId ->
hmg.getActiveGeofences({ activeGeofences -> hmg.getActiveGeofences({ activeGeofences ->
triggerGeofences.forEach { geofence -> triggerGeofences.forEach { geofence ->
// Extract PointID from 'geofence.requestId' and find from active geofences // Extract PointID from 'geofence.requestId' and find from active geofences
val pointID = activeGeofences.firstOrNull {it == geofence.requestId.split("_").first() } val pointID = activeGeofences.firstOrNull {it == geofence.requestId}?.split('_')?.first()
if(!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null){ if(!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null){
val jsonBody = Gson().toJson( val body = mapOf(
mapOf("PointsID" to pointID.toIntOrNull(), "PointsID" to pointID.toIntOrNull(),
"GeoType" to transition.value, "GeoType" to transition.value,
"PatientID" to "") "PatientID" to patientId
) )
API.LOG_GEOFENCE httpPost<Map<String,Any>>(API.LOG_GEOFENCE, body, { response ->
.httpPost() sendNotification(this, transition.named(), geofence.requestId, "Notified to server.😎")
.jsonBody(jsonBody,Charsets.UTF_8) },{ exception ->
.timeout(10000) sendNotification(this, transition.named(), geofence.requestId, "Failed to notify server.😔")
.response { request, response, result -> })
}
} }
} }
},null) },null)
} }
} }
} }

@ -0,0 +1,21 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package io.flutter.plugins.geofencing
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence
class GeofencingRebootBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action.equals("android.intent.action.BOOT_COMPLETED")) {
HMG_Geofence.shared(context).unRegisterAll { status, exception ->
HMG_Geofence.shared(context).re
}
}
}
}

@ -16,11 +16,21 @@ import com.google.gson.reflect.TypeToken
enum class GeofenceTransition(val value: Int) { enum class GeofenceTransition(val value: Int) {
ENTER(1), ENTER(1),
EXIT(2); EXIT(2),
ENTER_EXIT((ENTER.value or EXIT.value)),
DWELL(4);
companion object { companion object {
fun fromInt(value: Int) = GeofenceTransition.values().first { it.value == value } fun fromInt(value: Int) = GeofenceTransition.values().first { it.value == value }
} }
fun named():String{
if (value == 1)return "Enter"
if (value == 2)return "Exit"
if (value == (ENTER.value or EXIT.value))return "Enter or Exit"
if (value == 4)return "dWell"
return "unknown"
}
} }
const val PREFS_STORAGE = "FlutterSharedPreferences" const val PREFS_STORAGE = "FlutterSharedPreferences"
@ -28,9 +38,11 @@ const val PREF_KEY_SUCCESS = "HMG_GEOFENCE_SUCCESS"
const val PREF_KEY_FAILED = "HMG_GEOFENCE_FAILED" const val PREF_KEY_FAILED = "HMG_GEOFENCE_FAILED"
class HMG_Geofence { class HMG_Geofence {
// https://developer.android.com/training/location/geofencing#java
private lateinit var context: Context private lateinit var context: Context
private lateinit var preferences:SharedPreferences private lateinit var preferences:SharedPreferences
private val gson = Gson()
private lateinit var geofencingClient:GeofencingClient private lateinit var geofencingClient:GeofencingClient
private val geofencePendingIntent: PendingIntent by lazy { private val geofencePendingIntent: PendingIntent by lazy {
@ -86,10 +98,10 @@ class HMG_Geofence {
print(it.localizedMessage) print(it.localizedMessage)
} }
} }
},null); },null)
} }
fun unRegisterAll(completion: (status: Boolean, message: String?) -> Unit){ fun unRegisterAll(completion: (status: Boolean, exception:Exception?) -> Unit){
getActiveGeofences({ success -> getActiveGeofences({ success ->
geofencingClient geofencingClient
.removeGeofences(success) .removeGeofences(success)
@ -97,7 +109,7 @@ class HMG_Geofence {
completion(true, null) completion(true, null)
} }
.addOnFailureListener { .addOnFailureListener {
completion(false, it.localizedMessage) completion(false, it)
} }
}, { failed -> }, { failed ->
// Nothing to do with failed geofences. // Nothing to do with failed geofences.
@ -105,7 +117,6 @@ class HMG_Geofence {
} }
fun saveGeofenceResults(success: List<String>, failed: List<String>){ fun saveGeofenceResults(success: List<String>, failed: List<String>){
val gson = Gson()
val jsonSuccess = gson.toJson(success) val jsonSuccess = gson.toJson(success)
val jsonFailure = gson.toJson(failed) val jsonFailure = gson.toJson(failed)
preferences.edit().putString(PREF_KEY_SUCCESS, jsonSuccess).apply() preferences.edit().putString(PREF_KEY_SUCCESS, jsonSuccess).apply()
@ -114,7 +125,6 @@ class HMG_Geofence {
} }
fun getActiveGeofences(success: (success: List<String>) -> Unit, failure: ((failed: List<String>) -> Unit)?){ fun getActiveGeofences(success: (success: List<String>) -> Unit, failure: ((failed: List<String>) -> Unit)?){
val gson = Gson()
val type = object : TypeToken<List<String?>?>() {}.type val type = object : TypeToken<List<String?>?>() {}.type
val jsonSuccess = preferences.getString(PREF_KEY_SUCCESS, "[]") val jsonSuccess = preferences.getString(PREF_KEY_SUCCESS, "[]")
@ -130,14 +140,16 @@ class HMG_Geofence {
} }
private fun checkPermission() : Boolean{ private fun checkPermission() : Boolean{
return ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED return ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
} }
fun getPatientID():Int?{ fun getPatientID():Int?{
val profileJson = preferences.getString("flutter.user-profile", "{}") val profileJson = preferences.getString("flutter.user-profile", "{}")
val type = object : TypeToken<Map<String?, Any?>?>() {}.type val type = object : TypeToken<Map<String?, Any?>?>() {}.type
return Gson() return gson.fromJson<Map<String?, Any?>?>(profileJson,type)
.fromJson<Map<String?, Any?>?>(profileJson,type) ?.get("PatientID")
?.get("PatientID") as? Int .toString()
.toDoubleOrNull()
?.toInt()
} }
} }

@ -3,21 +3,28 @@ package com.cloud.diplomaticquarterapp.utils
import android.app.NotificationChannel import android.app.NotificationChannel
import android.app.NotificationManager import android.app.NotificationManager
import android.app.PendingIntent import android.app.PendingIntent
import android.content.ClipData.newIntent
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.annotation.Nullable
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.TaskStackBuilder import androidx.core.app.TaskStackBuilder
import com.cloud.diplomaticquarterapp.BuildConfig import com.cloud.diplomaticquarterapp.BuildConfig
import com.cloud.diplomaticquarterapp.MainActivity import com.cloud.diplomaticquarterapp.MainActivity
import com.cloud.diplomaticquarterapp.R import com.cloud.diplomaticquarterapp.R
import com.github.kittinunf.fuel.core.extensions.jsonBody
import com.github.kittinunf.fuel.httpPost
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.util.* import java.util.*
import kotlin.concurrent.timerTask import kotlin.concurrent.timerTask
class HMGUtils { class HMGUtils {
companion object{ companion object{
@ -25,34 +32,34 @@ class HMGUtils {
fun getPlatformChannel():MethodChannel{ fun getPlatformChannel():MethodChannel{
return platformChannel return platformChannel
} }
fun setPlatformChannel(channel:MethodChannel){ fun setPlatformChannel(channel: MethodChannel){
platformChannel = channel platformChannel = channel
} }
fun timer(delay:Long, repeat:Boolean, tick:(Timer)->Unit) : Timer{ fun timer(delay: Long, repeat: Boolean, tick: (Timer) -> Unit) : Timer{
val timer = Timer() val timer = Timer()
if(repeat) if(repeat)
timer.schedule(timerTask { timer.schedule(timerTask {
tick(timer) tick(timer)
},delay,delay) }, delay, delay)
else else
timer.schedule(timerTask { timer.schedule(timerTask {
tick(timer) tick(timer)
},delay) }, delay)
return timer return timer
} }
fun popMessage(context:MainActivity, message:String){ fun popMessage(context: MainActivity, message: String){
context.runOnUiThread { context.runOnUiThread {
Toast.makeText(context,message,Toast.LENGTH_LONG).show() Toast.makeText(context, message, Toast.LENGTH_LONG).show()
} }
} }
fun popFlutterText(context:MainActivity, key:String){ fun popFlutterText(context: MainActivity, key: String){
context.runOnUiThread { context.runOnUiThread {
FlutterText.with(key){ FlutterText.with(key){
Toast.makeText(context,it,Toast.LENGTH_LONG).show() Toast.makeText(context, it, Toast.LENGTH_LONG).show()
} }
} }
} }
@ -66,9 +73,8 @@ private fun Timer.schedule(timerTask: TimerTask) {
} }
private const val NOTIFICATION_CHANNEL_ID = BuildConfig.APPLICATION_ID + ".channel" private const val NOTIFICATION_CHANNEL_ID = BuildConfig.APPLICATION_ID + ".channel"
fun sendNotification(context: Context, message: String) { fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, message:String?) {
val notificationManager = context val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
&& notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID) == null) { && notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID) == null) {
@ -80,23 +86,63 @@ fun sendNotification(context: Context, message: String) {
notificationManager.createNotificationChannel(channel) notificationManager.createNotificationChannel(channel)
} }
val intent = Intent(context,MainActivity::class.java) val intent = Intent(context, MainActivity::class.java)
val stackBuilder = TaskStackBuilder.create(context) val stackBuilder = TaskStackBuilder.create(context)
.addParentStack(MainActivity::class.java) .addParentStack(MainActivity::class.java)
.addNextIntent(intent) .addNextIntent(intent)
val notificationPendingIntent = stackBuilder val notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT)
.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT)
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher) .setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(message)
.setContentIntent(notificationPendingIntent) .setContentIntent(notificationPendingIntent)
.setAutoCancel(true) .setAutoCancel(true)
.build() .setContentTitle(title)
subtitle.let { notification.setContentText(it) }
message.let { notification.setSubText(it) }
notificationManager.notify(getUniqueId(), notification.build())
}
notificationManager.notify(getUniqueId(), notification) private fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt())
fun isJSONValid(jsonString: String?): Boolean {
try { JSONObject(jsonString) } catch (ex: JSONException) {
try { JSONArray(jsonString) } catch (ex1: JSONException) {
return false
}
}
return true
} }
class HTTPResponse<T>(data: T){
final var data:T = data
}
fun <T>httpPost(url: String, body: Map<String, Any?>, onSuccess: (response: HTTPResponse<T>) -> Unit, onError: (error: Exception) -> Unit){
val gson = Gson()
val type = object : TypeToken<T>() {}.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<T>(dataString,type)
onSuccess(HTTPResponse(responseData))
}else{
onError(Exception("Invalid response from server (Not a valid JSON)"))
}
}, {
onError(it)
it.localizedMessage
})
private fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt()) }
}

@ -94,9 +94,8 @@ class PlatformBridge(binaryMessenger: BinaryMessenger, flutterMainActivity: Main
if (!wm.isWifiEnabled) if (!wm.isWifiEnabled)
wm.isWifiEnabled = true wm.isWifiEnabled = true
result.success(true) result.success(true)
}else{ }else
result.error("101","Error while opening wifi, Please try to open wifi yourself and try again","'WifiManager' service failed"); result.error("101","Error while opening wifi, Please try to open wifi yourself and try again","'WifiManager' service failed");
}
} }
@ -104,10 +103,10 @@ class PlatformBridge(binaryMessenger: BinaryMessenger, flutterMainActivity: Main
channel.invokeMethod("getGeoZones",null, object : MethodChannel.Result{ channel.invokeMethod("getGeoZones",null, object : MethodChannel.Result{
override fun success(result: Any?) { override fun success(result: Any?) {
if(result is String) if(result is String) {
HMG_Geofence.shared(mainActivity).unRegisterAll { status, message -> val geoZones = GeoZoneModel().listFrom(result)
HMG_Geofence.shared(mainActivity).register(GeoZoneModel().listFrom(result)) HMG_Geofence.shared(mainActivity).register(geoZones)
} }
} }
override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) { print(result) } override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) { print(result) }
@ -117,7 +116,12 @@ class PlatformBridge(binaryMessenger: BinaryMessenger, flutterMainActivity: Main
} }
private fun unRegisterHmgGeofences(methodCall: MethodCall, result: MethodChannel.Result) { private fun unRegisterHmgGeofences(methodCall: MethodCall, result: MethodChannel.Result) {
HMG_Geofence.shared(mainActivity).unRegisterAll { status, exception ->
if(status)
result.success(true)
else
result.error("101", exception?.localizedMessage, exception);
}
} }
} }

@ -20,7 +20,7 @@ PODS:
- Firebase/Messaging (6.33.0): - Firebase/Messaging (6.33.0):
- Firebase/CoreOnly - Firebase/CoreOnly
- FirebaseMessaging (~> 4.7.0) - FirebaseMessaging (~> 4.7.0)
- firebase_core (0.5.2): - firebase_core (0.5.3):
- Firebase/CoreOnly (~> 6.33.0) - Firebase/CoreOnly (~> 6.33.0)
- Flutter - Flutter
- firebase_core_web (0.1.0): - firebase_core_web (0.1.0):
@ -70,7 +70,7 @@ PODS:
- Flutter - Flutter
- flutter_tts (0.0.1): - flutter_tts (0.0.1):
- Flutter - Flutter
- "geolocator (6.0.0+4)": - geolocator (6.1.9):
- Flutter - Flutter
- google_maps_flutter (0.0.1): - google_maps_flutter (0.0.1):
- Flutter - Flutter
@ -375,7 +375,7 @@ SPEC CHECKSUMS:
device_calendar: 23b28a5f1ab3bf77e34542fb1167e1b8b29a98f5 device_calendar: 23b28a5f1ab3bf77e34542fb1167e1b8b29a98f5
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
firebase_core: 350ba329d1641211bc6183a3236893cafdacfea7 firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659
firebase_core_web: d501d8b946b60c8af265428ce483b0fff5ad52d1 firebase_core_web: d501d8b946b60c8af265428ce483b0fff5ad52d1
firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75 firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75
FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd
@ -390,7 +390,7 @@ SPEC CHECKSUMS:
flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186 flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186
flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35 flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35
flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d
geolocator: 1ae40084cc6c1586ce5ad12cfc3fd38c64d05f2f geolocator: 057a0c63a43e9c5296d8ad845a3ac8e6df23d899
google_maps_flutter: c7f9c73576de1fbe152a227bfd6e6c4ae8088619 google_maps_flutter: c7f9c73576de1fbe152a227bfd6e6c4ae8088619
GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833
GoogleMaps: 4b5346bddfe6911bb89155d43c903020170523ac GoogleMaps: 4b5346bddfe6911bb89155d43c903020170523ac
@ -440,4 +440,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 5a17be3f8af73a757fa4439c77cf6ab2db29a6e7 PODFILE CHECKSUM: 5a17be3f8af73a757fa4439c77cf6ab2db29a6e7
COCOAPODS: 1.10.0 COCOAPODS: 1.8.4

@ -472,7 +472,7 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 3A359E86ZF; DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -611,7 +611,7 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 3A359E86ZF; DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -644,7 +644,7 @@
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 3A359E86ZF; DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",

Loading…
Cancel
Save