diff --git a/projects/CitiSim/Android/.gitignore b/projects/CitiSim/Android/.gitignore new file mode 100644 index 00000000..2fd41868 --- /dev/null +++ b/projects/CitiSim/Android/.gitignore @@ -0,0 +1,83 @@ +# Built application files +*.apk +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ +release/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries + +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml + +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml + +# Keystore files +*.jks +*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +lint/reports/ diff --git a/projects/CitiSim/Android/app/.gitignore b/projects/CitiSim/Android/app/.gitignore new file mode 100755 index 00000000..2fd41868 --- /dev/null +++ b/projects/CitiSim/Android/app/.gitignore @@ -0,0 +1,83 @@ +# Built application files +*.apk +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ +release/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries + +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml + +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml + +# Keystore files +*.jks +*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +lint/reports/ diff --git a/projects/CitiSim/Android/app/.idea/codeStyles/Project.xml b/projects/CitiSim/Android/app/.idea/codeStyles/Project.xml new file mode 100755 index 00000000..30aa626c --- /dev/null +++ b/projects/CitiSim/Android/app/.idea/codeStyles/Project.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/CitiSim/Android/app/.idea/misc.xml b/projects/CitiSim/Android/app/.idea/misc.xml new file mode 100755 index 00000000..c72ad176 --- /dev/null +++ b/projects/CitiSim/Android/app/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/CitiSim/Android/app/.idea/runConfigurations.xml b/projects/CitiSim/Android/app/.idea/runConfigurations.xml new file mode 100755 index 00000000..7f68460d --- /dev/null +++ b/projects/CitiSim/Android/app/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/projects/CitiSim/Android/app/build.gradle b/projects/CitiSim/Android/app/build.gradle new file mode 100755 index 00000000..b5d5a6ac --- /dev/null +++ b/projects/CitiSim/Android/app/build.gradle @@ -0,0 +1,33 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "ro.beia.citisimR" + minSdkVersion 15 + targetSdkVersion 28 + versionCode 4 + versionName "1.0.2" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.google.android.gms:play-services-location:16.0.0' + implementation 'com.google.maps.android:android-maps-utils:0.5+' ///////////////// + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation 'com.google.android.gms:play-services-maps:16.1.0' + implementation 'com.android.volley:volley:1.1.1' + +} diff --git a/projects/CitiSim/Android/app/gradle/wrapper/gradle-wrapper.properties b/projects/CitiSim/Android/app/gradle/wrapper/gradle-wrapper.properties new file mode 100755 index 00000000..f8d70928 --- /dev/null +++ b/projects/CitiSim/Android/app/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed May 08 09:07:41 EEST 2019 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip diff --git a/projects/CitiSim/Android/app/gradlew b/projects/CitiSim/Android/app/gradlew new file mode 100755 index 00000000..cccdd3d5 --- /dev/null +++ b/projects/CitiSim/Android/app/gradlew @@ -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" "$@" diff --git a/projects/CitiSim/Android/app/gradlew.bat b/projects/CitiSim/Android/app/gradlew.bat new file mode 100755 index 00000000..f9553162 --- /dev/null +++ b/projects/CitiSim/Android/app/gradlew.bat @@ -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 diff --git a/projects/CitiSim/Android/app/proguard-rules.pro b/projects/CitiSim/Android/app/proguard-rules.pro new file mode 100755 index 00000000..f1b42451 --- /dev/null +++ b/projects/CitiSim/Android/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/projects/CitiSim/Android/app/src/androidTest/java/com/main/citisim/ExampleInstrumentedTest.java b/projects/CitiSim/Android/app/src/androidTest/java/com/main/citisim/ExampleInstrumentedTest.java new file mode 100755 index 00000000..e268ee1b --- /dev/null +++ b/projects/CitiSim/Android/app/src/androidTest/java/com/main/citisim/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.main.citisim; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.main.citisim", appContext.getPackageName()); + } +} diff --git a/projects/CitiSim/Android/app/src/main/AndroidManifest.xml b/projects/CitiSim/Android/app/src/main/AndroidManifest.xml new file mode 100755 index 00000000..82aa4db9 --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/AndroidManifest.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/CitiSim/Android/app/src/main/java/com/main/citisim/ChangePass.java b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/ChangePass.java new file mode 100755 index 00000000..aeab50c1 --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/ChangePass.java @@ -0,0 +1,95 @@ +package com.main.citisim; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import com.android.volley.AuthFailureError; +import com.android.volley.NoConnectionError; +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.Response; +import com.android.volley.TimeoutError; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.JsonObjectRequest; +import com.android.volley.toolbox.StringRequest; +import com.android.volley.toolbox.Volley; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; + +public class ChangePass extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_change_pass); + + final EditText oldpass = (EditText) findViewById(R.id.oldPass); + final EditText newPass1 = (EditText) findViewById(R.id.newPass1); + final EditText newPass2 = (EditText) findViewById(R.id.newPass2); + + Button confirm = (Button)findViewById(R.id.confirm); + + confirm.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(newPass1.getText().toString().equals(newPass2.getText().toString())) { + /////////// + HashMap data = new HashMap(); + data.put("currentPassword", oldpass.getText().toString()); + data.put("newPassword", newPass1.getText().toString()); + + String url = getResources().getString(R.string.api_server)+"/api/account/change-password"; + + JsonObjectRequest jsonObjectRequest = new JsonObjectRequest + (Request.Method.POST, url, new JSONObject(data), new Response.Listener() { + + @Override + public void onResponse(JSONObject response) { + Toast.makeText(getApplicationContext(),"Completed",Toast.LENGTH_SHORT).show(); + } + }, new Response.ErrorListener() { + + @Override + public void onErrorResponse(VolleyError error) { + // TODO: Handle error + if(error instanceof TimeoutError || error instanceof NoConnectionError){ + Toast.makeText(getApplicationContext(),"no internet connection",Toast.LENGTH_SHORT).show(); + }else if(error instanceof AuthFailureError){ + Toast.makeText(getApplicationContext(),error.toString(),Toast.LENGTH_SHORT).show(); + + } + else { + Toast.makeText(getApplicationContext(),error.toString(),Toast.LENGTH_SHORT).show(); + } + } + } + + ) { + @Override + public java.util.Map getHeaders() { + HashMap params = new HashMap<>(); + params.put("Authorization", "Bearer " + new Session(getApplication()).getAuthToken()); + return params; + } + }; + + // Access the RequestQueue through your singleton class. + MyVolleyQueue.getInstance(getApplicationContext()).addToRequestQueue(jsonObjectRequest); + /////////// + } else { + Toast.makeText(getApplicationContext(), "The password and the confirmation should match.", Toast.LENGTH_LONG).show(); + } + } + }); + + } + +} diff --git a/projects/CitiSim/Android/app/src/main/java/com/main/citisim/MainActivity.java b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/MainActivity.java new file mode 100755 index 00000000..b22006f9 --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/MainActivity.java @@ -0,0 +1,153 @@ +package com.main.citisim; + +import android.app.Dialog; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.volley.AuthFailureError; +import com.android.volley.NoConnectionError; +import com.android.volley.Request; +import com.android.volley.Response; +import com.android.volley.TimeoutError; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.JsonObjectRequest; +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GoogleApiAvailability; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; + +public class MainActivity extends AppCompatActivity { + + private static final String TAG = "MainActivity"; + private static final int ERROR_DIALOG_REQUEST = 9001; + public static String token; + + private void openRegisterPage() { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getResources().getString(R.string.api_server) + "/#/register"))); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + Button addBtn = (Button) findViewById(R.id.addBtn); + Button register= ( Button) findViewById(R.id.register); + + register.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + openRegisterPage(); + } + }); + + + + addBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + EditText username = (EditText) findViewById(R.id.username); + EditText password = (EditText) findViewById(R.id.password); + final TextView okmsg = (TextView) findViewById(R.id.okmsg); + + + + + //------LOGARE------- + okmsg.setText(""); + HashMap data = new HashMap(); + data.put("username", username.getText().toString()); + data.put("password", password.getText().toString()); + data.put("rememberMe", true); + + String url = getResources().getString(R.string.api_server)+"/api/authenticate"; + + JsonObjectRequest jsonObjectRequest = new JsonObjectRequest + (Request.Method.POST, url, new JSONObject(data), new Response.Listener() { + + @Override + public void onResponse(JSONObject response) { + okmsg.setText("Authentication succesful"); + try { + // Procesare continut raspuns + token=response.getString("id_token"); + Session session = new Session(getApplicationContext()); + session.setAuthToken(token); + // Procesare raspuns + openMap(); + } catch (JSONException e) { + Toast.makeText(getApplicationContext(), "Invalid response from server.", Toast.LENGTH_LONG).show(); + } + } + }, new Response.ErrorListener() { + + @Override + public void onErrorResponse(VolleyError error) { + // TODO: Handle error + if(error instanceof TimeoutError || error instanceof NoConnectionError){ + Toast.makeText(getApplicationContext(),error.toString(),Toast.LENGTH_SHORT).show(); + }else if(error instanceof AuthFailureError){ + Toast.makeText(getApplicationContext(),"wronguser/pass",Toast.LENGTH_SHORT).show(); + } + else{ + Toast.makeText(getApplicationContext(),"????",Toast.LENGTH_SHORT).show(); + } + } + }); + +// Access the RequestQueue through your singleton class. + MyVolleyQueue.getInstance(getApplicationContext()).addToRequestQueue(jsonObjectRequest); + + + //------LOGARE-------// + } + }); + } + + public void openRegister(){ + Intent intent = new Intent(this, Register.class); + startActivity(intent); + } + + public void openMap(){ + Intent intent = new Intent(this, MapActivity.class); + startActivity(intent); + } + + + public boolean isServicesOK(){ + Log.d(TAG,"isServicesOK: checking google services version"); + + int available = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(MainActivity.this); + + if(available == ConnectionResult.SUCCESS) { + Log.d(TAG,"isServicesOK: Google Play Services is working"); + return true; + } + else if(GoogleApiAvailability.getInstance().isUserResolvableError(available)) { + Log.d(TAG,"isServicesOK: a version error occured"); + Dialog dialog = GoogleApiAvailability.getInstance().getErrorDialog(MainActivity.this,available,ERROR_DIALOG_REQUEST); + dialog.show(); + }else { + Toast.makeText(this,"an error occured",Toast.LENGTH_SHORT).show(); + } + return false; + } + + + + + +} + diff --git a/projects/CitiSim/Android/app/src/main/java/com/main/citisim/MapActivity.java b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/MapActivity.java new file mode 100755 index 00000000..cdcc38ed --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/MapActivity.java @@ -0,0 +1,275 @@ +package com.main.citisim; + +import android.Manifest; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.location.Location; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.Toast; + +import com.android.volley.Request; +import com.android.volley.Response; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.JsonArrayRequest; +import com.google.android.gms.location.FusedLocationProviderClient; +import com.google.android.gms.location.LocationServices; +import com.google.android.gms.maps.CameraUpdateFactory; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.OnMapReadyCallback; +import com.google.android.gms.maps.SupportMapFragment; +import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.TileOverlayOptions; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.maps.android.heatmaps.HeatmapTileProvider; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class MapActivity extends AppCompatActivity implements OnMapReadyCallback { + + final HashMap info = new HashMap(); + + @Override + public void onMapReady(GoogleMap googleMap) { + mMap = googleMap; + + if (mLocationPermissionsGranted) { + getDeviceLocation(); + if (ActivityCompat.checkSelfPermission(this, + Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, + Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + Toast.makeText(getApplicationContext(), "Location permission not gruanteed.", Toast.LENGTH_LONG).show(); + return; + } + mMap.setMyLocationEnabled(true); + //mMap.getUiSettings(). different settings + + // Get the reports + getReports(); + } + + } + + private static final String TAG = "MapActivity"; + + private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION; + private static final String COURSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION; + private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234; + private static final float DEFAULT_ZOOM = 15f; + //vars + private Boolean mLocationPermissionsGranted = false; + private GoogleMap mMap; + private FusedLocationProviderClient mFusedLocationProviderClient; + + + public static double latitude; + public static double longitude; + + private HeatmapTileProvider mProvider; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_map); + + getLocationPermission(); + Button button2; + button2 = (Button) findViewById(R.id.button2); + button2.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + openNewReport(); + } + }); + + ImageButton settings; + settings = (ImageButton) findViewById(R.id.settings); + settings.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + openSettings(); + } + }); + + } + + + /////////////////////////////////////////////////////// + + + private void openSettings() { + Intent intent = new Intent(this, Settings.class); + startActivity(intent); + } + + + private void updateHeatMap(List list) { + // Create a heat map tile provider, passing it the latlngs of the police stations. + mProvider = new HeatmapTileProvider.Builder() + .data(list) + .build(); + + // Add a tile overlay to the map, using the heat map tile provider. + mMap.addTileOverlay(new TileOverlayOptions().tileProvider(mProvider)); + + } + + +//////////////////////////////////////////////////////////// + + + public void getReports() { + final String url = getResources().getString(R.string.api_server) + "/api/reports"; + + + final JsonArrayRequest getRequest = new JsonArrayRequest(Request.Method.GET, url, null, + new Response.Listener() { + @Override + public void onResponse(JSONArray response) { + ArrayList coordinates = new ArrayList<>(); + try { + for (int i = 0; i < response.length(); i++) { + JSONObject report = response.getJSONObject(i); + Double lat = Double.parseDouble(report.getString("latitude")); + Double lng = Double.parseDouble(report.getString("longitude")); + coordinates.add(new LatLng(lat, lng)); + } + updateHeatMap(coordinates); + + } catch (JSONException e) { + e.printStackTrace(); + } + } + }, + new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show(); + } + } + ) { + @Override + public java.util.Map getHeaders() { + HashMap params = new HashMap<>(); + params.put("Authorization", "Bearer " + new Session(getApplication()).getAuthToken()); + return params; + } + }; + + // add it to the RequestQueue + MyVolleyQueue.getInstance(getApplicationContext()).addToRequestQueue(getRequest); + } + + + public void openNewReport() { + Intent intent = new Intent(this, NewReport.class); + startActivity(intent); + } + + public void getDeviceLocation() { + mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this); + try { + if (mLocationPermissionsGranted) { + Task location = mFusedLocationProviderClient.getLastLocation(); + location.addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (task.isSuccessful()) { + Log.d(TAG, "onComplete: found location!"); + Location currentLocation = (Location) task.getResult(); + + moveCamera(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()), + DEFAULT_ZOOM); + + latitude = currentLocation.getLatitude(); + longitude = currentLocation.getLongitude(); + + + } else { + Log.d(TAG, "onComplete: current location is null"); + Toast.makeText(MapActivity.this, "unable to get current location", Toast.LENGTH_SHORT).show(); + } + } + }); + } + } catch (SecurityException e) { + Log.e(TAG, "getDeviceLocation: SecurityException: " + e.getMessage()); + } + } + + + private void moveCamera(LatLng latLng, float zoom) { + mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoom)); + } + + private void initMap() { + SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); + + mapFragment.getMapAsync(MapActivity.this); + } + + private void getLocationPermission() { + String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION}; + + if (ContextCompat.checkSelfPermission(this.getApplicationContext(), + FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { + if (ContextCompat.checkSelfPermission(this.getApplicationContext(), + COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { + mLocationPermissionsGranted = true; + initMap(); + } else { + ActivityCompat.requestPermissions(this, + permissions, + LOCATION_PERMISSION_REQUEST_CODE); + + } + } else { + ActivityCompat.requestPermissions(this, + permissions, + LOCATION_PERMISSION_REQUEST_CODE); + + } + + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + mLocationPermissionsGranted = false; + + switch (requestCode) { + case LOCATION_PERMISSION_REQUEST_CODE: { + if (grantResults.length > 0) { + for (int i = 0; i < grantResults.length; i++) { + if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { + mLocationPermissionsGranted = false; + return; + } + } + mLocationPermissionsGranted = true; + //initialize map + initMap(); + } + + } + + } + } + + +} diff --git a/projects/CitiSim/Android/app/src/main/java/com/main/citisim/MyVolleyQueue.java b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/MyVolleyQueue.java new file mode 100755 index 00000000..4e5be5d1 --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/MyVolleyQueue.java @@ -0,0 +1,61 @@ +package com.main.citisim; +import android.content.Context; +import android.graphics.Bitmap; +import android.util.LruCache; + +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.toolbox.ImageLoader; +import com.android.volley.toolbox.Volley; + +public class MyVolleyQueue { + private static MyVolleyQueue instance; + private RequestQueue requestQueue; + private ImageLoader imageLoader; + private static Context ctx; + + private MyVolleyQueue(Context context) { + ctx = context; + requestQueue = getRequestQueue(); + + imageLoader = new ImageLoader(requestQueue, + new ImageLoader.ImageCache() { + private final LruCache + cache = new LruCache(20); + + @Override + public Bitmap getBitmap(String url) { + return cache.get(url); + } + + @Override + public void putBitmap(String url, Bitmap bitmap) { + cache.put(url, bitmap); + } + }); + } + + public static synchronized MyVolleyQueue getInstance(Context context) { + if (instance == null) { + instance = new MyVolleyQueue(context); + } + return instance; + } + + public RequestQueue getRequestQueue() { + if (requestQueue == null) { + // getApplicationContext() is key, it keeps you from leaking the + // Activity or BroadcastReceiver if someone passes one in. + requestQueue = Volley.newRequestQueue(ctx.getApplicationContext()); + } + return requestQueue; + } + + public void addToRequestQueue(Request req) { + getRequestQueue().add(req); + } + + public ImageLoader getImageLoader() { + return imageLoader; + } +} \ No newline at end of file diff --git a/projects/CitiSim/Android/app/src/main/java/com/main/citisim/NewReport.java b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/NewReport.java new file mode 100755 index 00000000..943395b9 --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/NewReport.java @@ -0,0 +1,299 @@ +package com.main.citisim; + +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.os.Bundle; +import android.provider.MediaStore; +import android.support.v7.app.AppCompatActivity; +import android.util.Base64; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.Toast; + +import com.android.volley.AuthFailureError; +import com.android.volley.DefaultRetryPolicy; +import com.android.volley.NetworkResponse; +import com.android.volley.NoConnectionError; +import com.android.volley.Request; +import com.android.volley.Response; +import com.android.volley.TimeoutError; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.JsonObjectRequest; +/* +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +*/ +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class NewReport extends AppCompatActivity { + + //vars + private Button backToReports; + private ImageButton addImage; + private Button submitImage; + ImageView image; + private static final int PICK_IMAGE = 100; + Uri imageUri; + Bitmap image_bitmap; + EditText latitude; + EditText longitude; + EditText title; + final HashMap info = new HashMap(); + + private Uri buildURI(String url, Map params) { + + // build url with parameters. + Uri.Builder builder = Uri.parse(url).buildUpon(); + for (Map.Entry entry : params.entrySet()) { + builder.appendQueryParameter(entry.getKey(), entry.getValue()); + } + + return builder.build(); + } + + private void uploadImage(final Bitmap bitmap, final String url, Map query_params) { + + String full_url = buildURI(url, query_params).toString(); + + VolleyMultipartRequest volleyMultipartRequest = new VolleyMultipartRequest(Request.Method.POST, full_url, + new Response.Listener() { + @Override + public void onResponse(NetworkResponse response) { + try { + JSONObject jsonObject = new JSONObject(new String(response.data)); + Log.d("raspuns", response.data.toString()); + + } catch (JSONException e) { + e.printStackTrace(); + } + } + }, + new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + Toast.makeText(getApplicationContext(), "Failed to submit report: " + error.getMessage(), Toast.LENGTH_SHORT).show(); + NetworkResponse networkResponse = error.networkResponse; + if (networkResponse != null && networkResponse.data != null) { + String jsonError = new String(networkResponse.data); + Log.d("error_response", jsonError); + } + } + }) { + + @Override + public java.util.Map getHeaders() { + HashMap params = new HashMap<>(); + params.put("Authorization", "Bearer " + new Session(getApplication()).getAuthToken()); + return params; + } + + /* + * If you want to add more parameters with the image + * you can do it here + * here we have only one parameter with the image + * which is tags + * */ + @Override + protected Map getParams() throws AuthFailureError { + Map params = new HashMap<>(); + // params.put("tags", "ccccc"); add string parameters + return params; + } + + /* + *pass files using below method + * */ + @Override + protected Map getByteData() { + Map params = new HashMap<>(); + long imagename = System.currentTimeMillis(); + params.put("file", new DataPart(imagename + ".png", getFileDataFromDrawable(bitmap))); + return params; + } + }; + + + volleyMultipartRequest.setRetryPolicy(new DefaultRetryPolicy( + 0, + DefaultRetryPolicy.DEFAULT_MAX_RETRIES, + DefaultRetryPolicy.DEFAULT_BACKOFF_MULT)); + MyVolleyQueue.getInstance(getApplicationContext()).addToRequestQueue(volleyMultipartRequest); + } + + public byte[] getFileDataFromDrawable(Bitmap bitmap) { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream); + return byteArrayOutputStream.toByteArray(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_new_report); + + getUserInfo(); + + title = (EditText) findViewById(R.id.title); + + + image = (ImageView) findViewById(R.id.image); + // + image.setVisibility(View.INVISIBLE); + backToReports = (Button) findViewById(R.id.backToReports); + backToReports.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + openMap2(); + } + }); + + addImage = (ImageButton) findViewById(R.id.addImage); + addImage.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + openGallery(); + } + }); + + submitImage = (Button) findViewById(R.id.submitImage); + submitImage.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + + /*latitude.setText(Double.toString(MapActivity.latitude)); + longitude.setText(Double.toString(MapActivity.longitude)); +*/ + + + HashMap query_params = new HashMap(); + query_params.put("latitude", Double.toString(MapActivity.latitude)); + query_params.put("longitude", Double.toString(MapActivity.longitude)); + query_params.put("altitude", "0"); + query_params.put("userId", info.get("id").toString()); + // data.put("photoDescription","0"); + //data.put("photoPath","0"); + + //data.put("status","REPORT_CREATED"); + query_params.put("title", title.getText().toString()); + //data.put("id","0"); + query_params.put("date", "0"); + + + String url = getResources().getString(R.string.api_server) + "/api/reports"; + + submitImage.setEnabled(false); + + Toast.makeText(getApplicationContext(), "Submitting report...", Toast.LENGTH_LONG).show(); + uploadImage(image_bitmap, url, query_params); + + + } + }); + + + } + + + public void getUserInfo() { + final String url = getResources().getString(R.string.api_server) + "/api/account"; + + + final JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, url, null, + new Response.Listener() { + @Override + public void onResponse(JSONObject response) { + //firstName.setText(""+response.toString()); + try { + + info.put("id", response.getString("id")); + // Toast.makeText(NewReport.this, info.get("id").toString(), Toast.LENGTH_SHORT).show(); + + } catch (JSONException e) { + e.printStackTrace(); + + } + + Log.d("Response", response.toString()); + } + }, + new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show(); + Log.d("Error.Response", "??"); + } + } + ) { + @Override + public java.util.Map getHeaders() { + HashMap params = new HashMap<>(); + params.put("Authorization", "Bearer " + new Session(getApplication()).getAuthToken()); + return params; + } + }; + + // add it to the RequestQueue + MyVolleyQueue.getInstance(getApplicationContext()).addToRequestQueue(getRequest); + } + + + private void openGallery() { + Intent gallery = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI); + startActivityForResult(gallery, PICK_IMAGE); + } + + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK && requestCode == PICK_IMAGE) { + imageUri = data.getData(); + image.setImageURI(imageUri); + image.setVisibility(View.VISIBLE); + + Log.d("hau", "am ajuns aici"); + + //aici imaginea trebuie rotita + //aici imaginea trebuie rotita + //aici imaginea trebuie rotita + //aici imaginea trebuie rotita + + image_bitmap = null; + try { + image_bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + + } + + + public void openMap2() { + Intent intent = new Intent(this, MapActivity.class); + startActivity(intent); + } + + +} diff --git a/projects/CitiSim/Android/app/src/main/java/com/main/citisim/Register.java b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/Register.java new file mode 100755 index 00000000..264b9eb0 --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/Register.java @@ -0,0 +1,88 @@ +package com.main.citisim; + +import android.content.Intent; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import com.android.volley.AuthFailureError; +import com.android.volley.NoConnectionError; +import com.android.volley.Request; +import com.android.volley.Response; +import com.android.volley.TimeoutError; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.JsonObjectRequest; + +import org.json.JSONObject; + +import java.util.HashMap; + +public class Register extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_register); + + Button register = (Button) findViewById(R.id.registerButton); + + register.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + EditText firstName = (EditText) findViewById(R.id.editText_firstName); + EditText lastName = (EditText) findViewById(R.id.editText_lastName); + EditText email = (EditText) findViewById(R.id.editText_email); + EditText password = (EditText) findViewById(R.id.editText_password); + EditText repeatPassword = (EditText) findViewById(R.id.editText_repeatPassword); + + if(!password.getText().toString().equals( repeatPassword.getText().toString())){ + ///TODO: pop-up message "Password not ok" + Toast.makeText(getApplicationContext(),"Password not ok",Toast.LENGTH_SHORT).show(); + }else { + + + HashMap data = new HashMap(); + data.put("email", email.getText().toString()); + data.put("firstName", firstName.getText().toString()); + data.put("lastName", lastName.getText().toString()); + data.put("password", password.getText().toString()); + + + String url = getResources().getString(R.string.api_server) + "/api/register"; + + JsonObjectRequest jsonObjectRequest = new JsonObjectRequest + (Request.Method.POST, url, new JSONObject(data), new Response.Listener() { + @Override + public void onResponse(JSONObject response) { + Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_SHORT).show(); + openMain(); + } + }, new Response.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + // TODO: Handle error + if (error instanceof TimeoutError || error instanceof NoConnectionError) { + Toast.makeText(getApplicationContext(), "no internet connection", Toast.LENGTH_SHORT).show(); + } else if (error instanceof AuthFailureError) { + Toast.makeText(getApplicationContext(), "wronguser/pass", Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(getApplicationContext(),"???", Toast.LENGTH_SHORT).show(); + } + } + }); + + MyVolleyQueue.getInstance(getApplicationContext()).addToRequestQueue(jsonObjectRequest); + } + } + + }); + } + + public void openMain(){ + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + } +} diff --git a/projects/CitiSim/Android/app/src/main/java/com/main/citisim/Session.java b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/Session.java new file mode 100755 index 00000000..a5519217 --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/Session.java @@ -0,0 +1,25 @@ +package com.main.citisim; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +public class Session { + private SharedPreferences prefs; + final private String AUTH_TOKEN_KEY = "authToken"; + + + public Session(Context cntx) { + // TODO Auto-generated constructor stub + prefs = PreferenceManager.getDefaultSharedPreferences(cntx); + } + + public void setAuthToken(String token) { + prefs.edit().putString(AUTH_TOKEN_KEY, token).commit(); + } + + public String getAuthToken() { + String usename = prefs.getString(AUTH_TOKEN_KEY,""); + return usename; + } +} diff --git a/projects/CitiSim/Android/app/src/main/java/com/main/citisim/Settings.java b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/Settings.java new file mode 100755 index 00000000..a4e4d683 --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/Settings.java @@ -0,0 +1,113 @@ +package com.main.citisim; + +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.volley.Request; +import com.android.volley.Response; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.JsonObjectRequest; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; + +public class Settings extends AppCompatActivity { + + TextView email; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_settings); + + final TextView firstName; + final TextView lastName; + + Button changePass; + + + + + firstName=(TextView)findViewById(R.id.firstName); + lastName=(TextView)findViewById(R.id.lastName); + email=(TextView)findViewById(R.id.email); + changePass=(Button)findViewById(R.id.changePass); + + changePass.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + + openChangePass(); + + + + } + }); + + + /////////////////GETDATAFROMVOLLEY///////////////// + + getUserInfo(); + + /////////////////GETDATAFROMVOLLEY///////////////// + + } + + public void getUserInfo(){ + final String url = getResources().getString(R.string.api_server) + "/api/account"; + + + JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, url, null, + new Response.Listener() + { + @Override + public void onResponse(JSONObject response) { + //firstName.setText(""+response.toString()); + try { + email.setText(response.getString("email")); + + } catch (JSONException e) { + e.printStackTrace(); + } + + Log.d("Response", response.toString()); + } + }, + new Response.ErrorListener() + { + @Override + public void onErrorResponse(VolleyError error) { + Toast.makeText(getApplicationContext(),error.toString(),Toast.LENGTH_SHORT).show(); + Log.d("Error.Response","??" ); + } + } + ){ + @Override + public java.util.Map getHeaders() { + HashMap params = new HashMap<>(); + params.put("Authorization", "Bearer " + new Session(getApplication()).getAuthToken()); + return params; + } + }; + +// add it to the RequestQueue + MyVolleyQueue.getInstance(getApplicationContext()).addToRequestQueue(getRequest); + } + + + public void openChangePass(){ + Intent intent = new Intent(this, ChangePass.class); + startActivity(intent); + } + +} diff --git a/projects/CitiSim/Android/app/src/main/java/com/main/citisim/VolleyMultipartRequest.java b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/VolleyMultipartRequest.java new file mode 100644 index 00000000..87821f60 --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/java/com/main/citisim/VolleyMultipartRequest.java @@ -0,0 +1,214 @@ +package com.main.citisim; + +import com.android.volley.AuthFailureError; +import com.android.volley.NetworkResponse; +import com.android.volley.ParseError; +import com.android.volley.Request; +import com.android.volley.Response; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.HttpHeaderParser; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Map; + +public class VolleyMultipartRequest extends Request { + + private final String twoHyphens = "--"; + private final String lineEnd = "\r\n"; + private final String boundary = "apiclient-" + System.currentTimeMillis(); + + private Response.Listener mListener; + private Response.ErrorListener mErrorListener; + private Map mHeaders; + + + public VolleyMultipartRequest(int method, String url, + Response.Listener listener, + Response.ErrorListener errorListener) { + super(method, url, errorListener); + this.mListener = listener; + this.mErrorListener = errorListener; + } + + @Override + public Map getHeaders() throws AuthFailureError { + return (mHeaders != null) ? mHeaders : super.getHeaders(); + } + + @Override + public String getBodyContentType() { + return "multipart/form-data;boundary=" + boundary; + } + + @Override + public byte[] getBody() throws AuthFailureError { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(bos); + + try { + // populate text payload + Map params = getParams(); + if (params != null && params.size() > 0) { + textParse(dos, params, getParamsEncoding()); + } + + // populate data byte payload + Map data = getByteData(); + if (data != null && data.size() > 0) { + dataParse(dos, data); + } + + // close multipart form data after text and file data + dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); + + return bos.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + /** + * Custom method handle data payload. + * + * @return MapActivity data part label with data byte + * @throws AuthFailureError + */ + protected Map getByteData() throws AuthFailureError { + return null; + } + + @Override + protected Response parseNetworkResponse(NetworkResponse response) { + try { + return Response.success( + response, + HttpHeaderParser.parseCacheHeaders(response)); + } catch (Exception e) { + return Response.error(new ParseError(e)); + } + } + + @Override + protected void deliverResponse(NetworkResponse response) { + mListener.onResponse(response); + } + + @Override + public void deliverError(VolleyError error) { + mErrorListener.onErrorResponse(error); + } + + /** + * Parse string map into data output stream by key and value. + * + * @param dataOutputStream data output stream handle string parsing + * @param params string inputs collection + * @param encoding encode the inputs, default UTF-8 + * @throws IOException + */ + private void textParse(DataOutputStream dataOutputStream, Map params, String encoding) throws IOException { + try { + for (Map.Entry entry : params.entrySet()) { + buildTextPart(dataOutputStream, entry.getKey(), entry.getValue()); + } + } catch (UnsupportedEncodingException uee) { + throw new RuntimeException("Encoding not supported: " + encoding, uee); + } + } + + /** + * Parse data into data output stream. + * + * @param dataOutputStream data output stream handle file attachment + * @param data loop through data + * @throws IOException + */ + private void dataParse(DataOutputStream dataOutputStream, Map data) throws IOException { + for (Map.Entry entry : data.entrySet()) { + buildDataPart(dataOutputStream, entry.getValue(), entry.getKey()); + } + } + + /** + * Write string data into header and data output stream. + * + * @param dataOutputStream data output stream handle string parsing + * @param parameterName name of input + * @param parameterValue value of input + * @throws IOException + */ + private void buildTextPart(DataOutputStream dataOutputStream, String parameterName, String parameterValue) throws IOException { + dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd); + dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + parameterName + "\"" + lineEnd); + dataOutputStream.writeBytes(lineEnd); + dataOutputStream.writeBytes(parameterValue + lineEnd); + } + + /** + * Write data file into header and data output stream. + * + * @param dataOutputStream data output stream handle data parsing + * @param dataFile data byte as DataPart from collection + * @param inputName name of data input + * @throws IOException + */ + private void buildDataPart(DataOutputStream dataOutputStream, DataPart dataFile, String inputName) throws IOException { + dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd); + dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"" + + inputName + "\"; filename=\"" + dataFile.getFileName() + "\"" + lineEnd); + if (dataFile.getType() != null && !dataFile.getType().trim().isEmpty()) { + dataOutputStream.writeBytes("Content-Type: " + dataFile.getType() + lineEnd); + } + dataOutputStream.writeBytes(lineEnd); + + ByteArrayInputStream fileInputStream = new ByteArrayInputStream(dataFile.getContent()); + int bytesAvailable = fileInputStream.available(); + + int maxBufferSize = 1024 * 1024; + int bufferSize = Math.min(bytesAvailable, maxBufferSize); + byte[] buffer = new byte[bufferSize]; + + int bytesRead = fileInputStream.read(buffer, 0, bufferSize); + + while (bytesRead > 0) { + dataOutputStream.write(buffer, 0, bufferSize); + bytesAvailable = fileInputStream.available(); + bufferSize = Math.min(bytesAvailable, maxBufferSize); + bytesRead = fileInputStream.read(buffer, 0, bufferSize); + } + + dataOutputStream.writeBytes(lineEnd); + } + + class DataPart { + private String fileName; + private byte[] content; + private String type; + + public DataPart() { + } + + DataPart(String name, byte[] data) { + fileName = name; + content = data; + } + + String getFileName() { + return fileName; + } + + byte[] getContent() { + return content; + } + + String getType() { + return type; + } + + } +} diff --git a/projects/CitiSim/Android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/projects/CitiSim/Android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100755 index 00000000..1f6bb290 --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/projects/CitiSim/Android/app/src/main/res/drawable/account.png b/projects/CitiSim/Android/app/src/main/res/drawable/account.png new file mode 100755 index 00000000..49dc302b Binary files /dev/null and b/projects/CitiSim/Android/app/src/main/res/drawable/account.png differ diff --git a/projects/CitiSim/Android/app/src/main/res/drawable/buttonshape.xml b/projects/CitiSim/Android/app/src/main/res/drawable/buttonshape.xml new file mode 100755 index 00000000..a27d63d8 --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/res/drawable/buttonshape.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/projects/CitiSim/Android/app/src/main/res/drawable/camera.png b/projects/CitiSim/Android/app/src/main/res/drawable/camera.png new file mode 100755 index 00000000..cd7f0752 Binary files /dev/null and b/projects/CitiSim/Android/app/src/main/res/drawable/camera.png differ diff --git a/projects/CitiSim/Android/app/src/main/res/drawable/camera2.png b/projects/CitiSim/Android/app/src/main/res/drawable/camera2.png new file mode 100755 index 00000000..500c573e Binary files /dev/null and b/projects/CitiSim/Android/app/src/main/res/drawable/camera2.png differ diff --git a/projects/CitiSim/Android/app/src/main/res/drawable/ic_launcher_background.xml b/projects/CitiSim/Android/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100755 index 00000000..0d025f9b --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/CitiSim/Android/app/src/main/res/drawable/logo.png b/projects/CitiSim/Android/app/src/main/res/drawable/logo.png new file mode 100755 index 00000000..a1fa010a Binary files /dev/null and b/projects/CitiSim/Android/app/src/main/res/drawable/logo.png differ diff --git a/projects/CitiSim/Android/app/src/main/res/drawable/settings.png b/projects/CitiSim/Android/app/src/main/res/drawable/settings.png new file mode 100755 index 00000000..62dc6585 Binary files /dev/null and b/projects/CitiSim/Android/app/src/main/res/drawable/settings.png differ diff --git a/projects/CitiSim/Android/app/src/main/res/layout/activity_change_pass.xml b/projects/CitiSim/Android/app/src/main/res/layout/activity_change_pass.xml new file mode 100644 index 00000000..b569d373 --- /dev/null +++ b/projects/CitiSim/Android/app/src/main/res/layout/activity_change_pass.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + +