Merge branch 'master' into 'development'

Master

See merge request Cloud_Solution/diplomatic-quarter!230
merge-requests/232/merge
Mohammad Aljammal 4 years ago
commit be1a2d4180

1
.gitignore vendored

@ -42,3 +42,4 @@ app.*.map.json
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
health_calculators.dart

@ -0,0 +1,13 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Flutter",
"request": "launch",
"type": "dart"
}
]
}

Binary file not shown.

@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICkDCCAXgCAQAwSzEjMCEGCSqGSIb3DQEJARYUaGFyb29uNjEzOEBnbWFpbC5j
b20xFzAVBgNVBAMMDk1vaGFtZWQgTWVrYXd5MQswCQYDVQQGEwJBRTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALcPrk09MmhQhRNe8LYdaeN4mYtoKJg3
SndMLgpxnaRqP7a6f4sp118wCFZsTXnwhPVP4DzmXWc2AzZtsusmhdw1tzNFtme0
PtEjDXIPI2lHU3Zhi2zukZdAVxF+uNi3pcp0axina60ZQciIfb/7Fx6hNbqpk90E
O8a2Ob17Wq/ZTYIP4H7ZGydUe2ra9QyDtjmGj9vpEv+xXYWX685sgEylTG14DSOP
ozGsQmaf+QCMbCT3osq7idWc1IQ+3Oed0kUTx1jmRtZwPzQkJJ1Bx3vYSXN/EOlb
u+ei1Nqtc14aVCYvmcuvGDtMyRtw6w+syCw2CpJCPGNkxNz+EH9h+EUCAwEAAaAA
MA0GCSqGSIb3DQEBCwUAA4IBAQBYdu2AaZY6kReuT1Xp8ktlyPfjBRKhPPChuaeR
tFnYMsJtG0aIA/xOu4/RYDgmL92seimULXd9DIPvkJ2DuaB+bdfGTw0qXUlihkm8
ui5O0L2F9OZbQxJogvTmrMsKnkoR27O5vyfCn9VMOLk3x1nyEzAXIj/5GHWw9T6t
r65jPUOfm6ikiZtICBzSaTPBtyfZB8mrbwG2dpOvVNSa1dj3xip4L8CL6TxH+qM3
+N90QFYjvjphJkpn2Kt0ow9IyIyeqJbIYJmsWoV9pXddOHCjKdTWUjq7D2Jn3eUA
DAKjKgVqF4/dU10k7EtSfrw01aHLXjj5FxsD5YhVrgTA5xSq
-----END CERTIFICATE REQUEST-----

Binary file not shown.

Binary file not shown.

@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICkDCCAXgCAQAwSzEjMCEGCSqGSIb3DQEJARYUaGFyb29uNjEzOEBnbWFpbC5j
b20xFzAVBgNVBAMMDk1vaGFtZWQgTWVrYXd5MQswCQYDVQQGEwJBRTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnHqsyE7WfiVcE1Lpa4t4OVO6qlll2q
1djs0XG06R/dlDtIqv4940/XLj+hU93mzAcVvFW4DSIEdD3InM3+T6oMTjPu6meU
69h9ryaVkluQRrT/tdGI1EKO4MWGMe4MDIt7DqMhMfAcxTwekwdxdKaCEhaw3qnA
l/64AelY6URW1pHHJMA0VV7j+pE3jVNai+muMXPrhQ1VrOrV8FftpY3bEeRJR2Cl
T0tv0LhEMu4SfLnVWCzGQQC82hilDw3rH3ZDs8DFxF9agNVdwKlYamarh1dQXwRq
Yx2+sjY1/51r9L4VS+GAh9ECxz0e+43NpzfZ/N+mTeDYKDepaBwPQ6kCAwEAAaAA
MA0GCSqGSIb3DQEBCwUAA4IBAQB89OyLfywKT7ftmpEqCmgsmaJexb580q9w8wOk
1JhJkNV5ec+p1dnge2NZeJ4LGII/5wmPj1vANNW0GZdmJDgnC+2gg9toq1QLCAsF
rW7/LMpgAoEH+P5bhrHV9RRv6BQi0ZmN0apBHjp/pqZfm2Cl5jQPEWjUEf2tIF4l
LSKdok6IPO9n4Fgyk0XdUNSEhgVhsLtZkGiXnkI1YovKDnupTFYPXMLp103bc9zP
xDxwscvOysNDijlzZAkJPg2z8NrJIRDrKvLRHzxQwZ/1LHVB/51bp/1iyks3vOjh
qw5XVsrtGAjCjU9md7q3XkPSyKzhK9UqPdOxdvl1OY0KKIIY
-----END CERTIFICATE REQUEST-----

@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICkDCCAXgCAQAwSzEjMCEGCSqGSIb3DQEJARYUaGFyb29uNjEzOEBnbWFpbC5j
b20xFzAVBgNVBAMMDk1vaGFtZWQgTWVrYXd5MQswCQYDVQQGEwJBRTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnHqsyE7WfiVcE1Lpa4t4OVO6qlll2q
1djs0XG06R/dlDtIqv4940/XLj+hU93mzAcVvFW4DSIEdD3InM3+T6oMTjPu6meU
69h9ryaVkluQRrT/tdGI1EKO4MWGMe4MDIt7DqMhMfAcxTwekwdxdKaCEhaw3qnA
l/64AelY6URW1pHHJMA0VV7j+pE3jVNai+muMXPrhQ1VrOrV8FftpY3bEeRJR2Cl
T0tv0LhEMu4SfLnVWCzGQQC82hilDw3rH3ZDs8DFxF9agNVdwKlYamarh1dQXwRq
Yx2+sjY1/51r9L4VS+GAh9ECxz0e+43NpzfZ/N+mTeDYKDepaBwPQ6kCAwEAAaAA
MA0GCSqGSIb3DQEBCwUAA4IBAQB89OyLfywKT7ftmpEqCmgsmaJexb580q9w8wOk
1JhJkNV5ec+p1dnge2NZeJ4LGII/5wmPj1vANNW0GZdmJDgnC+2gg9toq1QLCAsF
rW7/LMpgAoEH+P5bhrHV9RRv6BQi0ZmN0apBHjp/pqZfm2Cl5jQPEWjUEf2tIF4l
LSKdok6IPO9n4Fgyk0XdUNSEhgVhsLtZkGiXnkI1YovKDnupTFYPXMLp103bc9zP
xDxwscvOysNDijlzZAkJPg2z8NrJIRDrKvLRHzxQwZ/1LHVB/51bp/1iyks3vOjh
qw5XVsrtGAjCjU9md7q3XkPSyKzhK9UqPdOxdvl1OY0KKIIY
-----END CERTIFICATE REQUEST-----

@ -0,0 +1,8 @@
{\rtf1\ansi\ansicpg1252\cocoartf2513
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\paperw11900\paperh16840\margl1440\margr1440\vieww10800\viewh8400\viewkind0
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\partightenfactor0
\f0\fs24 \cf0 Hmg54321}

Binary file not shown.

Binary file not shown.

@ -0,0 +1,17 @@
package io.flutter.plugins.firebasemessaging;
import android.content.Intent;
import com.google.firebase.messaging.RemoteMessage;
public class CustomFlutterFirebaseMessagingService extends FlutterFirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage.getData().containsKey("is_call")) {
Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
startActivity(intent);
super.onMessageReceived(remoteMessage);
} else
super.onMessageReceived(remoteMessage);
}
}

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r</string>
<key>API_KEY</key>
<string>AIzaSyA_6ayGCk4fly7o7eTVBrj9kuHBYHMAOfs</string>
<key>GCM_SENDER_ID</key>
<string>864393916058</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.cloud.diplomaticquarterapp</string>
<key>PROJECT_ID</key>
<string>diplomaticquarter-d2385</string>
<key>STORAGE_BUCKET</key>
<string>diplomaticquarter-d2385.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:864393916058:ios:13f787bbfe6051f8b97923</string>
<key>DATABASE_URL</key>
<string>https://diplomaticquarter-d2385.firebaseio.com</string>
</dict>
</plist>

@ -0,0 +1,17 @@
package io.flutter.plugins.firebasemessaging;
import android.content.Intent;
import com.google.firebase.messaging.RemoteMessage;
public class CustomFlutterFirebaseMessagingService extends FlutterFirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage.getData().containsKey("is_call")) {
Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
startActivity(intent);
super.onMessageReceived(remoteMessage);
} else
super.onMessageReceived(remoteMessage);
}
}

@ -23,10 +23,11 @@ if (flutterVersionName == null) {
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 30
compileSdkVersion 28
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
@ -40,17 +41,28 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.cloud.diplomaticquarterapp"
minSdkVersion 21
targetSdkVersion 30
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
}
buildTypes {
debug {}
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
staging {
// Specifies a sorted list of fallback build types that the
// plugin should try to use when a dependency does not include a
// "staging" build type. You may specify as many fallbacks as you
// like, and the plugin selects the first build type that's
// available in the dependency.
matchingFallbacks = ['debug', 'qa', 'release']
}
}
}
@ -60,4 +72,22 @@ flutter {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.google.firebase:firebase-messaging:20.3.0"
implementation 'pub.devrel:easypermissions:0.4.0'
implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0'
implementation 'com.google.guava:guava:27.0.1-android'
// Dependency on local binaries
implementation fileTree(dir: 'libs', include: ['*.jar'])
// Dependency on a remote binary
// implementation 'com.example.android:app-magic:12.3'
// Native Dependency
implementation "org.jetbrains.anko:anko-commons:0.10.4"
implementation 'com.github.kittinunf.fuel:fuel:2.3.0' //for JVM
implementation 'com.github.kittinunf.fuel:fuel-android:2.3.0'
implementation 'com.google.android.gms:play-services-location:17.1.0'//for Android
}

@ -0,0 +1,42 @@
{
"project_info": {
"project_number": "815750722565",
"firebase_url": "https://api-project-815750722565.firebaseio.com",
"project_id": "api-project-815750722565",
"storage_bucket": "api-project-815750722565.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063",
"android_client_info": {
"package_name": "com.cloud.diplomaticquarterapp"
}
},
"oauth_client": [
{
"client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"
}

@ -0,0 +1,6 @@
#Sun Sep 20 09:53:06 EEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

172
android/app/gradlew vendored

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

@ -0,0 +1,8 @@
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Sun Sep 20 09:53:03 EEST 2020
sdk.dir=/Users/erababah/Library/Android/sdk

@ -5,43 +5,99 @@
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<!-- Wifi Permissions-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- Detect Reboot Permission -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:name="io.flutter.app.FlutterApplication"
android:label="diplomaticquarterapp"
android:icon="@mipmap/ic_launcher">
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true"
android:label="diplomaticquarterapp">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme" />
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
</intent-filter>
</receiver>
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
<!-- Geofencing -->
<service android:name=".geofence.GeofenceTransitionsJobIntentService" android:exported="true" android:permission="android.permission.BIND_JOB_SERVICE" />
<receiver android:name=".geofence.GeofenceBroadcastReceiver" android:enabled="true" android:exported="true" />
<receiver android:name=".geofence.GeofencingRebootBroadcastReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCmevVlr2Bh-c8W1VUzo8gt8JRY7n5PANw"/>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
</manifest>

@ -1,6 +1,23 @@
package com.cloud.diplomaticquarterapp
import android.os.Bundle
import android.util.Log
import androidx.annotation.NonNull;
import com.cloud.diplomaticquarterapp.utils.FlutterText
import com.cloud.diplomaticquarterapp.utils.PlatformBridge
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterFragmentActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
// Create Flutter Platform Bridge
PlatformBridge(flutterEngine.dartExecutor.binaryMessenger, this).create()
class MainActivity: FlutterActivity() {
}
}
override fun onResume() {
super.onResume()
}
}

@ -0,0 +1,56 @@
package com.cloud.diplomaticquarterapp.geofence
import com.google.android.gms.location.Geofence
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
class GeoZoneModel {
var GEOF_ID:Int = 0
var Radius:Int = 0
var Type:Int = 0
var ProjectID:Int = 0
var Description:String? = null
var DescriptionN:String? = null
var Latitude:String? = null
var Longitude:String? = null
var ImageURL:String? = null
var IsCity:String? = null
fun identifier():String{
return "$GEOF_ID" + "_hmg"
}
fun message():String{
return Description ?: "nil"
}
fun listFrom(jsonString: String) : List<GeoZoneModel>{
val type = object : TypeToken<List<GeoZoneModel?>?>() {}.getType()
return Gson().fromJson(jsonString, type)
}
fun toGeofence() : Geofence?{
if (!Latitude.isNullOrEmpty() && !Longitude.isNullOrEmpty() && Radius > 50) {
val lat = Latitude!!.trim().toDoubleOrNull()
val long = Longitude!!.trim().toDoubleOrNull()
val rad = Radius.toFloat()
if(lat != null && long != null){
return Geofence.Builder()
.setRequestId(identifier())
.setCircularRegion(
lat,
long,
rad
)
.setTransitionTypes(GeofenceTransition.ENTER_EXIT.value)
// .setNotificationResponsiveness(0)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build()
}
}
return null
}
}

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

@ -0,0 +1,34 @@
package com.cloud.diplomaticquarterapp.geofence
import android.content.Context
import com.cloud.diplomaticquarterapp.R
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.location.GeofenceStatusCodes
object GeofenceErrorMessages {
fun getErrorString(context: Context, e: Exception): String {
return if (e is ApiException) {
getErrorString(context, e.statusCode)
} else {
context.resources.getString(R.string.geofence_unknown_error)
}
}
fun getErrorString(context: Context, errorCode: Int): String {
val resources = context.resources
return when (errorCode) {
GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE ->
resources.getString(R.string.geofence_not_available)
GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES ->
resources.getString(R.string.geofence_too_many_geofences)
GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS ->
resources.getString(R.string.geofence_too_many_pending_intents)
else -> resources.getString(R.string.geofence_unknown_error)
}
}
}

@ -0,0 +1,106 @@
/*
* Copyright (c) 2018 Razeware LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Notwithstanding the foregoing, you may not use, copy, modify, merge, publish,
* distribute, sublicense, create a derivative work, and/or sell copies of the
* Software in any work that is designed, intended, or marketed for pedagogical or
* instructional purposes related to programming, coding, application development,
* or information technology. Permission for such use, copying, modification,
* merger, publication, distribution, sublicensing, creation of derivative works,
* or sale is expressly withheld.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.cloud.diplomaticquarterapp.geofence
import android.content.Context
import android.content.Intent
import android.location.Location
import android.util.Log
import androidx.core.app.JobIntentService
import com.cloud.diplomaticquarterapp.utils.API
import com.cloud.diplomaticquarterapp.utils.httpPost
import com.cloud.diplomaticquarterapp.utils.sendNotification
import com.github.kittinunf.fuel.core.extensions.jsonBody
import com.github.kittinunf.fuel.core.isSuccessful
import com.github.kittinunf.fuel.httpPost
import com.google.android.gms.location.Geofence
import com.google.android.gms.location.GeofencingEvent
import com.google.gson.Gson
class GeofenceTransitionsJobIntentService : JobIntentService() {
companion object {
private const val LOG_TAG = "GeoTrIntentService"
private const val JOB_ID = 573
fun enqueueWork(context: Context, intent: Intent) {
enqueueWork(
context,
GeofenceTransitionsJobIntentService::class.java, JOB_ID,
intent)
}
}
override fun onHandleWork(intent: Intent) {
val geofencingEvent = GeofencingEvent.fromIntent(intent)
if (geofencingEvent.hasError()) {
val errorMessage = GeofenceErrorMessages.getErrorString(this, geofencingEvent.errorCode)
Log.e(LOG_TAG, errorMessage)
return
}
if (geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition));
}
}
private fun handleEvent(triggerGeofences: List<Geofence>, location:Location, transition:GeofenceTransition) {
val hmg = HMG_Geofence.shared(this)
hmg.getPatientID()?.let { patientId ->
hmg.getActiveGeofences({ activeGeofences ->
triggerGeofences.forEach { geofence ->
// Extract PointID from 'geofence.requestId' and find from active geofences
val pointID = activeGeofences.firstOrNull {it == geofence.requestId}?.split('_')?.first()
if(!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null){
val body = mapOf(
"PointsID" to pointID.toIntOrNull(),
"GeoType" to transition.value,
"PatientID" to patientId
)
httpPost<Map<String,Any>>(API.LOG_GEOFENCE, body, { response ->
sendNotification(this, transition.named(), geofence.requestId, "Notified to server.😎")
},{ exception ->
sendNotification(this, transition.named(), geofence.requestId, "Failed to notify server.😔")
})
}
}
},null)
}
}
}

@ -0,0 +1,27 @@
package com.cloud.diplomaticquarterapp.geofence
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Message
import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence
import com.cloud.diplomaticquarterapp.utils.HMGUtils
class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){
override fun onReceive(context: Context, intent: Intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.action)) {
val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE)
pref.edit().putString("REBOOT_DETECTED","YES").apply()
HMG_Geofence.shared(context).unRegisterAll { status, exception ->
val geoZones = HMGUtils.getGeoZonesFromPreference(context)
HMG_Geofence.shared(context).register(geoZones)
}
}
}
}

@ -0,0 +1,165 @@
package com.cloud.diplomaticquarterapp.geofence
import android.Manifest
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import androidx.core.content.ContextCompat
import com.google.android.gms.location.Geofence
import com.google.android.gms.location.GeofencingClient
import com.google.android.gms.location.GeofencingRequest
import com.google.android.gms.location.LocationServices
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
enum class GeofenceTransition(val value: Int) {
ENTER(1),
EXIT(2),
ENTER_EXIT((ENTER.value or EXIT.value)),
DWELL(4);
companion object {
fun fromInt(value: Int) = GeofenceTransition.values().first { it.value == value }
}
fun named():String{
if (value == 1)return "Enter"
if (value == 2)return "Exit"
if (value == (ENTER.value or EXIT.value))return "Enter or Exit"
if (value == 4)return "dWell"
return "unknown"
}
}
const val PREFS_STORAGE = "FlutterSharedPreferences"
const val PREF_KEY_SUCCESS = "HMG_GEOFENCE_SUCCESS"
const val PREF_KEY_FAILED = "HMG_GEOFENCE_FAILED"
const val PREF_KEY_HMG_ZONES = "flutter.hmg-geo-fences"
class HMG_Geofence {
// https://developer.android.com/training/location/geofencing#java
private lateinit var context: Context
private lateinit var preferences:SharedPreferences
private val gson = Gson()
private lateinit var geofencingClient:GeofencingClient
private val geofencePendingIntent: PendingIntent by lazy {
val intent = Intent(context, GeofenceBroadcastReceiver::class.java)
PendingIntent.getBroadcast(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT)
}
companion object{
var instance: HMG_Geofence? = null
fun shared(context: Context) : HMG_Geofence {
if (instance == null) {
instance = HMG_Geofence()
instance?.context = context
instance?.geofencingClient = LocationServices.getGeofencingClient(context)
instance?.preferences = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE)
}
return instance!!
}
}
fun register(geoZones: List<GeoZoneModel>){
if (geoZones.isEmpty())
return
fun buildGeofencingRequest(geofences: List<Geofence>): GeofencingRequest {
return GeofencingRequest.Builder()
.setInitialTrigger(0)
.addGeofences(geofences)
.build()
}
getActiveGeofences({ active ->
val geofences = mutableListOf<Geofence>()
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 {
saveActiveGeofence(geofences.map { it.requestId }, listOf())
}
.addOnFailureListener {
print(it.localizedMessage)
}
}
},null)
}
fun unRegisterAll(completion: (status: Boolean, exception:Exception?) -> Unit){
getActiveGeofences({ success ->
val mList = success.toMutableList()
mList.add("12345")
geofencingClient
.removeGeofences(success)
.addOnSuccessListener {
completion(true, null)
}
.addOnFailureListener {
completion(false, it)
}
removeActiveGeofences()
}, { failed ->
// Nothing to do with failed geofences.
})
}
fun saveActiveGeofence(success: List<String>, failed: List<String>){
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<String>) -> Unit, failure: ((failed: List<String>) -> Unit)?){
val type = object : TypeToken<List<String?>?>() {}.type
val jsonSuccess = preferences.getString(PREF_KEY_SUCCESS, "[]")
val success = gson.fromJson<List<String>>(jsonSuccess, type)
success(success)
if(failure != null){
val jsonFailure = preferences.getString(PREF_KEY_FAILED, "[]")
val failed = gson.fromJson<List<String>>(jsonFailure, type)
failure(failed)
}
}
private fun checkPermission() : Boolean{
return ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
fun getPatientID():Int?{
val profileJson = preferences.getString("flutter.imei-user-data", "{}")
val type = object : TypeToken<Map<String?, Any?>?>() {}.type
return gson.fromJson<Map<String?, Any?>?>(profileJson,type)
?.get("PatientID")
.toString()
.toDoubleOrNull()
?.toInt()
}
}

@ -0,0 +1,172 @@
package com.cloud.diplomaticquarterapp.hmgwifi
import android.content.Context
import android.net.ConnectivityManager
import android.net.wifi.WifiConfiguration
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.os.Build
import android.util.Log
import android.widget.Toast
import com.cloud.diplomaticquarterapp.MainActivity
import com.cloud.diplomaticquarterapp.utils.FlutterText
import com.cloud.diplomaticquarterapp.utils.HMGUtils
class HMG_Guest(context: MainActivity) {
private var wifiManager: WifiManager? = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager?
private var connectivityManager: ConnectivityManager? = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
private var context = context
private val TAG = "HMG_Guest"
private val TEST = false
private var SSID = """"HMG-MobileApp""""
private lateinit var completionListener: ((status: Boolean, message: String) -> Unit)
fun completionOnUiThread(status: Boolean, message: String){
completionListener(status, message)
}
/*
* 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) {
wifiManager?.let { wm ->
completionListener = completion
if (!wm.isWifiEnabled){
wm.isWifiEnabled = true
HMGUtils.popFlutterText(context,"enablingWifi");
HMGUtils.timer(2000,false){
connect()
}
}else{
connect()
}
}
}
private fun connect(){
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
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
conf.networkId = ssidToNetworkId(SSID)
val wm = wifiManager!!
if (conf.networkId == -1) {
wm.addNetwork(conf)
} else {
Log.v(TAG, "WiFi found - updating it.\n")
wm.updateNetwork(conf)
}
conf.networkId = ssidToNetworkId(SSID)
Log.d(TAG, "Network ID: ${conf.networkId}")
val networkIdToConnect = conf.networkId
if (networkIdToConnect >= 0) {
Log.v(TAG, "Start connecting to $SSID Wifi...")
// We disable the network before connecting, because if this was the last connection before
// a disconnect(), this will not reconnect.
wm.disableNetwork(networkIdToConnect)
val result = wm.enableNetwork(networkIdToConnect, true)
if(result){
HMGUtils.timer(8000,false){
if(wm.getConnectionInfo().getSSID() == SSID){
completionOnUiThread(true, "successConnectingHmgNetwork")
}else{
errorConnecting()
}
}
}else{
errorConnecting()
}
}else{
Log.v(TAG, "Cannot connect to $SSID network")
errorConnecting()
}
}
private fun errorConnecting(){
completionOnUiThread(false, "errorConnectingHmgNetwork")
}
// If CompileSDK is greater and equals to APILevel 29
private fun connectNewer(wm:WifiManager){
// 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)
}
/**
* 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.
*/
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
}
}

@ -0,0 +1,110 @@
package com.cloud.diplomaticquarterapp.hmgwifi
import android.annotation.SuppressLint
import com.cloud.diplomaticquarterapp.utils.API
import com.cloud.diplomaticquarterapp.MainActivity
import com.cloud.diplomaticquarterapp.utils.FlutterText
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 = false
private var context = flutterMainActivity;
private lateinit var completionListener: ((status: Boolean, message: String) -> Unit)
private var SSID = "GUEST-POC"
private var USER_NAME = ""
private var PASSWORD = ""
fun completionOnUiThread(status: Boolean, message: String){
completionListener(status, message)
// context.runOnUiThread {
//
// FlutterText.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(patientId: String, completion: (status: Boolean, message: String) -> Unit): HMG_Internet {
completionListener = completion
getWifiCredentials(patientId) {
WPA(context,SSID).connect(USER_NAME,PASSWORD) { 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("<title>success</title>", true)
completion(have)
},failure = {
completion(false)
})
}
}
private fun getWifiCredentials(patientId:String, success: (() -> Unit)){
if (TEST){
SSID = "GUEST-POC"
USER_NAME = "0696"
PASSWORD = "0000"
success()
return
}
val jsonBody = """{"PatientID":$patientId}"""
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")){
USER_NAME = object_.getString("UserName")
PASSWORD = object_.getString("Password")
success()
}else{
completionOnUiThread(false, "somethingWentWrong")
}
}
}
}
},failure = { error ->
completionOnUiThread(false, "somethingWentWrong" )
})
}
}
}

@ -0,0 +1,105 @@
package com.cloud.diplomaticquarterapp.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.cloud.diplomaticquarterapp.MainActivity
import com.cloud.diplomaticquarterapp.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
}
}

@ -0,0 +1,11 @@
package com.cloud.diplomaticquarterapp.utils
class API {
companion object{
private val BASE = "https://uat.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"
}
}

@ -0,0 +1,36 @@
package com.cloud.diplomaticquarterapp.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"
}
}
})
}
}
}

@ -0,0 +1,160 @@
package com.cloud.diplomaticquarterapp.utils
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.widget.Toast
import androidx.annotation.Nullable
import androidx.core.app.NotificationCompat
import androidx.core.app.TaskStackBuilder
import com.cloud.diplomaticquarterapp.BuildConfig
import com.cloud.diplomaticquarterapp.MainActivity
import com.cloud.diplomaticquarterapp.R
import com.cloud.diplomaticquarterapp.geofence.GeoZoneModel
import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE
import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_HMG_ZONES
import com.github.kittinunf.fuel.core.extensions.jsonBody
import com.github.kittinunf.fuel.httpPost
import com.google.android.gms.location.Geofence
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import io.flutter.plugin.common.MethodChannel
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.util.*
import kotlin.concurrent.timerTask
class HMGUtils {
companion object{
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 getGeoZonesFromPreference(context: Context):List<GeoZoneModel>{
val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE)
val json = pref.getString(PREF_KEY_HMG_ZONES,"[]")
val geoZones = GeoZoneModel().listFrom(json)
return geoZones
}
}
}
private fun Timer.schedule(timerTask: TimerTask) {
}
private const val NOTIFICATION_CHANNEL_ID = BuildConfig.APPLICATION_ID + ".channel"
fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, message:String?) {
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
&& notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID) == null) {
val name = context.getString(R.string.app_name)
val channel = NotificationChannel(NOTIFICATION_CHANNEL_ID,
name,
NotificationManager.IMPORTANCE_DEFAULT)
notificationManager.createNotificationChannel(channel)
}
val intent = Intent(context, MainActivity::class.java)
val stackBuilder = TaskStackBuilder.create(context)
.addParentStack(MainActivity::class.java)
.addNextIntent(intent)
val notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT)
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(notificationPendingIntent)
.setAutoCancel(true)
.setContentTitle(title)
subtitle.let { notification.setContentText(it) }
message.let { notification.setSubText(it) }
notificationManager.notify(getUniqueId(), notification.build())
}
private fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt())
fun isJSONValid(jsonString: String?): Boolean {
try { JSONObject(jsonString) } catch (ex: JSONException) {
try { JSONArray(jsonString) } catch (ex1: JSONException) {
return false
}
}
return true
}
class HTTPResponse<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
})
}
}

@ -0,0 +1,351 @@
//package com.cloud.diplomaticquarterapp.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.cloud.diplomaticquarterapp.utils.API
//import com.cloud.diplomaticquarterapp.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("<TITLE>Success</TITLE>", 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
// }
//
//}

@ -0,0 +1,127 @@
package com.cloud.diplomaticquarterapp.utils
import android.content.Context
import android.net.wifi.WifiManager
import android.util.Log
import com.cloud.diplomaticquarterapp.MainActivity
import com.cloud.diplomaticquarterapp.hmgwifi.HMG_Guest
import com.cloud.diplomaticquarterapp.hmgwifi.HMG_Internet
import com.cloud.diplomaticquarterapp.geofence.GeoZoneModel
import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
class PlatformBridge(binaryMessenger: BinaryMessenger, flutterMainActivity: MainActivity) {
private var binaryMessenger = binaryMessenger
private var mainActivity = flutterMainActivity
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"
}
fun create(){
channel = MethodChannel(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{
result.notImplemented()
}
}
val res = channel.invokeMethod("localizedValue","errorConnectingHmgNetwork")
print(res)
}
private fun connectHMGInternetWifi(methodCall: MethodCall, result: MethodChannel.Result){
(methodCall.arguments as ArrayList<*>).let {
require(it.size > 0 && (it[0] is String),lazyMessage = {
"Missing or invalid arguments (Must have one argument 'String at 0'"
})
val patientId = it[0].toString()
HMG_Internet(mainActivity)
.connectToHMGGuestNetwork(patientId){ 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){
HMG_Guest(mainActivity).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(geoZones)
}
}
override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) { print(result) }
override fun notImplemented() { print(result) }
})
}
private fun unRegisterHmgGeofences(methodCall: MethodCall, result: MethodChannel.Result) {
HMG_Geofence.shared(mainActivity).unRegisterAll { status, exception ->
if(status)
result.success(true)
else
result.error("101", exception?.localizedMessage, exception);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@drawable/*,@raw/slow_spring_board" />

@ -0,0 +1,16 @@
<resources>
<string name="app_name">HMG Patient App</string>
<string name="geofence_unknown_error">
Unknown error: the Geofence service is not available now.
</string>
<string name="geofence_not_available">
Geofence service is not available now. Go to Settings>Location>Mode and choose High accuracy.
</string>
<string name="geofence_too_many_geofences">
Your app has registered too many geofences.
</string>
<string name="geofence_too_many_pending_intents">
You have provided too many PendingIntents to the addGeofences() call.
</string>
</resources>

@ -6,8 +6,9 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath 'com.android.tools.build:gradle:4.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.2'
}
}

@ -0,0 +1,40 @@
{
"project_info": {
"project_number": "864393916058",
"firebase_url": "https://diplomaticquarter-d2385.firebaseio.com",
"project_id": "diplomaticquarter-d2385",
"storage_bucket": "diplomaticquarter-d2385.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:864393916058:android:5b5a65cd6d8c18b4b97923",
"android_client_info": {
"package_name": "com.cloud.diplomaticquarterapp"
}
},
"oauth_client": [
{
"client_id": "864393916058-tphjrn8j39ntevt32ekcvmll8aue7qql.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyBdV3mos1BPhUzNKCj2KANJtiO3o2zh9IM"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "864393916058-tphjrn8j39ntevt32ekcvmll8aue7qql.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

@ -1,4 +1,5 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
org.gradle.jvmargs=-Xmx4608m

@ -1,6 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
#Thu Sep 03 16:26:30 EEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

@ -0,0 +1 @@
include ':app'

File diff suppressed because one or more lines are too long

Binary file not shown.

@ -0,0 +1,93 @@
Copyright (c) 2014-2015 Wei Huang (wweeiihhuuaanngg@gmail.com)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save