diff --git a/.classpath b/.classpath
deleted file mode 100644
index 4f95ed0..0000000
--- a/.classpath
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bc21e6d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,188 @@
+
+# Created by https://www.gitignore.io/api/android,windows,androidstudio
+
+### Android ###
+# Built application files
+*.apk
+*.ap_
+
+# Files for the ART/Dalvik VM
+*.dex
+
+# Java class files
+*.class
+
+# Generated files
+bin/
+gen/
+out/
+
+# 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/dictionaries
+.idea/libraries
+
+# External native build folder generated in Android Studio 2.2 and later
+.externalNativeBuild
+
+# Freeline
+freeline.py
+freeline/
+freeline_project_description.json
+
+### Android Patch ###
+gen-external-apklibs
+
+### AndroidStudio ###
+# Covers files to be ignored for android development using Android Studio.
+
+# Built application files
+
+# Files for the ART/Dalvik VM
+
+# Java class files
+
+# Generated files
+
+# Gradle files
+.gradle
+
+# Signing files
+.signing/
+
+# Local configuration file (sdk path, etc)
+
+# Proguard folder generated by Eclipse
+
+# Log Files
+
+# Android Studio
+/*/build/
+/*/local.properties
+/*/out
+/*/*/build
+/*/*/production
+*.ipr
+*~
+*.swp
+
+# Android Patch
+
+# External native build folder generated in Android Studio 2.2 and later
+
+# NDK
+obj/
+
+# IntelliJ IDEA
+*.iws
+/out/
+
+# User-specific configurations
+.idea/libraries/
+.idea/.name
+.idea/compiler.xml
+.idea/copyright/profiles_settings.xml
+.idea/encodings.xml
+.idea/misc.xml
+.idea/modules.xml
+.idea/scopes/scope_settings.xml
+.idea/vcs.xml
+.idea/jsLibraryMappings.xml
+.idea/datasources.xml
+.idea/dataSources.ids
+.idea/sqlDataSources.xml
+.idea/dynamic.xml
+.idea/uiDesigner.xml
+
+# OS-specific files
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.db
+
+# Legacy Eclipse project files
+.classpath
+.project
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.war
+*.ear
+
+# virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml)
+hs_err_pid*
+
+## Plugin-specific files:
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Mongo Explorer plugin
+.idea/mongoSettings.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+### AndroidStudio Patch ###
+
+!/gradle/wrapper/gradle-wrapper.jar
+
+### Windows ###
+# Windows thumbnail cache files
+ehthumbs_vista.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# End of https://www.gitignore.io/api/android,windows,androidstudio
+/.idea/gradle.xml
+/.idea/misc.xml
+/.idea
+/.idea/modules.xml
+/.idea/gradle.xml
+/.idea/misc.xml
diff --git a/.project b/.project
deleted file mode 100644
index fa1a5d6..0000000
--- a/.project
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- SafeDispatch
-
-
-
-
-
- com.android.ide.eclipse.adt.ResourceManagerBuilder
-
-
-
-
- com.android.ide.eclipse.adt.PreCompilerBuilder
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- com.android.ide.eclipse.adt.ApkBuilder
-
-
-
-
-
- com.android.ide.eclipse.adt.AndroidNature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/.settings/com.google.appengine.eclipse.core.prefs b/.settings/com.google.appengine.eclipse.core.prefs
deleted file mode 100644
index 74a1742..0000000
--- a/.settings/com.google.appengine.eclipse.core.prefs
+++ /dev/null
@@ -1,3 +0,0 @@
-#Thu Nov 24 10:30:15 EET 2011
-eclipse.preferences.version=1
-filesCopiedToWebInfLib=
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index a005f9d..0000000
--- a/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,12 +0,0 @@
-#Fri Dec 09 16:13:31 EET 2011
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
deleted file mode 100644
index f6e7403..0000000
--- a/AndroidManifest.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/AndroidManifest_Safe.xml b/AndroidManifest_Safe.xml
deleted file mode 100644
index 4a9f3a0..0000000
--- a/AndroidManifest_Safe.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/AndroidManifest_demo.xml b/AndroidManifest_demo.xml
deleted file mode 100644
index 7ddee12..0000000
--- a/AndroidManifest_demo.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..01f7b88
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,22 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ repositories {
+ jcenter()
+ maven {
+ url 'https://maven.google.com/'
+ name 'Google'
+ }
+ google()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:7.1.2'
+ classpath 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1'
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ google()
+ }
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..6403ff1
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,41 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+VERSION_NAME=1.2
+
+# Increase memory allotted to JVM
+org.gradle.jvmargs=-Xmx2048M
+#Xmx1536M
+#org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# Enable Gradle Daemon
+#org.gradle.daemon=true
+
+# Enable Configure on demand
+#org.gradle.configureondemand=true
+
+# Enable parallel builds
+org.gradle.parallel=true
+android.useAndroidX=true
+android.enableJetifier=true
+
+# Enable Build Cache
+#android.enableBuildCache=true
+
+# Enable simple gradle caching
+#org.gradle.caching=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..b1a86b3
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Mar 10 10:35:08 EET 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## 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='"-Xmx64m" "-Xms64m"'
+
+# 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 or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; 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=`expr $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"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@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 Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@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="-Xmx64m" "-Xms64m"
+
+@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 execute
+
+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 execute
+
+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
+
+: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 %*
+
+: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/import-summary.txt b/import-summary.txt
new file mode 100644
index 0000000..5a3915d
--- /dev/null
+++ b/import-summary.txt
@@ -0,0 +1,85 @@
+ECLIPSE ANDROID PROJECT IMPORT SUMMARY
+======================================
+
+Manifest Merging:
+-----------------
+Your project uses libraries that provide manifests, and your Eclipse
+project did not explicitly turn on manifest merging. In Android Gradle
+projects, manifests are always merged (meaning that contents from your
+libraries' manifests will be merged into the app manifest. If you had
+manually copied contents from library manifests into your app manifest
+you may need to remove these for the app to build correctly.
+
+Ignored Files:
+--------------
+The following files were *not* copied into the new Gradle project; you
+should evaluate whether these are still needed in your project and if
+so manually move them:
+
+From LibSafeMobile:
+* proguard-project.txt
+* safemobile.keystore
+From SafeDispatch:
+* AndroidManifest_Safe.xml
+* AndroidManifest_demo.xml
+* proguard.cfg
+
+Replaced Jars with Dependencies:
+--------------------------------
+The importer recognized the following .jar files as third party
+libraries and replaced them with Gradle dependencies instead. This has
+the advantage that more explicit version information is known, and the
+libraries can be updated automatically. However, it is possible that
+the .jar file in your project was of an older version than the
+dependency we picked, which could render the project not compileable.
+You can disable the jar replacement in the import wizard and try again:
+
+android-support-v4.jar => com.android.support:support-v4:18.0.0
+
+Replaced Libraries with Dependencies:
+-------------------------------------
+The importer recognized the following library projects as third party
+libraries and replaced them with Gradle dependencies instead. This has
+the advantage that more explicit version information is known, and the
+libraries can be updated automatically. However, it is possible that
+the source files in your project were of an older version than the
+dependency we picked, which could render the project not compileable.
+You can disable the library replacement in the import wizard and try
+again:
+
+LibGooglePlayServices => [com.google.android.gms:play-services:+]
+
+Moved Files:
+------------
+Android Gradle projects use a different directory structure than ADT
+Eclipse projects. Here's how the projects were restructured:
+
+In LibSafeMobile:
+* AndroidManifest.xml => libSafeMobile\src\main\AndroidManifest.xml
+* assets\ => libSafeMobile\src\main\assets
+* libs\Citizen_Android_1063.jar => libSafeMobile\libs\Citizen_Android_1063.jar
+* res\ => libSafeMobile\src\main\res\
+* src\ => libSafeMobile\src\main\java\
+* truck5_large.PNG => truck5_large.png
+In SafeDispatch:
+* disable.PNG => disable.png
+* AndroidManifest.xml => safeDispatch\src\main\AndroidManifest.xml
+* assets\ => safeDispatch\src\main\assets\
+* lint.xml => safeDispatch\lint.xml
+* res\ => safeDispatch\src\main\res\
+* src\ => safeDispatch\src\main\java\
+
+Next Steps:
+-----------
+You can now build the project. The Gradle project needs network
+connectivity to download dependencies.
+
+Bugs:
+-----
+If for some reason your project does not build, and you determine that
+it is due to a bug or limitation of the Eclipse to Gradle importer,
+please file a bug at http://b.android.com with category
+Component-Tools.
+
+(This import summary is for your information only, and can be deleted
+after import once you are satisfied with the results.)
diff --git a/libSafeMobile/build.gradle b/libSafeMobile/build.gradle
new file mode 100644
index 0000000..8cecc9c
--- /dev/null
+++ b/libSafeMobile/build.gradle
@@ -0,0 +1,44 @@
+apply plugin: 'com.android.library'
+apply plugin: 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
+
+android {
+ compileSdkVersion 31
+ buildToolsVersion "31.0.0"
+
+ defaultConfig {
+ minSdkVersion 21
+ targetSdkVersion 31
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+ }
+ }
+ buildFeatures {
+ viewBinding false
+ }
+}
+
+dependencies {
+ implementation files('libs/Citizen_Android_1063.jar')
+
+ // support libraries
+ implementation 'androidx.appcompat:appcompat:1.4.1'
+ implementation 'com.google.android.material:material:1.5.0'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'androidx.recyclerview:recyclerview:1.2.1'
+ implementation 'androidx.media:media:1.5.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
+ implementation 'com.google.android.gms:play-services-auth:20.1.0'
+
+ // Fused location provider with and without google services
+ implementation 'com.google.android.gms:play-services-location:19.0.1'
+
+ // Google maps library
+ implementation 'com.google.android.gms:play-services-maps:18.0.2'
+
+ // add Gson
+ implementation 'com.google.code.gson:gson:2.8.6'
+}
diff --git a/libSafeMobile/libs/Citizen_Android_1063.jar b/libSafeMobile/libs/Citizen_Android_1063.jar
new file mode 100644
index 0000000..41cf8d8
Binary files /dev/null and b/libSafeMobile/libs/Citizen_Android_1063.jar differ
diff --git a/libSafeMobile/src/main/AndroidManifest.xml b/libSafeMobile/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..b6b0535
--- /dev/null
+++ b/libSafeMobile/src/main/AndroidManifest.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/java/com/safemobile/activities/AbstractEmptyActivity.java b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractEmptyActivity.java
new file mode 100644
index 0000000..3a7e4d1
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractEmptyActivity.java
@@ -0,0 +1,15 @@
+package com.safemobile.activities;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class AbstractEmptyActivity extends Activity {
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/activities/AbstractLiveActivity.java b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractLiveActivity.java
new file mode 100644
index 0000000..11a7695
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractLiveActivity.java
@@ -0,0 +1,60 @@
+package com.safemobile.activities;
+
+import java.util.ArrayList;
+
+import com.safemobile.lib.Vehicle;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+public abstract class AbstractLiveActivity extends AppCompatActivity {
+
+ private AbstractSDParentActivity parentTab;
+ private Activity activity;
+ private Context context;
+
+ private Bundle savedInstanceState;
+
+ public abstract void refreshMap(); // --> updateMap
+ public abstract void vehiclesReceived(ArrayList vehiclesList); // --> SaveVehicleInfo
+ public abstract void pollReceived(int position, double lat, double lng); // --> UpdatePoll
+ public abstract void vehicleStatusReceived(long imei, int opCode, int status); // --> UpdateOptions
+ public abstract void emergencyAlarmReceived(int position, double lat, double lng); // --> UpdateEmergencyAlarm
+
+
+ /** Misc */
+ public AbstractSDParentActivity getParentTab() {
+ return parentTab;
+ }
+
+ public void setParentTab(AbstractSDParentActivity parentTab) {
+ this.parentTab = parentTab;
+ }
+
+ public Activity getActivity() {
+ return activity;
+ }
+
+ public void setActivity(Activity activity) {
+ this.activity = activity;
+ }
+
+ public Context getContext() {
+ return context;
+ }
+
+ public void setContext(Context context) {
+ this.context = context;
+ }
+
+ public Bundle getSavedInstanceState() {
+ return savedInstanceState;
+ }
+
+ public void setSavedInstanceState(Bundle savedInstanceState) {
+ this.savedInstanceState = savedInstanceState;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/activities/AbstractMessagesActivity.java b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractMessagesActivity.java
new file mode 100644
index 0000000..ddbda64
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractMessagesActivity.java
@@ -0,0 +1,25 @@
+package com.safemobile.activities;
+
+import android.app.Activity;
+import android.content.Context;
+
+public abstract class AbstractMessagesActivity extends Activity {
+
+ /** Misc */
+ public AbstractParentActivity parentTab;
+ public Activity activity;
+ public Context context;
+
+ // GridView Type
+ public boolean LASTMESSAGES = true;
+
+ /*
+ public abstract void UpdateSMS(ArrayList list);
+ public abstract void updateResultsInUi();
+ public abstract void selectVehicle4Sc_id(long sc_id);
+ public abstract void updateTCPConnection(boolean connected);
+ public abstract void ConfirmSMS(String data);
+ public abstract void NewSMS(String imei, String message);
+ public abstract void onContactsUpdate();
+ */
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/activities/AbstractParentActivity.java b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractParentActivity.java
new file mode 100644
index 0000000..a1e18cd
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractParentActivity.java
@@ -0,0 +1,129 @@
+package com.safemobile.activities;
+
+import com.safemobile.bluetooth.BluetoothTether;
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.Contact;
+import com.safemobile.lib.R;
+import com.safemobile.services.TCPhandler;
+import com.safemobile.services.TCPmsgParser;
+
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.app.TabActivity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.os.Handler;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+
+@SuppressWarnings("deprecation")
+public abstract class AbstractParentActivity extends TabActivity {
+
+ /** UI Elements */
+ public RelativeLayout layoutLoading, relativeLayoutMenu;
+ public ImageView imageViewLoading;
+
+ /** Misc */
+ public Activity activity;
+ public Context context;
+ public NotificationManager mNotificationManager;
+ public boolean displayLogCat = false; // show logCat messages when TCP send was successful
+
+ /** Handler */
+ public Handler myHandler = new Handler();
+
+ /** BlueTooth Tether */
+ public BluetoothTether bluetoothTether = null;
+
+ /** Broadcast Receiver */
+ public BroadcastReceiver mReceiver = null;
+
+ /** TCP */
+ protected TCPhandler tcp = null;
+ protected TCPmsgParser tcpParser = null;
+
+ /** Methods */
+ //public void onCreate(Bundle savedInstanceState) { };
+ public abstract void startAudioHandler();
+ public abstract void getSetZoneAndChannel(int gwID, int rgwID, int zoneNR, int channelNR);
+ public abstract void getRadioStatus(int gwID, int rgwID);
+ public abstract void sendPTT(int callType, long id);
+ public abstract void sendCallType(int callType, long id);
+ public abstract void sendDekey();
+ public abstract void sendReset();
+ public abstract void sendEmergency(int onOFF);
+ public abstract void sendEmergency(int onOFF, long group_id);
+ public abstract void sendSMS(String seqId, long sc_id, String txt);
+ public abstract void displayToast(final String msg);
+ public abstract void whenBackPressed(AppParams.ActivityResult result);
+ public abstract void whenMenuPressed();
+ public abstract void changeLanguage();
+ public abstract Contact getVehicleById(long imei);
+
+ /** enable the menu buttons placed on the right side of the screen
+ * @param enable if set to true, the buttons will be enabled, else they will be disabled */
+ public abstract void enableMenuButtons(boolean enable);
+
+ public abstract void setRadioActivity(AbstractRadioActivity radioActivity);
+ public abstract void setMessagesActivity(AbstractMessagesActivity messageActivity);
+
+ /** Send a TCP Command using Async Tasks
+ * @param params Here you will add parameters for commands, and params[0] will be the Operation Code
+ * followed by others parameters accordingly to the command*/
+ public abstract void executeNetworkStuff(String[] params);
+
+
+ /** get if TCP is connected or disconnected or null */
+ public Object getTCPState() {
+ // return true if tcp connection is on, false if not connected and null
+
+ if(tcp!=null && tcp.isConnectionUP)
+ return "true";
+ else if(tcp!=null && !tcp.isConnectionUP)
+ return "false";
+ return null;
+ }
+
+ public void showMenu(boolean show)
+ {
+ if(relativeLayoutMenu != null)
+ {
+ // do not performe animation if already shown or already hidden
+ if((relativeLayoutMenu.isShown() && show) || (!relativeLayoutMenu.isShown() && !show))
+ ;
+ else {
+ Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_out_bottom);
+ if(show)
+ anim = AnimationUtils.loadAnimation(this, R.anim.slide_in_bottom);
+ relativeLayoutMenu.clearAnimation();
+ relativeLayoutMenu.startAnimation(anim);
+ relativeLayoutMenu.setVisibility(show ? View.VISIBLE : View.GONE);
+ }
+ }
+ }
+
+ public boolean isMenuVisibile()
+ {
+ if(relativeLayoutMenu!= null && relativeLayoutMenu.getVisibility() == View.VISIBLE)
+ return true;
+ else
+ return false;
+ }
+
+ public abstract void unregisterReceivers(BroadcastReceiver receiver);
+ public abstract void cancelNotification(int drawable);
+ public abstract void stopTethering();
+ public abstract void stopAudio();
+ public abstract void stopTCP();
+ public abstract void recreateTCPConnection();
+ public abstract void removeITCPListener();
+
+ /*
+ public abstract void onResume();
+ public abstract void onStart();
+ public abstract void onPause();
+ */
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/activities/AbstractRadioActivity.java b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractRadioActivity.java
new file mode 100644
index 0000000..3c1342e
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractRadioActivity.java
@@ -0,0 +1,264 @@
+package com.safemobile.activities;
+
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.ListIterator;
+import java.util.Timer;
+
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.Contact;
+import com.safemobile.lib.radio.Channel;
+import com.safemobile.lib.radio.Emerg;
+import com.safemobile.lib.radio.IncCall;
+import com.safemobile.lib.radio.Zone;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.os.Handler;
+import android.widget.ArrayAdapter;
+
+public abstract class AbstractRadioActivity extends Activity {
+
+
+ /** Misc */
+ public AbstractParentActivity parentTab;
+ public Activity activity;
+ public Context context;
+ public boolean emergencyOn = false;
+ public boolean pttONoff = false;
+ public IncCall incCall;
+ public String chMsg = "";
+ public Emerg emerg;
+ public Dialog dialogExternal;
+ // only in PadRadio
+ //public int radioID, GWID, zoneNR, chNR;
+
+ /** Handler */
+ public Handler myHandler = new Handler();
+ public Timer timerInCall, timerPTTOn, timerCallType;
+
+ /** Lists */
+ //public ArrayList allContactsNames = new ArrayList();
+ //public ArrayList allGroupsNames = new ArrayList();
+ //public ArrayList allContactsIDs = new ArrayList();
+ //public ArrayList allGroupsIDs = new ArrayList();
+ //public ArrayList crtZones = new ArrayList();
+ //public ArrayList crtChannels = new ArrayList();
+ public ArrayAdapter adapter;
+
+
+ /** Methods */
+ //public void onCreate(Bundle savedInstanceState) { };
+ public abstract void startAudioHandler();
+ public void PTTclick(int type) { };
+ /*
+ public abstract void updateRadioTCPdown();
+ public abstract void UpdateRadios(ArrayList radios);
+ public abstract void UpdateCallTypeChanged(IncCall response);
+ public abstract void UpdateZoneCH(int _radioID, int _GWID, int _zoneNR, int _chNR);
+ public abstract void UpdateRadioStatus(int status);
+ public abstract void UpdateIncCall (IncCall iCall);
+ public abstract String updateUI(EnumCallState radioStatus);
+ public abstract void UpdateEmerg (Emerg emerg);
+ public abstract void onContactsUpdate();
+ */
+ public abstract void sendPTTFromBlueTooth(boolean on);
+ public abstract void ShowDialog(String title, String errorMsg);
+ public abstract void stopAudioHandler();
+ public abstract Object getAudioHandlerState();
+ public abstract void initUDP();
+
+
+
+ /** Stop the timer that ends call after one minute */
+ public void stopTimerInCall()
+ {
+ timerInCall.cancel();
+ timerInCall.purge();
+ timerInCall = null;
+ }
+
+
+ /** get Group Contact ID from Name */
+ public long getGroupID4Name_old(String name)
+ {
+ try {
+ ListIterator it = AppParams.listContacts.listIterator();
+ while(it.hasNext())
+ {
+ Contact ctc = it.next();
+ // if searched name - return corresponding id
+ if(ctc.name.equals(name) && ctc.contactType == Contact.GROUP)
+ return ctc.id;
+ }
+
+ long id = -1;
+
+ // try to get id from name because the id was manual dialed
+ try {
+ id = Long.parseLong(name);
+ }
+ catch(Exception ex) {
+
+ }
+
+ return id;
+ }
+ catch (ConcurrentModificationException ex) {
+ return -1;
+ }
+ }
+
+ /** get Private Contact ID from Name */
+ public long getPrivateID4Name_old(String name)
+ {
+ try {
+ ListIterator it = AppParams.listContacts.listIterator();
+ while(it.hasNext())
+ {
+ Contact ctc = it.next();
+ // if searched name - return corresponding id
+ if(ctc.name.equals(name) && ctc.contactType == Contact.PRIVATE)
+ return ctc.id;
+ }
+
+ long id = -1;
+
+ // try to get id from name because the id was manual dialed
+ try {
+ id = Long.parseLong(name);
+ }
+ catch(Exception ex) {
+
+ }
+
+ return id;
+ }
+ catch (ConcurrentModificationException ex) {
+ return -1;
+ }
+ }
+
+
+ /** get Private Contact ID from Name */
+ public String getName4PrivateID(long id)
+ {
+ try {
+ ListIterator it = AppParams.listContacts.listIterator();
+ while(it.hasNext())
+ {
+ Contact ctc = it.next();
+ // if searched name - return corresponding id
+ if(ctc.id == id && ctc.contactType == Contact.PRIVATE)
+ return ctc.name;
+ }
+
+ return id+"";
+ }
+ catch (ConcurrentModificationException ex) {
+ return id+"";
+ }
+ }
+
+
+ /** get Group Contact ID from Name */
+ public String getName4GroupID(long id)
+ {
+ try {
+ ListIterator it = AppParams.listContacts.listIterator();
+ while(it.hasNext())
+ {
+ Contact ctc = it.next();
+ // if searched name - return corresponding id
+ if(ctc.id == id && ctc.contactType == Contact.GROUP)
+ return ctc.name;
+ }
+
+ return id+"";
+ }
+ catch (ConcurrentModificationException ex) {
+ return id+"";
+ }
+ }
+
+
+
+ /** get zone number from spinner zoneName */
+ public int getNR4Zone_old(String zoneName)
+ {
+ for(Zone zone: AppParams.listZones)
+ if(zone.ZoneName.equals(zoneName))
+ return zone.id;
+ return -1;
+ }
+
+ /** get channel number from spinner chName */
+ public int getNR4CH_old(String chName)
+ {
+ for(Channel ch: AppParams.crtZone.channelList)
+ if(ch.chName.equals(chName))
+ return ch.id;
+ return -1;
+ }
+
+
+ /** get All Contacts Names */
+ public static ArrayList getAllContactsName(String type, ArrayList listContacts)
+ {
+ ArrayList list = new ArrayList();
+ try {
+ ListIterator it = listContacts.listIterator();
+ while(it.hasNext())
+ {
+ Contact contact = it.next();
+
+ if(type.equals("Call"))
+ list.add(contact.name);
+ else {
+ if((type.equalsIgnoreCase("Private Call") && contact.contactType == Contact.PRIVATE) ||
+ (type.equalsIgnoreCase("Group Call") && contact.contactType == Contact.GROUP))
+ list.add(contact.name);
+ }
+ }
+ }
+ catch (ConcurrentModificationException ex) {
+
+ }
+ return list;
+ }
+
+ /** get All Contacts Names */
+ public static ArrayList getAllContactsIDs(String type, ArrayList listContacts)
+ {
+ ArrayList list = new ArrayList();
+
+ try
+ {
+ ListIterator it = listContacts.listIterator();
+ while(it.hasNext())
+ {
+ Contact contact = it.next();
+
+ if(type.equals("Call"))
+ list.add((long)contact.id);
+
+ if((type.equalsIgnoreCase("Private Call") && contact.contactType == Contact.PRIVATE) ||
+ (type.equalsIgnoreCase("Group Call") && contact.contactType == Contact.GROUP))
+ list.add((long)contact.id);
+ }
+
+ }
+ catch (ConcurrentModificationException ex) {
+
+ }
+ return list;
+ }
+
+
+ /** Display a toast Message */
+ public void displayToast(String msg)
+ {
+ parentTab.displayToast(msg);
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/activities/AbstractRecordingsActivity.java b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractRecordingsActivity.java
new file mode 100644
index 0000000..26fd17b
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractRecordingsActivity.java
@@ -0,0 +1,15 @@
+package com.safemobile.activities;
+
+import android.app.Activity;
+import android.content.Context;
+
+public abstract class AbstractRecordingsActivity extends Activity {
+
+ /** Misc */
+ public AbstractParentActivity parentTab;
+ public Activity activity;
+ public Context context;
+
+ public abstract void deleteSelected(final int position);
+
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/activities/AbstractSDParentActivity.java b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractSDParentActivity.java
new file mode 100644
index 0000000..3feaf95
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/activities/AbstractSDParentActivity.java
@@ -0,0 +1,323 @@
+package com.safemobile.activities;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+import com.safemobile.bluetooth.BluetoothTether;
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.SM;
+import com.safemobile.lib.SuperVehicle;
+import com.safemobile.lib.Vehicle;
+import com.safemobile.services.TCPhandler;
+import com.safemobile.services.TCPmsgParser;
+
+import android.app.Activity;
+import android.app.NotificationManager;
+import android.app.TabActivity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.os.Handler;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+
+@SuppressWarnings("deprecation")
+public abstract class AbstractSDParentActivity extends TabActivity {
+
+ /** UI Elements */
+ public RelativeLayout layoutLoading;
+ public ImageView imageViewLoading;
+
+ /** Misc */
+ public Activity activity;
+ public Context context;
+ public NotificationManager mNotificationManager;
+ public boolean displayLogCat = true; // show logCat messages when TCP send was successful
+ public String imei, mess;
+ public int demoPosition = 0;
+
+ /** Lists */
+ public ArrayList allVehicle = new ArrayList();
+ public Hashtable SuperVehHash = new Hashtable();
+ public Hashtable VehHashbySc_id = new Hashtable();
+
+ /** Handler */
+ public Handler myHandler = new Handler();
+
+ /** BlueTooth Tether */
+ public BluetoothTether bluetoothTether = null;
+
+ /** Broadcast Receiver */
+ public BroadcastReceiver mReceiver = null;
+
+ /** TCP */
+ protected TCPhandler tcp = null;
+ protected TCPmsgParser tcpParser = null;
+
+ /** Methods */
+ public abstract void displayToast(final String msg);
+ public abstract void whenBackPressed(AppParams.ActivityResult result);
+ public abstract void changeLanguage();
+ public abstract void enableMenuButtons(boolean enable);
+ public abstract void setRadioActivity(AbstractRadioActivity radioActivity);
+ public abstract void setLiveActivity(AbstractLiveActivity liveActivity);
+ public abstract void setMessagesActivity(AbstractMessagesActivity messageActivity);
+
+ /** get if TCP is connected or disconnected or null */
+ public Object getTCPState() {
+ // return true if tcp connection is on, false if not connected and null
+
+ if(tcp!=null && tcp.isConnectionUP)
+ return "true";
+ else if(tcp!=null && !tcp.isConnectionUP)
+ return "false";
+ return null;
+ }
+
+ public abstract void unregisterReceivers(BroadcastReceiver receiver);
+ public abstract void cancelNotification(int drawable);
+ public abstract void stopTCP();
+ public abstract void stopTCPParser();
+ public abstract void executeNetworkStuff(String[] params);
+ public abstract void recreateTCPConnection();
+ public abstract void removeITCPListener();
+
+
+ public abstract void updateDemoPosition();
+ public abstract void updateResultsPollInUi(String type);
+ public abstract double best_zoom(double LATMAX,double LATmin,double LNGMAX,double LNGmin);
+
+ /* SafeDispatch Mobile functions */
+ /** get Vehicles for an user id */
+ public boolean getVehicles(int userID)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#21#" + AppParams.USERID + "#");
+ if(res && displayLogCat)
+ SM.Debug("Message (getVehs) sent to app server");
+ else
+ SM.Debug("Could not send message(getVehs)!!");
+
+ return res;
+ }
+
+ /** get vehicles Last Positions for an user id */
+ public boolean getLastPositions(int userID)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#25#" + userID + "#");
+ if(res && displayLogCat)
+ SM.Debug("Message (getLastPOS) sent to app server");
+ else
+ SM.Debug("Could not send message(getLastSMS)!!");
+
+ return res;
+ }
+
+ /** set Enable/Disable a vehicle */
+ public boolean setVehicleStatus(int radioCode, int opCode, int sc_id, int enable)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#"+radioCode+"#"+opCode+"#" + sc_id+"#" + enable + "#");
+ if(res && displayLogCat)
+ SM.Debug("Message (Option4Unit) sent to app server radioCode:"+radioCode+ " opCode:"+opCode+ " sc_id:"+sc_id+ " value:" + enable);
+ else
+ SM.Debug("Could not send message(Option4Unit)!!");
+
+ return res;
+ }
+
+ /** get Last SMSs for an user */
+ public boolean getLastSMSs(int userID)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#23#" + userID + "#");
+ if(res && displayLogCat)
+ SM.Debug("#Send Request#", "Message [getLastSMSs] sent to app server");
+ else
+ SM.Debug("#Send Request#", "Could not send message [getLastSMSs]!!");
+
+ return res;
+ }
+
+ /** get SMSs for an user that are recent than timeGMT
+ * @param sc_id the vehicle imei for which we want the SMSs
+ * @param timeGMT the unix time for the last message in the grid or messages that are newer than this time */
+ public boolean getRecentSMSs(int sc_id, long timeGMT)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#22#"+sc_id+"#" +timeGMT+"#");
+ if(res && displayLogCat)
+ SM.Debug("#Send Request#", "Message [getRecentSMSs] sent to app server");
+ else
+ SM.Debug("#Send Request#", "Could not send message [getRecentSMSs]!!");
+
+ return res;
+ }
+
+ /** send a SMS to a vehicle
+ * @param seqID is a unique identifier for the SMS
+ * @param sc_id vehicle imei to which you want to send the SMS
+ * @param txt the message to be send */
+ public boolean sendSMS(String seqID, int sc_id, String txt)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write(seqID, "#24#" + AppParams.USERID + "#" + sc_id + "#" + txt + "#");
+ if(res && displayLogCat)
+ SM.Debug("Message [sendSMS] sent to app server sc_id:"+sc_id+ " txt:"+txt);
+ else
+ SM.Debug("Could not send message [sendSMS]!!");
+
+ return res;
+ }
+
+
+ public boolean sendAlarmAcknoledge(int alarm_id, int type)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#28#" + alarm_id + "#" + type + "#");
+ if(res)
+ SM.Debug("Message [sendAlarmAcknoledge] sent to app server alarm_id:" + alarm_id + " type:" + type);
+ else
+ SM.Debug("Could not send message [sendAlarmAcknoledge]!!");
+
+ return res;
+ }
+
+ public boolean sendPlayRecordingRequest(long record_id)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#18#" + record_id + "#");
+ if(res)
+ SM.Debug("Message [sendPlayRecordingRequest] sent to app server record_id:"+record_id);
+ else
+ SM.Debug("Could not send message [sendPlayRecordingRequest]!!");
+
+ return res;
+ }
+
+
+ public boolean sendDekey(int gwID, int radioID)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#30#160#" + gwID + "." + radioID + "#");
+ if(res)
+ SM.Debug("Message [sendDekey] sent to app server record_id");
+ else
+ SM.Debug("Could not send message [sendDeKey]!!");
+
+ return res;
+ }
+
+ public boolean getHistoryPositions(int sc_id, long timeGMTStart, long timeGMTStop)
+ {
+ if(tcp == null)
+ return false;
+
+ String histSeqID = "1."+Integer.toString((int) (System.currentTimeMillis() / 1000L));
+ boolean res = tcp.Write(histSeqID,"#26#"+sc_id+"#"+timeGMTStart+"#"+timeGMTStop+"#");
+ if(res)
+ SM.Debug("Message [getHistoryPositions] sent to app server");
+ else
+ SM.Debug("Could not send message [getHistoryPositions]!!");
+
+ return res;
+ }
+
+ public boolean getRadiosList()
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#30#100#");
+ if(res)
+ SM.Debug("Message [getRadiosList] sent to app server");
+ else
+ SM.Debug("Could not send message [getRadiosList]!!");
+
+ return res;
+ }
+
+
+ // if zoneNr=0 and channelNR =0 then function acts as GET
+ public boolean getSetZoneAndChannel(int gwID, int rgwID, int zoneNR, int channelNR)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#30#104#" + gwID + "#" + rgwID + "#" + zoneNR + "#" +channelNR +"#");
+ if(res)
+ SM.Debug("Message [GetSetZoneAndChannel] sent to app server zoneNR:"+zoneNR+ " channelNR:"+channelNR);
+ else
+ SM.Debug("Could not send message [GetSetZoneAndChannel]!!");
+
+ return res;
+ }
+
+ public boolean getRadioStatus(int gwID, int rgwID)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#30#99#" + gwID + "#" + rgwID + "#");
+ if(res)
+ SM.Debug("Message [RadioGetRadioList] sent to app server || gwID: " + gwID + " | rgwID: " + rgwID);
+ else
+ SM.Debug("Could not send message [getLastSMS]!!");
+
+ return res;
+ }
+
+ public boolean getAlarms(long userID)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#27#" + userID + "#"); // = tcp.Write("0.0", "#30#99#" + gwID + "#" + rgwID + "#");
+ if(res)
+ SM.Debug("Message [GetAlarms] sent to app server");
+ else
+ SM.Debug("Could not send message [GetAlarms]!!");
+
+ return res;
+ }
+
+
+ public boolean getRecordings(int gwID, int radioID)
+ {
+ if(tcp == null)
+ return false;
+
+ boolean res = tcp.Write("0.0", "#29#"+AppParams.USERID+"#"+ gwID +"#"+ radioID +"#");
+ if(res)
+ SM.Debug("Message [GetRecordings] sent to app server");
+ else
+ SM.Debug("Could not send message [GetRecordings]!!");
+
+ return res;
+ }
+
+ //public abstract void getVehiclePosition(long imei);
+ /*
+ public abstract void onResume();
+ public abstract void onStart();
+ public abstract void onPause();
+ */
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/adapters/AlertGridViewAdapter.java b/libSafeMobile/src/main/java/com/safemobile/adapters/AlertGridViewAdapter.java
new file mode 100644
index 0000000..abaf299
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/adapters/AlertGridViewAdapter.java
@@ -0,0 +1,138 @@
+package com.safemobile.adapters;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.safemobile.lib.Alarm;
+import com.safemobile.lib.R;
+import com.safemobile.lib.SM;
+
+@SuppressLint("SimpleDateFormat")
+public class AlertGridViewAdapter extends BaseAdapter
+{
+ private ArrayList listAlarms;
+ private Activity activity;
+ private ArrayList acknowledged = new ArrayList();
+
+ public AlertGridViewAdapter(Activity activity, ArrayList listAlarms, Context context, ArrayList acknowledged) {
+ super();
+ this.activity = activity;
+ this.listAlarms = listAlarms;
+ this.acknowledged = acknowledged;
+ }
+
+ @Override
+ public int getCount() {
+ return listAlarms.size();
+ }
+
+ @Override
+ public Alarm getItem(int position) {
+ return listAlarms.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ public static class ViewHolder
+ {
+ public LinearLayout layoutAlert;
+ public ImageView imageViewAlert, imageViewRecycle;
+ public TextView textViewUnitName, textViewType, textViewDate;
+ }
+
+ @SuppressWarnings("deprecation")
+ @SuppressLint("SimpleDateFormat")
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder view;
+ LayoutInflater inflator = activity.getLayoutInflater();
+
+ if(convertView==null)
+ {
+ view = new ViewHolder();
+ convertView = inflator.inflate(R.layout.row_alert, null);
+
+ view.textViewUnitName = (TextView) convertView.findViewById(R.id.textViewUnitName);
+ view.textViewType = (TextView) convertView.findViewById(R.id.textViewType);
+ view.textViewDate = (TextView) convertView.findViewById(R.id.textViewDate);
+ view.imageViewRecycle = (ImageView) convertView.findViewById(R.id.imageViewRecycle);
+ view.imageViewAlert = (ImageView) convertView.findViewById(R.id.imageViewAlert);
+ view.layoutAlert = (LinearLayout) convertView.findViewById(R.id.layoutAlert);
+
+ convertView.setTag(view);
+ }
+ else
+ {
+ view = (ViewHolder) convertView.getTag();
+ }
+ view.textViewUnitName.setText(listAlarms.get(position).unitName);
+ view.textViewType.setText(listAlarms.get(position).typestr);
+
+ //view.txtViewDescription.setText(listAlarms.get(position).description);
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
+ Date date = new Date((long)listAlarms.get(position).timeGMT * 1000);
+ if(date.getDate() == Calendar.getInstance().get(Calendar.DAY_OF_MONTH))
+ sdf = new SimpleDateFormat("HH:mm:ss");
+ else
+ sdf = new SimpleDateFormat("MMM-dd HH:mm");
+ view.textViewDate.setText(String.valueOf(sdf.format(date)));
+
+ // set ack/!ack image
+ switch(acknowledged.get(position) ? 1 : 0)
+ {
+ case 1:
+ view.imageViewAlert.setImageResource(R.drawable.alert_off);
+ //view.layoutAlarm.setBackgroundColor(0xffffffff);
+ break;
+ case 0:
+ view.imageViewAlert.setImageResource(R.drawable.alert);
+ //view.layoutAlarm.setBackgroundColor(0xffcccccc);
+ break;
+ }
+ return convertView;
+ }
+
+ public void changeACK(int position)
+ {
+ SM.Debug("ACK ON START: " + position + " | " + (acknowledged.get(position) ? "true": "false"));
+ // change in list
+ acknowledged.remove(position);
+ acknowledged.add(position, true);
+
+ ViewHolder view = new ViewHolder();
+ LayoutInflater inflator = activity.getLayoutInflater();
+ View convertView = null;
+ if(convertView==null)
+ {
+ convertView = inflator.inflate(R.layout.row_alert, null);
+ try
+ {
+ view.imageViewAlert = (ImageView) convertView.findViewById(R.id.imageViewAlert);
+ view.imageViewAlert.setImageResource(R.drawable.alert_off);
+ convertView.setTag(view);
+
+ view = (ViewHolder) convertView.getTag();
+ }
+ catch (Exception e) {
+ }
+ }
+ }
+
+}
+
diff --git a/libSafeMobile/src/main/java/com/safemobile/adapters/ContactsComboBoxAdapter.java b/libSafeMobile/src/main/java/com/safemobile/adapters/ContactsComboBoxAdapter.java
new file mode 100644
index 0000000..1cba3cd
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/adapters/ContactsComboBoxAdapter.java
@@ -0,0 +1,107 @@
+package com.safemobile.adapters;
+
+import java.util.ArrayList;
+
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.Contact;
+import com.safemobile.lib.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class ContactsComboBoxAdapter extends ArrayAdapter{
+
+ private Context context;
+ int layoutResourceId;
+ private ArrayList listValues;
+
+ public ContactsComboBoxAdapter(Context context, int textViewResourceId, ArrayList listValues) {
+ super(context, textViewResourceId, listValues);
+ this.context = context;
+ this.layoutResourceId = textViewResourceId;
+ this.listValues = listValues;
+
+ }
+
+ @Override
+ public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ return getCustomView(position, convertView, parent);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ return getCustomView(position, convertView, parent);
+ }
+
+ public View getCustomView(int position, View convertView, ViewGroup parent) {
+ View row = convertView;
+ ImagesSpinnerHolder holder = null;
+
+ if(row == null) {
+
+ LayoutInflater inflater = ((Activity) context).getLayoutInflater();
+ /*LayoutInflater inflater = (LayoutInflater) context
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);*/
+
+ row = inflater.inflate(layoutResourceId, parent, false);
+
+ holder = new ImagesSpinnerHolder();
+ holder.textSpinner = (TextView)row.findViewById(R.id.language);
+ holder.imgSpinner = (ImageView)row.findViewById(R.id.icon);
+
+ row.setTag(holder);
+ }
+ else
+ holder = (ImagesSpinnerHolder)row.getTag();
+
+ holder.textSpinner.setText(getTextFromArrayList(position));
+ holder.imgSpinner.setImageResource(getImageFromArrayList(position));
+
+ return row;
+ }
+
+ /**
+ * Find which generic type which is used in the array list and then display the string field for that class type
+ * @param position The position in the array list which needs to be displayed
+ * @return The string which will be used
+ */
+ private String getTextFromArrayList(int position) {
+ return listValues.get(position).name;
+ }
+
+
+ /**
+ * Find which generic type which is used in the array list and then get the icon which needs to be displayed
+ * @param position The position in the array list which needs to be displayed
+ * @return The Image Resource which will be displayed
+ */
+ private int getImageFromArrayList(int position) {
+ int contactType = listValues.get(position).contactType;
+
+ switch(contactType)
+ {
+ case AppParams.MotoManualDial:
+ return R.drawable.dial;
+ case AppParams.MotoAllCall:
+ return R.drawable.call_all_green_small;
+ case AppParams.MotoPrivate:
+ return R.drawable.call_private_green_small;
+ case AppParams.MotoGroup:
+ return R.drawable.call_group_green_small;
+
+ default: return R.drawable.call_private_blue_small;
+ }
+ }
+
+
+ private class ImagesSpinnerHolder {
+ ImageView imgSpinner;
+ TextView textSpinner;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/adapters/ConversationGridViewAdapter.java b/libSafeMobile/src/main/java/com/safemobile/adapters/ConversationGridViewAdapter.java
new file mode 100644
index 0000000..e9ef9dd
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/adapters/ConversationGridViewAdapter.java
@@ -0,0 +1,200 @@
+package com.safemobile.adapters;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Hashtable;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.safemobile.lib.Msg;
+import com.safemobile.lib.R;
+import com.safemobile.lib.SM;
+
+public class ConversationGridViewAdapter extends BaseAdapter
+{
+ private ArrayList listMessages;
+ private Activity activity;
+ //public String time;
+ private ArrayList dispatcher_positions = new ArrayList();
+ private ArrayList ackPositions = new ArrayList();
+ private Hashtable hash = new Hashtable();
+
+
+ public ConversationGridViewAdapter(Activity activity, ArrayList listMessages, Context context, long sc_id, int unit_type, ArrayList dispatcher_positions, ArrayList ackPositions) {
+ this.activity = activity;
+ this.listMessages = listMessages;
+ this.dispatcher_positions = dispatcher_positions;
+ this.ackPositions = ackPositions;
+ }
+
+ @Override
+ public int getCount() {
+ return listMessages.size();
+ }
+
+ @Override
+ public Msg getItem(int position) {
+ return listMessages.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ public static class ViewHolder
+ {
+ public ImageView imgViewContact;
+ public TextView txtViewMsg;
+ public TextView txtViewDateTime;
+ public ImageView imgViewReceivedContact;
+ public TextView txtViewReceivedMsg;
+ public TextView txtViewReceivedDateTime;
+ public ImageView imageAck;
+ public TextView textViewNotACK;
+ public LinearLayout layoutSend;
+ public LinearLayout layoutReceived;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder view;
+ LayoutInflater inflator = activity.getLayoutInflater();
+
+ if(convertView==null)
+ {
+ view = new ViewHolder();
+ convertView = inflator.inflate(R.layout.row_conversation, null);
+
+ view.imgViewContact = (ImageView) convertView.findViewById(R.id.imageViewSenderIco);
+ view.txtViewMsg = (TextView) convertView.findViewById(R.id.textViewSendMsg);
+ view.txtViewDateTime = (TextView) convertView.findViewById(R.id.textViewSendDate);
+ view.imgViewReceivedContact = (ImageView) convertView.findViewById(R.id.imageViewReceivedIco);
+ view.txtViewReceivedMsg = (TextView) convertView.findViewById(R.id.textViewReceivedMsg);
+ view.txtViewReceivedDateTime = (TextView) convertView.findViewById(R.id.textViewReceivedDate);
+ view.layoutSend = (LinearLayout) convertView.findViewById(R.id.layoutSend);
+ view.layoutReceived = (LinearLayout) convertView.findViewById(R.id.layoutReceived);
+ view.textViewNotACK = (TextView) convertView.findViewById(R.id.textViewNotACKSendMsg);
+ view.imageAck = (ImageView) convertView.findViewById(R.id.imageAck);
+
+ convertView.setTag(view);
+ }
+ else
+ {
+ view = (ViewHolder) convertView.getTag();
+ }
+ try
+ {
+ hash.put(position, convertView);
+
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm MMM-dd");
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(Calendar.HOUR_OF_DAY,0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ if(listMessages.get(position).received.after(calendar.getTime()))
+ sdf = new SimpleDateFormat("HH:mm:ss");
+ else
+ sdf = new SimpleDateFormat("HH:mm MMM-dd");
+
+
+ //view.imgViewContact.setImageResource(getIcon(listMessages.get(position).from.user_type));
+ view.imgViewContact.setImageResource(R.drawable.peoplegreen_large);
+ view.txtViewMsg.setText(listMessages.get(position).message);
+ view.txtViewDateTime.setText(sdf.format(listMessages.get(position).received));
+ //view.imgViewReceivedContact.setImageResource(getIcon(listMessages.get(position).from.user_type));
+ view.imgViewReceivedContact.setImageResource(listMessages.get(position).from.getLargeIcon());
+ view.txtViewReceivedMsg.setText(listMessages.get(position).message);
+ view.txtViewReceivedDateTime.setText(sdf.format(listMessages.get(position).received));
+
+ if(ackPositions.size() > 0)
+ switch(ackPositions.get(position) ? 1: 0) {
+ case 0:
+ // show not ack
+ view.textViewNotACK.setVisibility(View.VISIBLE);
+ view.imageAck.setVisibility(View.VISIBLE);
+ break;
+ case 1:
+ // show not ack
+ view.textViewNotACK.setVisibility(View.INVISIBLE);
+ view.imageAck.setVisibility(View.INVISIBLE);
+ }
+
+ switch(dispatcher_positions.get(position) ? 1 : 0) {
+ case 1:
+ view.layoutReceived.setVisibility(View.GONE);
+ view.layoutSend.setVisibility(View.VISIBLE);
+ break;
+ case 0:
+ view.layoutReceived.setVisibility(View.VISIBLE);
+ view.layoutSend.setVisibility(View.GONE);
+ break;
+ }
+ }
+ catch(Exception ex)
+ {
+ SM.Exception(ex.toString());
+ }
+ return convertView;
+ }
+
+ public void setACK(String seqID)
+ {
+ int position = -1, i=0;
+
+ for(Msg msg: listMessages)
+ {
+ if(msg.seqID.equals(seqID))
+ position = i;
+
+ i++;
+ }
+
+ if(position > -1 && position < ackPositions.size()) {
+ ackPositions.remove(position);
+ ackPositions.add(position, true);
+ }
+ }
+
+ public void changeView(String seqID)
+ {
+ int position = -1, i=0;
+
+ for(Msg msg: listMessages)
+ {
+ if(msg.seqID.equals(seqID))
+ position = i;
+
+ i++;
+ }
+
+ if(position != -1 && hash.size() > position)
+ {
+ SM.Debug("POSITON : " + position);
+ View con = hash.get(position);
+ ViewHolder view = (ViewHolder) con.getTag();
+
+ switch(ackPositions.get(position) ? 1 : 0)
+ {
+ case 1:
+ view.imageAck.setVisibility(View.INVISIBLE);
+ view.textViewNotACK.setVisibility(View.INVISIBLE);
+ break;
+ case 0:
+ view.imageAck.setVisibility(View.VISIBLE);
+ view.textViewNotACK.setVisibility(View.VISIBLE);
+ break;
+ }
+ }
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/adapters/LanguageSpinnerAdapter.java b/libSafeMobile/src/main/java/com/safemobile/adapters/LanguageSpinnerAdapter.java
new file mode 100644
index 0000000..c248f03
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/adapters/LanguageSpinnerAdapter.java
@@ -0,0 +1,53 @@
+package com.safemobile.adapters;
+
+import com.safemobile.lib.R;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class LanguageSpinnerAdapter extends ArrayAdapter{
+
+ private String[] Languages;
+ private LayoutInflater inflater;
+
+ public LanguageSpinnerAdapter(Context context, int textViewResourceId,String[] Languages, LayoutInflater inflater) {
+ super(context, textViewResourceId, Languages);
+ this.Languages = Languages;
+ this.inflater = inflater;
+ }
+
+ @Override
+ public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ return getCustomView(position, convertView, parent);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ return getCustomView(position, convertView, parent);
+ }
+
+ public View getCustomView(int position, View convertView, ViewGroup parent) {
+ View row = inflater.inflate(R.layout.spinner, parent, false);
+ TextView label=(TextView)row.findViewById(R.id.language);
+ label.setText(Languages[position]);
+ ImageView icon =(ImageView)row.findViewById(R.id.icon);
+
+ switch (position)
+ {
+ case 0: icon.setImageResource(R.drawable.en); break;
+ case 1: icon.setImageResource(R.drawable.de); break;
+ case 2: icon.setImageResource(R.drawable.tr); break;
+ case 3: icon.setImageResource(R.drawable.ro); break;
+ case 4: icon.setImageResource(R.drawable.ru); break;
+ case 5: icon.setImageResource(R.drawable.es); break;
+ case 6: icon.setImageResource(R.drawable.ara); break;
+ }
+
+ return row;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/adapters/LiveGridViewAdapter.java b/libSafeMobile/src/main/java/com/safemobile/adapters/LiveGridViewAdapter.java
new file mode 100644
index 0000000..c614555
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/adapters/LiveGridViewAdapter.java
@@ -0,0 +1,231 @@
+package com.safemobile.adapters;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.safemobile.lib.R;
+import com.safemobile.lib.SM;
+import com.safemobile.lib.Vehicle;
+
+public class LiveGridViewAdapter extends BaseAdapter
+{
+ private ArrayList listVehicle;
+ private ArrayList displayedVehicles;
+ public ArrayList disabledVehicles;
+ private Activity activity;
+ //public String time;
+ //private int[] colors = new int[] { Color.parseColor("#FFFFFF"), Color.parseColor("#D2E4FC") };
+ private Hashtable hash = new Hashtable();
+
+ public LiveGridViewAdapter(Activity activity, ArrayList listVehicle, Context context, ArrayList displayedVehicles, ArrayList disabledVehicles)
+ {
+ super();
+ this.activity = activity;
+ this.listVehicle = listVehicle;
+ //this.time = time;
+ this.displayedVehicles = displayedVehicles;
+ this.disabledVehicles = disabledVehicles;
+ }
+
+ @Override
+ public int getCount() {
+ return listVehicle.size();
+ }
+
+ @Override
+ public Vehicle getItem(int position) {
+ return listVehicle.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ public static class ViewHolder
+ {
+ public ImageView imgViewIcon, imgViewChecked;
+ public TextView txtViewName;
+ public LinearLayout layoutVehicle;
+ }
+
+ @Override
+ public View getView(final int position, View convertView, ViewGroup parent) {
+ final ViewHolder view;
+ LayoutInflater inflator = activity.getLayoutInflater();
+ if(convertView==null)
+ {
+ view = new ViewHolder();
+ convertView = inflator.inflate(R.layout.row_vehicle, null);
+
+ view.imgViewIcon = (ImageView) convertView.findViewById(R.id.imageViewIcon);
+ view.txtViewName = (TextView) convertView.findViewById(R.id.textViewName);
+ view.imgViewChecked = (ImageView) convertView.findViewById(R.id.imageViewChecked);
+
+ //view.linearLayoutChecked = (LinearLayout) convertView.findViewById(R.id.linearLayoutChecked);
+ view.layoutVehicle = (LinearLayout) convertView.findViewById(R.id.layoutVehicle);
+ convertView.setTag(view);
+ }
+ else
+ {
+ view = (ViewHolder) convertView.getTag();
+ }
+
+ hash.put(position, convertView);
+
+ view.imgViewIcon.setImageResource(listVehicle.get(position).getSmallIcon());
+ view.txtViewName.setText(listVehicle.get(position).name);
+ // set color
+ //int colorPos = position % colors.length;
+ //view.layoutVehicle.setBackgroundColor(colors[colorPos]);
+ switch(displayedVehicles.get(position) ? 1 : 0)
+ {
+ case 1:
+ view.imgViewChecked.setImageResource(R.drawable.checked);
+ break;
+ case 0:
+ view.imgViewChecked.setImageResource(R.drawable.unchecked);
+ break;
+ }
+
+ switch(disabledVehicles.get(position) ? 1 : 0)
+ {
+ case 1:
+ view.layoutVehicle.setBackgroundColor(0xffcccccc);
+ //view.imgViewIcon.setImageDrawable(convertToGrayscale(activity.getResources().getDrawable(listVehicle.get(position).getSmallIcon())));
+ break;
+ case 0:
+ view.layoutVehicle.setBackgroundColor(0xffFFFFFF);
+ //view.imgViewIcon.setImageResource(listVehicle.get(position).getSmallIcon());
+ break;
+ }
+
+ return convertView;
+ }
+
+ public void changeDisplayed(int position, int status)
+ {
+ SM.Debug("DISABLE ON START: " + position + " | " + (disabledVehicles.get(position) ? "true": "false"));
+ SM.Debug("DISPLAY ON START: " + position + " | " + (displayedVehicles.get(position) ? "true": "false"));
+ // if vehicle is enable
+ if(status == 1)
+ {
+ // change icon
+ //view.imgViewChecked.setImageResource(R.drawable.unchecked);
+ // change in list
+ disabledVehicles.remove(position);
+ disabledVehicles.add(position, false);
+ }
+ else if(status == 0)
+ {
+ // change icon
+ //view.imgViewChecked.setImageResource(R.drawable.checked);
+ // change in list
+ disabledVehicles.remove(position);
+ disabledVehicles.add(position, true);
+ }
+ // change displayed
+ else if (status == -1)
+ {
+ // check selected position
+ displayedVehicles.remove(position);
+ displayedVehicles.add(position, true);
+ }
+
+ ViewHolder view = new ViewHolder();
+ LayoutInflater inflator = activity.getLayoutInflater();
+ View convertView = null;
+ if(convertView==null)
+ {
+ convertView = inflator.inflate(R.layout.row_vehicle, null);
+ try
+ {
+ view.layoutVehicle = (LinearLayout) convertView.findViewById(R.id.layoutVehicle);
+ view.imgViewIcon = (ImageView) convertView.findViewById(R.id.imageViewIcon);
+ view.imgViewChecked = (ImageView) convertView.findViewById(R.id.imageViewChecked);
+ convertView.setTag(view);
+
+ view = (ViewHolder) convertView.getTag();
+ }
+ catch (Exception e) {
+ }
+ }
+
+ SM.Debug("DISABLE AFTER: " + position + " | " + (disabledVehicles.get(position) ? "true": "false"));
+ SM.Debug("DISPLAY AFTER: " + position + " | " + (displayedVehicles.get(position) ? "true": "false"));
+ switch(disabledVehicles.get(position) ? 1 : 0)
+ {
+ case 1:
+ view.layoutVehicle.setBackgroundColor(0xffcccccc);
+ //view.imgViewIcon.setImageDrawable(convertToGrayscale(activity.getResources().getDrawable(listVehicle.get(position).getSmallIcon())));
+ break;
+ case 0:
+ view.layoutVehicle.setBackgroundColor(0xffFFFFFF);
+ //view.imgViewIcon.setImageResource(listVehicle.get(position).getSmallIcon());
+ break;
+ }
+
+ switch(displayedVehicles.get(position) ? 1 : 0)
+ {
+ case 1:
+ view.imgViewChecked.setImageResource(R.drawable.checked);
+ break;
+ case 0:
+ view.imgViewChecked.setImageResource(R.drawable.unchecked);
+ break;
+ }
+ }
+
+ public void changeView(int position)
+ {
+ View con = hash.get(position);
+ ViewHolder view = (ViewHolder) con.getTag();
+ switch(disabledVehicles.get(position) ? 1 : 0)
+ {
+ case 1:
+ view.layoutVehicle.setBackgroundColor(0xffcccccc);
+ //view.imgViewIcon.setImageDrawable(convertToGrayscale(activity.getResources().getDrawable(listVehicle.get(position).getSmallIcon())));
+ break;
+ case 0:
+ view.layoutVehicle.setBackgroundColor(0xffFFFFFF);
+ //view.imgViewIcon.setImageResource(listVehicle.get(position).getSmallIcon());
+ break;
+ }
+
+ switch(displayedVehicles.get(position) ? 1 : 0)
+ {
+ case 1:
+ view.imgViewChecked.setImageResource(R.drawable.checked);
+ break;
+ case 0:
+ view.imgViewChecked.setImageResource(R.drawable.unchecked);
+ break;
+ }
+ }
+
+ protected Drawable convertToGrayscale(Drawable drawable)
+ {
+ ColorMatrix matrix = new ColorMatrix();
+ matrix.setSaturation(0);
+
+ ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
+
+ drawable.setColorFilter(filter);
+
+ return drawable;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/adapters/MessagesGridViewAdapter.java b/libSafeMobile/src/main/java/com/safemobile/adapters/MessagesGridViewAdapter.java
new file mode 100644
index 0000000..d575684
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/adapters/MessagesGridViewAdapter.java
@@ -0,0 +1,132 @@
+package com.safemobile.adapters;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.safemobile.lib.Msg;
+import com.safemobile.lib.R;
+import com.safemobile.lib.SM;
+
+public class MessagesGridViewAdapter extends BaseAdapter
+{
+ private ArrayList listMessages;
+ private Activity activity;
+ //public String time;
+ //private int[] colors = new int[] { Color.parseColor("#FFFFFF"), Color.parseColor("#D2E4FC") };
+
+
+ public MessagesGridViewAdapter(Activity activity, ArrayList listMessages, Context context) {
+ super();
+ this.activity = activity;
+ this.listMessages = listMessages;
+ }
+
+ @Override
+ public int getCount() {
+ return listMessages.size();
+ }
+
+ @Override
+ public Msg getItem(int position) {
+ return listMessages.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ public static class ViewHolder
+ {
+ public ImageView imgViewContact;
+ public TextView txtViewContact;
+ public TextView txtViewDateTime;
+ public TextView txtViewLastMsg;
+ public LinearLayout layoutMessage;
+ }
+
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder view;
+ LayoutInflater inflator = activity.getLayoutInflater();
+
+ if(convertView==null)
+ {
+ view = new ViewHolder();
+ convertView = inflator.inflate(R.layout.row_message, null);
+
+ view.imgViewContact = (ImageView) convertView.findViewById(R.id.imageViewContact);
+ view.txtViewContact = (TextView) convertView.findViewById(R.id.textViewContact);
+ view.txtViewDateTime = (TextView) convertView.findViewById(R.id.textViewLastDate);
+ view.txtViewLastMsg = (TextView) convertView.findViewById(R.id.textViewLastMsg);
+ view.layoutMessage = (LinearLayout) convertView.findViewById(R.id.layoutMessage);
+
+ convertView.setTag(view);
+ }
+ else
+ {
+ view = (ViewHolder) convertView.getTag();
+ }
+
+ try
+ {
+ view.imgViewContact.setImageResource(listMessages.get(position).from.getLargeIcon());
+ //view.imgViewContact.setImageResource(R.drawable.peopleblue);
+ view.txtViewContact.setText(listMessages.get(position).from.name+ " :");
+ if(listMessages.get(position).message.length() > 25)
+ view.txtViewLastMsg.setText(listMessages.get(position).message.substring(0, 25) + "...");
+ else
+ view.txtViewLastMsg.setText(listMessages.get(position).message);
+
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(Calendar.HOUR_OF_DAY,0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ if(listMessages.get(position).received.after(calendar.getTime()))
+ sdf = new SimpleDateFormat("HH:mm:ss");
+ else
+ sdf = new SimpleDateFormat("MMM-dd HH:mm");
+
+ view.txtViewDateTime.setText(sdf.format(listMessages.get(position).received));
+ }
+ catch(Exception ex)
+ {
+ SM.Exception(ex.toString());
+ }
+ return convertView;
+ }
+
+ public int getIcon(int user_type, String username)
+ {
+ // if request was send by MessagesActivity -> Spinner
+ if(user_type == -1)
+ {
+ // get unit_type for selected username
+ for (Msg mes: listMessages)
+ {
+ // if user is selected
+ if(mes.from.name.equals(username))
+ {
+ user_type = (int) mes.from.driver_id; // save user_type
+
+ return mes.from.getLargeIcon();
+ }
+ }
+ }
+ return 0;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/adapters/PadConversationGridViewAdapter.java b/libSafeMobile/src/main/java/com/safemobile/adapters/PadConversationGridViewAdapter.java
new file mode 100644
index 0000000..a55ee65
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/adapters/PadConversationGridViewAdapter.java
@@ -0,0 +1,215 @@
+package com.safemobile.adapters;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Locale;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.safemobile.lib.R;
+import com.safemobile.lib.SM;
+import com.safemobile.libpad.PadTextMessage;
+
+public class PadConversationGridViewAdapter extends BaseAdapter
+{
+ private ArrayList listMessages;
+ private Activity activity;
+ //public String time;
+ private ArrayList outgoingPositions = new ArrayList();
+ private ArrayList ackPositions = new ArrayList();
+ private Hashtable hash = new Hashtable();
+
+
+ public PadConversationGridViewAdapter(Activity activity, ArrayList listMessages, Context context, ArrayList outgoingPositions, ArrayList ackPositions) {
+ this.activity = activity;
+ this.listMessages = listMessages;
+ this.outgoingPositions = outgoingPositions;
+ this.ackPositions = ackPositions;
+ }
+
+ @Override
+ public int getCount() {
+ return listMessages.size();
+ }
+
+ @Override
+ public PadTextMessage getItem(int position) {
+ return listMessages.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ /** return the list of messages in the adapter
+ * @return an ArrayList of PadTextMessages
+ */
+ public ArrayList getMessages() {
+ return listMessages;
+ }
+
+ public static class ViewHolder
+ {
+ public ImageView imgViewContact;
+ public TextView txtViewMsg;
+ public TextView txtViewDateTime;
+ public ImageView imgViewReceivedContact;
+ public TextView txtViewReceivedMsg;
+ public TextView txtViewReceivedDateTime;
+ public ImageView imageAck;
+ public TextView textViewNotACK;
+ public LinearLayout layoutSend;
+ public LinearLayout layoutReceived;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder view;
+ LayoutInflater inflator = activity.getLayoutInflater();
+
+ if(convertView==null)
+ {
+ view = new ViewHolder();
+ convertView = inflator.inflate(R.layout.row_conversation, null);
+
+ view.imgViewContact = (ImageView) convertView.findViewById(R.id.imageViewSenderIco);
+ view.txtViewMsg = (TextView) convertView.findViewById(R.id.textViewSendMsg);
+ view.txtViewDateTime = (TextView) convertView.findViewById(R.id.textViewSendDate);
+ view.imgViewReceivedContact = (ImageView) convertView.findViewById(R.id.imageViewReceivedIco);
+ view.txtViewReceivedMsg = (TextView) convertView.findViewById(R.id.textViewReceivedMsg);
+ view.txtViewReceivedDateTime = (TextView) convertView.findViewById(R.id.textViewReceivedDate);
+ view.layoutSend = (LinearLayout) convertView.findViewById(R.id.layoutSend);
+ view.layoutReceived = (LinearLayout) convertView.findViewById(R.id.layoutReceived);
+ view.textViewNotACK = (TextView) convertView.findViewById(R.id.textViewNotACKSendMsg);
+ view.imageAck = (ImageView) convertView.findViewById(R.id.imageAck);
+
+ convertView.setTag(view);
+ }
+ else
+ {
+ view = (ViewHolder) convertView.getTag();
+ }
+ try
+ {
+ hash.put(position, convertView);
+
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm MMM-dd", Locale.getDefault());
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(Calendar.HOUR_OF_DAY,0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+
+ Date date = new Date(listMessages.get(position).timeGMT * 1000);
+
+ if(date.after(calendar.getTime()))
+ sdf = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
+ else
+ sdf = new SimpleDateFormat("HH:mm MMM-dd", Locale.getDefault());
+
+ // set gmt time
+ //sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
+
+ //view.imgViewContact.setImageResource(getIcon(listMessages.get(position).from.user_type));
+ view.imgViewContact.setImageResource(R.drawable.peoplegreen_large);
+ view.txtViewMsg.setText(listMessages.get(position).message);
+ view.txtViewDateTime.setText(sdf.format(date));
+ //view.imgViewReceivedContact.setImageResource(getIcon(listMessages.get(position).from.user_type));
+ view.imgViewReceivedContact.setImageResource(R.drawable.peopleblue_large);
+ view.txtViewReceivedMsg.setText(listMessages.get(position).message);
+
+ view.txtViewReceivedDateTime.setText(sdf.format(date));
+
+ if(ackPositions.size() > 0)
+ switch(ackPositions.get(position) ? 1: 0) {
+ case 0:
+ // show not ack
+ view.textViewNotACK.setVisibility(View.VISIBLE);
+ view.imageAck.setVisibility(View.VISIBLE);
+ break;
+ case 1:
+ // show not ack
+ view.textViewNotACK.setVisibility(View.INVISIBLE);
+ view.imageAck.setVisibility(View.INVISIBLE);
+ }
+
+ switch(outgoingPositions.get(position) ? 1 : 0) {
+ case 1:
+ view.layoutReceived.setVisibility(View.GONE);
+ view.layoutSend.setVisibility(View.VISIBLE);
+ break;
+ case 0:
+ view.layoutReceived.setVisibility(View.VISIBLE);
+ view.layoutSend.setVisibility(View.GONE);
+ break;
+ }
+ }
+ catch(Exception ex)
+ {
+ SM.Exception(ex.toString());
+ }
+ return convertView;
+ }
+
+ /*
+ public void setACK(String seqID)
+ {
+ int position = -1, i=0;
+
+ for(Msg msg: listMessages)
+ {
+ if(msg.seqID.equals(seqID))
+ position = i;
+
+ i++;
+ }
+
+ ackPositions.remove(position);
+ ackPositions.add(position, true);
+ }
+
+ public void changeView(String seqID)
+ {
+ int position = -1, i=0;
+
+ for(Msg msg: listMessages)
+ {
+ if(msg.seqID.equals(seqID))
+ position = i;
+
+ i++;
+ }
+
+ if(position != -1 && hash.size() > position)
+ {
+ SM.Debug("POSITON : " + position);
+ View con = hash.get(position);
+ ViewHolder view = (ViewHolder) con.getTag();
+
+ switch(ackPositions.get(position) ? 1 : 0)
+ {
+ case 1:
+ view.imageAck.setVisibility(View.INVISIBLE);
+ view.textViewNotACK.setVisibility(View.INVISIBLE);
+ break;
+ case 0:
+ view.imageAck.setVisibility(View.VISIBLE);
+ view.textViewNotACK.setVisibility(View.VISIBLE);
+ break;
+ }
+ }
+ }
+ */
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/adapters/PadMessagesGridViewAdapter.java b/libSafeMobile/src/main/java/com/safemobile/adapters/PadMessagesGridViewAdapter.java
new file mode 100644
index 0000000..01e309b
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/adapters/PadMessagesGridViewAdapter.java
@@ -0,0 +1,128 @@
+package com.safemobile.adapters;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.Contact;
+import com.safemobile.lib.R;
+import com.safemobile.lib.SM;
+import com.safemobile.libpad.PadTextMessage;
+
+public class PadMessagesGridViewAdapter extends BaseAdapter
+{
+ private ArrayList listMessages;
+ private Activity activity;
+ //public String time;
+ //private int[] colors = new int[] { Color.parseColor("#FFFFFF"), Color.parseColor("#D2E4FC") };
+
+
+ public PadMessagesGridViewAdapter(Activity activity, ArrayList listMessages, Context context) {
+ super();
+ this.activity = activity;
+ this.listMessages = listMessages;
+ }
+
+ @Override
+ public int getCount() {
+ return listMessages.size();
+ }
+
+ @Override
+ public PadTextMessage getItem(int position) {
+ return listMessages.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ /** return the list of messages in the adapter
+ * @return an ArrayList of PadTextMessages
+ */
+ public ArrayList getMessages() {
+ return listMessages;
+ }
+
+ public static class ViewHolder
+ {
+ public ImageView imgViewContact;
+ public TextView txtViewContact;
+ public TextView txtViewDateTime;
+ public TextView txtViewLastMsg;
+ public LinearLayout layoutMessage;
+ }
+
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder view;
+ LayoutInflater inflator = activity.getLayoutInflater();
+
+ if(convertView==null)
+ {
+ view = new ViewHolder();
+ convertView = inflator.inflate(R.layout.row_message, null);
+
+ view.imgViewContact = (ImageView) convertView.findViewById(R.id.imageViewContact);
+ view.txtViewContact = (TextView) convertView.findViewById(R.id.textViewContact);
+ view.txtViewDateTime = (TextView) convertView.findViewById(R.id.textViewLastDate);
+ view.txtViewLastMsg = (TextView) convertView.findViewById(R.id.textViewLastMsg);
+ view.layoutMessage = (LinearLayout) convertView.findViewById(R.id.layoutMessage);
+
+ convertView.setTag(view);
+ }
+ else
+ {
+ view = (ViewHolder) convertView.getTag();
+ }
+
+ try
+ {
+ view.imgViewContact.setImageResource(R.drawable.peopleblue_large);
+ //view.imgViewContact.setImageResource(R.drawable.peopleblue);
+ view.txtViewContact.setText(Contact.getNameForRadioID(AppParams.listContacts, listMessages.get(position).radioID)+ " :");
+ if(listMessages.get(position).message.length() > 25)
+ view.txtViewLastMsg.setText(listMessages.get(position).message.substring(0, 25) + "...");
+ else
+ view.txtViewLastMsg.setText(listMessages.get(position).message);
+
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss",Locale.getDefault());
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(Calendar.HOUR_OF_DAY,0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ Date date = new Date(listMessages.get(position).timeGMT * 1000);
+
+ if(date.after(calendar.getTime()))
+ sdf = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
+ else
+ sdf = new SimpleDateFormat("MMM-dd HH:mm", Locale.getDefault());
+
+ // set gmt time
+ //sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
+
+ view.txtViewDateTime.setText(sdf.format(date));
+ }
+ catch(Exception ex)
+ {
+ SM.Exception(ex.toString());
+ }
+ return convertView;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/adapters/PadRecordingsGridViewAdapter.java b/libSafeMobile/src/main/java/com/safemobile/adapters/PadRecordingsGridViewAdapter.java
new file mode 100644
index 0000000..c8f62dc
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/adapters/PadRecordingsGridViewAdapter.java
@@ -0,0 +1,328 @@
+package com.safemobile.adapters;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.safemobile.activities.AbstractRecordingsActivity;
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.R;
+import com.safemobile.lib.Contact;
+import com.safemobile.lib.SM;
+import com.safemobile.libpad.PadRecording;
+
+public class PadRecordingsGridViewAdapter extends BaseAdapter
+{
+ private ArrayList listRecordings;
+ private ArrayList recordingExists;
+ private ArrayList playingPositions;
+ private Activity activity;
+ private Context context;
+ private int removePosition = -1;
+ //public String time;
+ //private int[] colors = new int[] { Color.parseColor("#FFFFFF"), Color.parseColor("#D2E4FC") };
+ private Hashtable hash = new Hashtable();
+
+ public PadRecordingsGridViewAdapter(Activity activity, Context context, ArrayList listRecordings)
+ {
+ super();
+ this.activity = activity;
+ this.context = context;
+ this.listRecordings = listRecordings;
+
+ this.recordingExists = new ArrayList();
+ for(int i=0; i();
+ for(int i=0; i getRecordings() {
+ return listRecordings;
+ }
+
+ /** Define Row Template */
+ public static class ViewHolder
+ {
+ public LinearLayout layoutRecording;
+ public ImageView imageViewPlay, imageViewRecycle;
+ public TextView textViewSender, textViewDuration, textViewDate;
+ }
+
+ @Override
+ public View getView(final int position, View convertView, ViewGroup parent) {
+ final ViewHolder view;
+ LayoutInflater inflator = activity.getLayoutInflater();
+ if(convertView==null)
+ {
+ view = new ViewHolder();
+ convertView = inflator.inflate(R.layout.row_recordings, null);
+ view.layoutRecording = (LinearLayout) convertView.findViewById(R.id.layoutRecording);
+ view.imageViewPlay = (ImageView) convertView.findViewById(R.id.imageViewPlay);
+ view.textViewSender = (TextView) convertView.findViewById(R.id.textViewSender);
+ view.textViewDuration = (TextView) convertView.findViewById(R.id.textViewDuration);
+ view.textViewDate = (TextView) convertView.findViewById(R.id.textViewDate);
+ view.imageViewRecycle = (ImageView) convertView.findViewById(R.id.imageViewRecycle);
+
+ convertView.setTag(view);
+ }
+ else
+ {
+ view = (ViewHolder) convertView.getTag();
+ }
+
+ hash.put(position, convertView);
+
+ try {
+ //SM.Debug("SIZE EXISTS : " + recordingExists.size() + " | " + playingPositions.size());
+ /* if recording doesn't exists change background */
+ /*
+ if(recordingExists.size()> position && !recordingExists.get(position))
+ view.layoutRecording.setBackgroundColor(0xFFDDDDDD);
+ else
+ */
+
+ if(playingPositions.size() > position)
+ {
+ /* if recording is not playing let background to white */
+
+ if(!playingPositions.get(position))
+ view.layoutRecording.setBackgroundColor(0xFFFFFFFF);
+ else
+ view.layoutRecording.setBackgroundColor(0xFF457c98);
+
+ }
+ else
+ view.layoutRecording.setBackgroundColor(0xFFFFFFFF);
+
+ /* change icon according to call type [outgoing or incoming] */
+ if(listRecordings.size() > position)
+ switch(listRecordings.get(position).callType)
+ {
+ case AppParams.MotoAllCall:
+ if(!listRecordings.get(position).isOutgoing)
+ view.imageViewPlay.setImageResource(R.drawable.call_received_all);
+ else
+ view.imageViewPlay.setImageResource(R.drawable.call_made_all);
+ break;
+ case AppParams.MotoPrivate:
+ if(!listRecordings.get(position).isOutgoing)
+ view.imageViewPlay.setImageResource(R.drawable.call_received);
+ else
+ view.imageViewPlay.setImageResource(R.drawable.call_made);
+ break;
+ case AppParams.MotoGroup:
+ if(!listRecordings.get(position).isOutgoing)
+ view.imageViewPlay.setImageResource(R.drawable.call_received_group);
+ else
+ view.imageViewPlay.setImageResource(R.drawable.call_made_group);
+ break;
+ }
+ }
+ catch(IndexOutOfBoundsException ex) {
+ SM.Exception("IndexOutOfBounds Exception [PadRecordingsGridViewAdapter]" + ex.toString());
+ }
+ /*
+ try
+ {
+ if(receivedPositions.get(position))
+ {
+ if(playingPositions.get(position))
+ view.imageViewPlay.setImageResource(R.drawable.play_received);
+ else
+ view.imageViewPlay.setImageResource(R.drawable.call_received);
+
+ }
+ else
+ {
+ if(playingPositions.get(position))
+ view.imageViewPlay.setImageResource(R.drawable.play_made);
+ else
+ view.imageViewPlay.setImageResource(R.drawable.call_made);
+ }
+ }
+ catch(Exception ex)
+ {
+ SM.Exception("EXCeptioN", ex.toString());
+ view.imageViewPlay.setImageResource(R.drawable.play);
+ }*/
+
+ /* intercept Recycle click */
+ view.imageViewRecycle.setVisibility(View.GONE);
+ view.imageViewRecycle.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // save the position of the marked record
+ removePosition = position;
+
+ // change the background for marked record
+ View view = (View) hash.get(position);
+ ViewHolder viewHolder = (ViewHolder) view.getTag();
+ viewHolder.layoutRecording.setBackgroundColor(0xFF457c98);
+ ((AbstractRecordingsActivity) activity).deleteSelected(position);
+ }
+ });
+
+ String sender = "", name="", initName="";
+
+ for(Contact cont: AppParams.listContacts)
+ {
+ if(cont.id == getItem(position).radioID)
+ {
+ // get name only if callType equals with the one from the ConfigFile
+ if( (getItem(position).callType == AppParams.MotoPrivate && cont.contactType == Contact.PRIVATE)
+ || (getItem(position).callType == AppParams.MotoGroup && cont.contactType == Contact.GROUP)
+ || (getItem(position).callType == AppParams.MotoAllCall))
+ // || getItem(position).type == AppParams.AllCall && cont.callType.equals("All Call"))
+ name = cont.name;
+ }
+ if (cont.id == getItem(position).initRadioID) {
+ // get name only if callType equals with the one from the ConfigFile
+ if( (getItem(position).callType == AppParams.MotoPrivate && cont.contactType == Contact.PRIVATE)
+ || (getItem(position).callType == AppParams.MotoGroup && cont.contactType == Contact.GROUP)
+ || (getItem(position).callType == AppParams.MotoAllCall))
+ // || getItem(position).type == AppParams.AllCall && cont.callType.equals("All Call"))
+ initName = cont.name;
+ }
+
+ // if call type is Group I should find a private
+ if(getItem(position).callType == AppParams.MotoGroup && (cont.id == getItem(position).initRadioID && cont.contactType == Contact.PRIVATE))
+ initName = cont.name;
+
+ }
+
+ // // set name to All Call if call was made from tabled
+ if(getItem(position).callType == AppParams.MotoAllCall && getItem(position).isOutgoing)
+ sender += context.getResources().getString(R.string.AllCall);
+ else if(getItem(position).callType == AppParams.MotoAllCall) {
+ name = context.getResources().getString(R.string.AllCall);
+ if(initName.length() > 0)
+ sender = name + " [" + initName + "]";
+ else
+ sender = name + " [" + getItem(position).initRadioID + "]";
+ }
+ // add the name/id of the contact that initiated the AllCall
+ else if(name.length() < 1)
+ sender += getItem(position).radioID;
+ else
+ sender += name;
+
+ // add caller name for group call
+ if(listRecordings.get(position).callType == AppParams.MotoGroup)
+ {
+ if(!getItem(position).isOutgoing) {
+ if(initName.length() > 0)
+ sender = name + " [" + initName + "]";
+ else
+ sender = name + " [" + getItem(position).initRadioID + "]";
+ }
+ else
+ sender = name;
+ }
+ // for private call that was received I have to get the id from the initRadioID
+ else if(listRecordings.get(position).callType == AppParams.MotoPrivate)
+ {
+ if(!getItem(position).isOutgoing && initName.length()>0)
+ sender = initName;
+ else if (!getItem(position).isOutgoing)
+ sender += getItem(position).initRadioID + "";
+ }
+
+ view.textViewSender.setText(sender);
+ view.textViewDuration.setText("[" + listRecordings.get(position).duration + " sec]");
+
+ /* Add call Date */
+ Date date = new Date(getItem(position).timeGMT * 1000);
+
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
+ Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ calendar.set(Calendar.HOUR_OF_DAY,0);
+ calendar.set(Calendar.MINUTE, 0);
+ calendar.set(Calendar.SECOND, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+
+ if(date.after(calendar.getTime()))
+ sdf = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
+ else
+ sdf = new SimpleDateFormat("MMM-dd HH:mm", Locale.getDefault());
+
+ // set gmt time
+ //sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
+
+ view.textViewDate.setText(sdf.format(date));
+
+ return convertView;
+ }
+
+
+ /** Reset row background when recycle was canceled */
+ public void cancelDelete()
+ {
+ View view = (View) hash.get(removePosition);
+ if(recordingExists.get(removePosition))
+ view.setBackgroundColor(0xFFFFFFFF);
+ else
+ view.setBackgroundColor(0xFFDDDDDD);
+
+ removePosition = -1;
+ }
+
+
+ /** Get the View for one row in the GridView */
+ public View getView(int position)
+ {
+ return (View) hash.get(position);
+ }
+
+
+ /** Change playing recording background */
+ public void changePlaying(int position, boolean playing)
+ {
+ // change value in the vector
+ playingPositions.set(position, playing);
+
+ // make changes in the UI //
+ try {
+ PadRecordingsGridViewAdapter.ViewHolder viewHolder = (PadRecordingsGridViewAdapter.ViewHolder) getView(position).getTag();
+ if(!playing)
+ viewHolder.layoutRecording.setBackgroundColor(0xFFFFFFFF);
+ else
+ viewHolder.layoutRecording.setBackgroundColor(0xFF457c98);
+ }
+ catch (NullPointerException ex) {
+
+ }
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/adapters/RecordingsGridViewAdapter.java b/libSafeMobile/src/main/java/com/safemobile/adapters/RecordingsGridViewAdapter.java
new file mode 100644
index 0000000..caac6da
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/adapters/RecordingsGridViewAdapter.java
@@ -0,0 +1,254 @@
+package com.safemobile.adapters;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.safemobile.activities.AbstractRecordingsActivity;
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.R;
+import com.safemobile.lib.Recording;
+import com.safemobile.lib.Contact;
+import com.safemobile.lib.SM;
+
+public class RecordingsGridViewAdapter extends BaseAdapter
+{
+ private ArrayList listRecordings;
+ private ArrayList recordingExists;
+ private ArrayList playingPositions;
+ private Activity activity;
+ private Context context;
+ private int removePosition = -1;
+ //public String time;
+ //private int[] colors = new int[] { Color.parseColor("#FFFFFF"), Color.parseColor("#D2E4FC") };
+ private Hashtable hash = new Hashtable();
+
+ public RecordingsGridViewAdapter(Activity activity, Context context, ArrayList listRecordings, ArrayList recordingExists)
+ {
+ super();
+ this.activity = activity;
+ this.context = context;
+ this.listRecordings = listRecordings;
+ this.recordingExists = recordingExists;
+
+ playingPositions = new ArrayList();
+ for(int i=0; i listVehicles;
+ private ArrayList disabledVehicles;
+ private ArrayList displayedVehicles;
+ private Activity activity;
+
+ private Hashtable hash = new Hashtable();
+
+ public VehiclesGridViewAdapter(Activity activity, Context context, ArrayList listVehicles, ArrayList disabledVehicles)
+ {
+ super();
+ this.activity = activity;
+ this.listVehicles = listVehicles;
+ this.disabledVehicles = disabledVehicles;
+
+ // set displayed positions to false
+ displayedVehicles = new ArrayList();
+ for(Vehicle veh: listVehicles)
+ {
+ if(AppParams.DEMO && (veh.sc_id == 101 || veh.sc_id == 102))
+ displayedVehicles.add(true);
+ else
+ displayedVehicles.add(false);
+ }
+ }
+
+ @Override
+ public int getCount() {
+ return listVehicles.size();
+ }
+
+ @Override
+ public Vehicle getItem(int position) {
+ return listVehicles.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return 0;
+ }
+
+ /** Define Row Template */
+ public static class ViewHolder
+ {
+ public ImageView imgViewIcon, imgViewChecked;
+ public TextView txtViewName;
+ public LinearLayout layoutVehicle;
+ }
+
+ @Override
+ public View getView(final int position, View convertView, ViewGroup parent) {
+ final ViewHolder view;
+ LayoutInflater inflator = activity.getLayoutInflater();
+ if(convertView==null)
+ {
+ view = new ViewHolder();
+ convertView = inflator.inflate(R.layout.row_vehicle, null);
+
+ view.imgViewIcon = (ImageView) convertView.findViewById(R.id.imageViewIcon);
+ view.txtViewName = (TextView) convertView.findViewById(R.id.textViewName);
+ view.imgViewChecked = (ImageView) convertView.findViewById(R.id.imageViewChecked);
+ view.layoutVehicle = (LinearLayout) convertView.findViewById(R.id.layoutVehicle);
+
+ convertView.setTag(view);
+ }
+ else
+ {
+ view = (ViewHolder) convertView.getTag();
+ }
+
+ hash.put(position, convertView);
+
+ /* if recording disabled change background */
+ try
+ {
+ if(!disabledVehicles.get(position))
+ view.layoutVehicle.setBackgroundColor(0xFFDDDDDD);
+ else
+ view.layoutVehicle.setBackgroundColor(0xFFFFFFFF);
+
+ }
+ catch(IndexOutOfBoundsException ex) {
+ view.layoutVehicle.setBackgroundColor(0xFFFFFFFF);
+ }
+
+ /* set vehicle name and icon */
+ view.imgViewIcon.setImageResource(listVehicles.get(position).getSmallIcon());
+ view.txtViewName.setText(listVehicles.get(position).name);
+
+ /* set checked or not */
+ if(displayedVehicles.get(position))
+ view.imgViewChecked.setImageResource(R.drawable.checked);
+ else
+ view.imgViewChecked.setImageResource(R.drawable.unchecked);
+
+ return convertView;
+ }
+
+
+
+ /** Get the View for one row in the GridView */
+ public View getView(int position)
+ {
+ return (View) hash.get(position);
+ }
+
+ /** Change all vehicles checkBox */
+ public void changeDisplayAll(boolean display)
+ {
+ for(int i=0; i{
+
+ private static final int TYPE_ZONE = 0;
+ private static final int TYPE_CHANNEL = 1;
+ private static final int TYPE_MAX_COUNT = 2;
+
+
+ private Context context;
+ int layoutResourceId;
+ private ArrayList listValues;
+
+ public ZoneChannelComboBoxAdapter(Context context, int textViewResourceId, ArrayList listValues) {
+ super(context, textViewResourceId, listValues);
+ this.context = context;
+ this.layoutResourceId = textViewResourceId;
+ this.listValues = listValues;
+ }
+
+ @Override
+ public View getDropDownView(int position, View convertView, ViewGroup parent) {
+ return getCustomView(position, convertView, parent);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ return getCustomView(position, convertView, parent);
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return listValues.get(position).isSection() ? TYPE_ZONE : TYPE_CHANNEL;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return TYPE_MAX_COUNT;
+ }
+
+ @Override
+ public int getCount() {
+ return listValues.size();
+ }
+
+ @Override
+ public ZoneChannel getItem(int position) {
+ return listValues.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ if(getItemViewType(position) == TYPE_ZONE)
+ return false;
+ return true;
+ }
+
+
+ public View getCustomView(int position, View convertView, ViewGroup parent) {
+ ImagesSpinnerHolder holder = null;
+ int type = getItemViewType(position);
+ LayoutInflater inflater = ((Activity) context).getLayoutInflater();
+
+ if(convertView == null) {
+ holder = new ImagesSpinnerHolder();
+
+ switch (type) {
+ case TYPE_ZONE:
+ convertView = inflater.inflate(R.layout.combobox_section_header, parent, false);
+ holder.title = (TextView) convertView.findViewById(R.id.txtHeader);
+ break;
+
+ case TYPE_CHANNEL:
+ convertView = inflater.inflate(R.layout.combobox_row, parent, false);
+ holder.textSpinner = (TextView)convertView.findViewById(R.id.text);
+ holder.imgSpinner = (ImageView)convertView.findViewById(R.id.icon);
+ holder.imgSpinner.setVisibility(View.GONE);
+ break;
+
+ }
+
+ convertView.setTag(holder);
+ }
+ else
+ holder = (ImagesSpinnerHolder) convertView.getTag();
+
+ switch(type) {
+ case TYPE_ZONE:
+ holder.title.setText(listValues.get(position).getZone().ZoneName);
+
+ break;
+
+ case TYPE_CHANNEL:
+ holder.textSpinner.setText(listValues.get(position).getChannel().chName);
+ holder.imgSpinner.setImageResource(R.drawable.channel_small);
+ break;
+ }
+
+ /*
+
+
+ View row = convertView;
+
+
+ if(row == null) {
+ // check if section header -> isSection will return true
+ if(sectionList.get(position))
+ {
+ row = inflater.inflate(R.layout.spinner_header, parent, false);
+ holder.title = (TextView) row.findViewById(R.id.txtHeader);
+ holder.title.setText(listValues.get(position).getZone().ZoneName);
+ }
+ else
+ {
+ row = inflater.inflate(R.layout.spinner, parent, false);
+ holder.textSpinner = (TextView)row.findViewById(R.id.language);
+ holder.imgSpinner = (ImageView)row.findViewById(R.id.icon);
+ holder.imgSpinner.setVisibility(View.INVISIBLE);
+
+ holder.textSpinner.setText(listValues.get(position).getChannel().chName);
+ holder.imgSpinner.setImageResource(R.drawable.channel_small);
+ }
+
+ row.setTag(holder);
+ }
+ else {
+
+ holder = (ImagesSpinnerHolder)row.getTag();
+ if(sectionList.get(position)){
+ if(holder.title!= null)
+ holder.title.setText(listValues.get(position).getZone().ZoneName);
+ }
+ else {
+ if(holder.textSpinner!=null)
+ holder.textSpinner.setText(listValues.get(position).getChannel().chName);
+ if(holder.imgSpinner != null)
+ holder.imgSpinner.setImageResource(R.drawable.channel_small);
+ }
+ }
+ */
+ return convertView;
+ }
+
+ private class ImagesSpinnerHolder {
+ ImageView imgSpinner;
+ TextView textSpinner;
+ TextView title;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/bluetooth/BlueEvent.java b/libSafeMobile/src/main/java/com/safemobile/bluetooth/BlueEvent.java
new file mode 100644
index 0000000..f54413b
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/bluetooth/BlueEvent.java
@@ -0,0 +1,24 @@
+package com.safemobile.bluetooth;
+
+import java.util.EventObject;
+public class BlueEvent extends EventObject {
+
+ private static final long serialVersionUID = -7646259130917916952L;
+ private int PTTclicked;
+ private int Connected;
+ public BlueEvent (Object source, int _PTTclicked, int _connected) {
+ super(source);
+ PTTclicked =_PTTclicked;
+ Connected = _connected;
+ }
+
+ public int PTTclicked()
+ {
+ return PTTclicked;
+ }
+
+ public int Connected()
+ {
+ return Connected;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/bluetooth/BluetoothTether.java b/libSafeMobile/src/main/java/com/safemobile/bluetooth/BluetoothTether.java
new file mode 100644
index 0000000..7cbde16
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/bluetooth/BluetoothTether.java
@@ -0,0 +1,525 @@
+package com.safemobile.bluetooth;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.UUID;
+
+import com.safemobile.bluetooth.BlueEvent;
+import com.safemobile.bluetooth.IBlueListener;
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.R;
+import com.safemobile.lib.SM;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.BluetoothSocket;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.media.AudioManager;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Handler;
+import android.util.Log;
+import android.widget.Toast;
+
+@TargetApi(Build.VERSION_CODES.HONEYCOMB)
+public class BluetoothTether {
+
+ private Context mContext;
+ private Activity activity;
+ private AudioManager audioManager;
+
+ private BluetoothAdapter bluetoothAdapter;
+ private BluetoothHeadset bluetoothHeadset = null;
+ private BluetoothDevice bluetoothDevice= null;
+
+ /* For bluComm Microphone */
+ private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
+ private List _listeners = new ArrayList();
+ private Thread bluCommThread = null;
+ private int bluetoothProfile;
+ private BluetoothProfile bluetoothProxy;
+ private BluetoothSocket bluetoothSocket = null;
+ private InputStream inputStream =null;
+ private Boolean socketIsConnected = false;
+
+ public BluetoothTether(Context context, Activity activity) {
+ this.mContext = context;
+ this.activity = activity;
+
+ audioManager = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
+ bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ bluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
+
+ IntentFilter filter1 = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
+ IntentFilter filter2 = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
+ IntentFilter filter3 = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
+
+ activity.registerReceiver(mReceiver, filter1);
+ activity.registerReceiver(mReceiver, filter2);
+ activity.registerReceiver(mReceiver, filter3);
+
+ filter3 = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
+ activity.registerReceiver(mReceiver, filter3);
+ }
+
+ private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
+ @Override
+ public void onServiceDisconnected(int profile) {
+
+ }
+
+ @Override
+ public void onServiceConnected(int profile, BluetoothProfile proxy) {
+
+ SM.Debug("###BluetoothProfile###", "###Connected###");
+ bluetoothProfile = profile;
+ bluetoothProxy = proxy;
+
+ if(profile == BluetoothProfile.HEADSET)
+ {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ bluetoothHeadset = (BluetoothHeadset) proxy;
+ List test;
+ test = bluetoothHeadset.getConnectedDevices();
+ SM.Debug("###BluetoothProfile###", "Headset Connected devices nr: " + test.size());
+ // check if one of three headsets are connected
+
+ for(BluetoothDevice dev : test)
+ bluetoothDevice = dev;
+ /*
+ if(dev.getAddress().contains(AppParams.MotorolaH730) ||
+ dev.getAddress().contains(AppParams.SamsungWep460) || dev.getAddress().contains(AppParams.BluCom))
+ bluetoothDevice = dev;
+ */
+
+ if(bluetoothDevice!=null)
+ {
+ if(AppParams.TETHERSOUND)
+ {
+ SM.Debug("###BluetoothProfile###", "Device : " + bluetoothDevice.getName() + " [" + bluetoothDevice.getAddress() + "]");
+ new Handler().post(new Runnable() {
+ @Override
+ public void run() {
+ Toast.makeText(mContext,
+ String.format(mContext.getString(R.string.bthDeviceConnected), bluetoothDevice.getName()), Toast.LENGTH_SHORT).show();
+ TetherSound(bluetoothDevice, true);
+
+ //*
+
+ SM.Debug("### blueComm ###", "BLUEcOMMFunction");
+ new connectTask().execute();
+ //blueCommFunction(bluetoothProfile, bluetoothProxy);
+
+ _fireBluetoothTethered(true);
+
+ final Timer t = new Timer();
+ t.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ // start thread that will manage bluComm button press
+ bluCommThread = new Thread(bluCommRunnable);
+ bluCommThread.start();
+ t.cancel();
+ t.purge();
+ }
+ }, 2500);
+ //*/
+ }
+ });
+ }
+ }
+ }
+ }
+ };
+
+
+ /** Function that will intercept bluComm button press */
+ private void blueCommFunction(int profile, BluetoothProfile proxy) {
+ //Boolean result = true;
+ SM.Debug("################");
+ if(profile == BluetoothProfile.HEADSET)
+ {
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ // if device connected -> redundant check
+ if(bluetoothDevice != null)
+ {
+ SM.Debug("###HEADSET###","Connected Device Address: " + bluetoothDevice.getAddress());
+
+ final Timer t = new Timer();
+ t.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ try {
+ if(bluetoothDevice!=null)
+ {
+ // create socket and then connect to it
+ bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(MY_UUID);
+ bluetoothSocket.connect();
+ inputStream = bluetoothSocket.getInputStream();
+ SM.Debug("##BTSocketConnected##", "Connection socket ok");
+ socketIsConnected = true;
+ t.cancel();
+ t.purge();
+ }
+ else
+ {
+ t.cancel();
+ t.purge();
+ }
+ }
+ catch (IOException e) {
+ //result = false;
+ //SM.Exception("###BTSocketError###", e.toString());
+ socketIsConnected = false;
+ if(bluetoothSocket!=null)
+ try {
+ bluetoothSocket.close();
+ bluetoothSocket = null;
+ }
+ catch (IOException e1) {
+ SM.Exception("###BTSocketError2###", e.toString());
+ }
+ }
+
+ try {
+
+ Thread.sleep(1000);
+
+ SM.Debug("BTSocketCreated", "bluetooth socket creation ended with result: " + socketIsConnected);
+ /*
+ if(result)
+ _fireDataArrived(blueSOCKET,-1);
+ else
+ _fireDataArrived(noBlueSOCKET,-1);
+ */
+ }
+ catch (InterruptedException e) {
+ SM.Exception("###BTSocketInterruptedException###", e.toString());
+ }
+ }
+ }, 500, 3000);
+
+ }
+ }
+
+ };
+
+
+ /** Runnable to intercept bluComm button press */
+ private Runnable bluCommRunnable = new Runnable() {
+
+ @Override
+ public void run() {
+ SM.Debug("####HERE####", "after Profile");
+
+ int read = 0;
+ byte[] buffer = new byte[20];
+
+ while(true)
+ {
+ try
+ {
+ while (socketIsConnected)
+ {
+
+ //SM.Debug("####Socket####", "Socket is Connected");
+ try
+ {
+ //Log.d("DECIVE STATUS", bhead.getConnectionState(mybluedev) + "");
+ read = inputStream.read(buffer);
+ /*
+ String buf = "";
+ for(int k=0;k10)
+ {
+ _fireDataArrived(-1,0);
+ Disconect();
+ }
+ */
+ }
+ }
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ Log.d("bigutag", "Error on");
+ }
+ }
+ }
+ };
+
+
+ /** BroadcastReceiver that will manage BlueTooth Connection and Disconnection */
+ public final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ if(device!=null)
+ Log.d("BlueTooth State Changed", "DEVICE " + device.getName() + " [" + device.getAddress() + "]" + " is now : " + action );
+
+ // Tether sound only if selected in setup
+ if(AppParams.TETHERSOUND)
+ {
+ if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
+ if(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1) == BluetoothAdapter.STATE_OFF)
+ untetherSound(bluetoothDevice);
+ }
+ else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
+ Toast.makeText(mContext, mContext.getString(R.string.bthDeviceFound) + ":" + bluetoothDevice.getName(), Toast.LENGTH_SHORT).show();
+
+ }
+ else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
+ //Toast.makeText(mContext, "Done searching", Toast.LENGTH_SHORT).show();
+ }
+ else
+ if(device.getAddress()!= null) /* && (device.getAddress().contains(AppParams.MotorolaH730) ||
+ device.getAddress().contains(AppParams.SamsungWep460) || device.getAddress().contains(AppParams.BluCom)))*/
+ {
+ // save device
+ bluetoothDevice = device;
+
+ // if bluetooth device has disconnected
+ if(action.contains("_DISCONNECTED"))
+ {
+ untetherSound(device);
+ }
+ // if bluetooth device had connected
+ else
+ {
+ new Handler().post(new Runnable()
+ {
+ @Override
+ public void run() {
+ Toast.makeText(mContext,
+ String.format(mContext.getString(R.string.bthDeviceConnected), bluetoothDevice.getName()), Toast.LENGTH_SHORT).show();
+ // set that bluComm Microphone is connected
+ if(bluetoothDevice != null)
+ {
+ TetherSound(bluetoothDevice, true);
+
+ if(bluetoothDevice.getAddress().contains(AppParams.BluCom))
+ {
+ AppParams.BluCommState = 1;
+ //TetherSound(bluetoothDevice, true);
+
+ _fireBluetoothTethered(true);
+
+ // create bluComm socket
+ new connectTask().execute();
+
+ /*
+ * if bluComm is not connected when RadioPad starts i will need
+ * to create the Thread that reads on socket
+ */
+
+ if(bluCommThread == null)
+ {
+ final Timer t = new Timer();
+ t.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ SM.Exception("bluComm", "creating blu comm thread");
+ // start thread that will manage bluComm button press
+ bluCommThread = new Thread(bluCommRunnable);
+ bluCommThread.start();
+ t.cancel();
+ t.purge();
+ }
+ }, 2500);
+ }
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * UnTether all the sound when a device is disconnected or then the BlueTooth is turned off
+ * @param device The BlueTooth device which needs to be unTethered
+ */
+ private void untetherSound(final BluetoothDevice device) {
+ new Handler().post(new Runnable() {
+ @Override
+ public void run() {
+ if(device == null)
+ return;
+
+ Toast.makeText(mContext,
+ String.format(mContext.getString(R.string.bthDeviceDisconnected),
+ (bluetoothDevice.getName() == null ? "?" : bluetoothDevice.getName())), Toast.LENGTH_SHORT).show();
+
+ _fireBluetoothTethered(false);
+ // set that bluComm Microphone is disconnected
+ if(bluetoothDevice!=null && bluetoothDevice.getAddress().contains(AppParams.BluCom))
+ AppParams.BluCommState = 0;
+ socketIsConnected = false;
+ Disconect();
+
+ TetherSound(device, false);
+ }
+ });
+ }
+
+ /** Unregister BroadcastReceiver **/
+ public void UnregisterReceiver()
+ {
+ try
+ {
+ if(mReceiver!=null && activity!=null)
+ {
+ SM.Debug("#### unregister Receiver ### ", "unregister receiver");
+ activity.unregisterReceiver(mReceiver);
+ }
+
+ if(mProfileListener!=null)
+ activity.unbindService((ServiceConnection) mProfileListener);
+ }
+ catch(Exception ex)
+ {
+
+ }
+ }
+
+
+ /** Tether sound */
+ private void TetherSound(final BluetoothDevice device, Boolean enable)
+ {
+ if(enable && AppParams.TETHERSOUND)
+ {
+ final Timer t = new Timer();
+ t.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ SM.Debug("### Start Tethering ###", "tethering " + device.getName());
+ audioManager.setBluetoothScoOn(true);
+ audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
+ audioManager.startBluetoothSco();
+ t.cancel();
+ t.purge();
+ }
+ }, 2000);
+ }
+ else
+ {
+ audioManager.stopBluetoothSco();
+ audioManager.setMode(AudioManager.MODE_NORMAL);
+ socketIsConnected = false;
+ }
+ }
+
+
+ /** Stop BluetoothTether and unregister BroadcastReceiver */
+ public void Stop()
+ {
+ TetherSound(null, false);
+ UnregisterReceiver();
+ Disconect();
+ }
+
+ public void Disconect()
+ {
+ try
+ {
+ if(bluetoothSocket!=null)
+ bluetoothSocket.close();
+ socketIsConnected = false;
+ socketIsConnected = false;
+ bluetoothDevice = null;
+ bluetoothSocket = null;
+ //bhead.stopVoiceRecognition(mybluedev);
+ //_fireDataArrived(-1,0);
+ }
+ catch (Exception e)
+ {
+ socketIsConnected = false;
+ bluetoothDevice = null;
+ bluetoothSocket = null;
+ SM.Exception("##BTDisconnectError",e.toString());
+ }
+ }
+
+
+ public synchronized void addBlueListener( IBlueListener l ) {
+ _listeners.add( l );
+ }
+
+ public synchronized void removeBlueListener( IBlueListener l ) {
+ _listeners.remove( l );
+ }
+
+ private synchronized void _fireDataArrived(int PTTClicked, int Connected)
+ {
+ BlueEvent event = new BlueEvent( this,PTTClicked,Connected);
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (IBlueListener) listeners.next() ).dataRecv(event);
+ }
+ }
+
+ private synchronized void _fireBluetoothTethered (boolean isTethered) {
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (IBlueListener) listeners.next() ).bluetoothTethered(isTethered);;
+ }
+ }
+
+ public class connectTask extends AsyncTask
+ {
+
+ @Override
+ protected Void doInBackground(String... params) {
+ SM.Debug("### blueComm ###", "recreate bluComm socket");
+ blueCommFunction(bluetoothProfile, bluetoothProxy);
+ return null;
+ }
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/bluetooth/IBlueListener.java b/libSafeMobile/src/main/java/com/safemobile/bluetooth/IBlueListener.java
new file mode 100644
index 0000000..9f357cf
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/bluetooth/IBlueListener.java
@@ -0,0 +1,6 @@
+package com.safemobile.bluetooth;
+
+public interface IBlueListener {
+ public void dataRecv( BlueEvent event );
+ public void bluetoothTethered (boolean isTethered);
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/database/DataBaseHelper.java b/libSafeMobile/src/main/java/com/safemobile/database/DataBaseHelper.java
new file mode 100644
index 0000000..c69b305
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/database/DataBaseHelper.java
@@ -0,0 +1,159 @@
+package com.safemobile.database;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import com.safemobile.lib.AppParams;
+
+import android.content.Context;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class DataBaseHelper extends SQLiteOpenHelper{
+
+ //The Android's default system path of your application database.
+ private static String DB_PATH = "/data/data/com.safemobile.motopad/databases/";
+
+ private static String DB_NAME = "safedispatch" + AppParams.Database;
+
+ private SQLiteDatabase myDataBase;
+
+ private final Context myContext;
+
+ /**
+ * Constructor
+ * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
+ * @param context
+ */
+ public DataBaseHelper(Context context) {
+
+ super(context, DB_NAME, null, 1);
+ this.myContext = context;
+ DB_PATH = "/data/data/" + context.getPackageName().toString() + "/databases/";
+ }
+
+ /**
+ * Creates a empty database on the system and rewrites it with your own database.
+ * */
+ public void createDataBase() throws IOException{
+
+ boolean dbExist = checkDataBase();
+
+ if(dbExist){
+ //do nothing - database already exist
+ }else{
+
+ //By calling this method and empty database will be created into the default system path
+ //of your application so we are gonna be able to overwrite that database with our database.
+ this.getReadableDatabase();
+
+ try {
+
+ copyDataBase();
+
+ } catch (IOException e) {
+
+ throw new Error("Error copying database");
+
+ }
+ }
+
+ }
+
+ /**
+ * Check if the database already exist to avoid re-copying the file each time you open the application.
+ * @return true if it exists, false if it doesn't
+ */
+ private boolean checkDataBase(){
+
+ SQLiteDatabase checkDB = null;
+
+ try{
+ String myPath = DB_PATH + DB_NAME;
+ checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
+
+ }catch(SQLiteException e){
+
+ //database does't exist yet.
+
+ }
+
+ if(checkDB != null){
+
+ checkDB.close();
+
+ }
+
+ return checkDB != null ? true : false;
+ }
+
+ /**
+ * Copies your database from your local assets-folder to the just created empty database in the
+ * system folder, from where it can be accessed and handled.
+ * This is done by transfering bytestream.
+ * */
+ private void copyDataBase() throws IOException{
+
+ //Open your local db as the input stream
+ InputStream myInput = myContext.getAssets().open(DB_NAME);
+
+ // Path to the just created empty db
+ String outFileName = DB_PATH + DB_NAME;
+
+ //Open the empty db as the output stream
+ OutputStream myOutput = new FileOutputStream(outFileName);
+
+ //transfer bytes from the inputfile to the outputfile
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = myInput.read(buffer))>0){
+ myOutput.write(buffer, 0, length);
+ }
+
+ //Close the streams
+ myOutput.flush();
+ myOutput.close();
+ myInput.close();
+
+ }
+
+ public SQLiteDatabase openDataBase(Boolean readonly) throws SQLException{
+
+ //Open the database
+ String myPath = DB_PATH + DB_NAME;
+ if(readonly)
+ return myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
+ else
+ return myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
+
+ }
+
+ @Override
+ public synchronized void close() {
+
+ if(myDataBase != null)
+ myDataBase.close();
+
+ super.close();
+
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+
+ }
+
+ // Add your public helper methods to access and get content from the database.
+ // You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
+ // to you to create adapters for your views.
+
+}
\ No newline at end of file
diff --git a/libSafeMobile/src/main/java/com/safemobile/database/DatabaseCommunication.java b/libSafeMobile/src/main/java/com/safemobile/database/DatabaseCommunication.java
new file mode 100644
index 0000000..7049f6e
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/database/DatabaseCommunication.java
@@ -0,0 +1,639 @@
+package com.safemobile.database;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import com.safemobile.lib.Contact;
+import com.safemobile.lib.Recording;
+import com.safemobile.lib.SM;
+import com.safemobile.lib.SMS;
+import com.safemobile.lib.Vehicle;
+import com.safemobile.lib.radio.Channel;
+import com.safemobile.lib.radio.Zone;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.provider.BaseColumns;
+import android.util.Log;
+
+public class DatabaseCommunication {
+ /* Database */
+ private SQLiteDatabase database;
+ private DataBaseHelper myDbHelper;
+ private boolean first = false, READONLY = false;;
+ private Context context;
+
+ public DatabaseCommunication(Context context)
+ {
+ this.context = context;
+ }
+
+
+ // open database Connection
+ public void openConnection()
+ {
+ // start database connection
+ myDbHelper = new DataBaseHelper(context);
+ try
+ {
+ myDbHelper.createDataBase();
+ Log.d("CONNECT", "Succes connection");
+ }
+ catch (IOException ioe)
+ {
+ throw new Error("Unable to create database");
+ }
+ // end database connection
+
+ myDbHelper = new DataBaseHelper(context);
+
+ try {
+ if(database!=null)
+ database.close();
+ database = myDbHelper.openDataBase(READONLY);
+ Log.d("CONNECT", "Opened Connection");
+
+ }catch(SQLException sqle){
+ first = true;
+ //throw sqle;
+ }
+
+ if(first)
+ {
+ try {
+ if(database!=null)
+ database.close();
+ database = myDbHelper.openDataBase(READONLY);
+ Log.d("CONNECT", "Opened Connection");
+
+ }catch(SQLException sqle){
+ first = false;
+ //throw sqle;
+ }
+ }
+ }
+
+ // close database Connection
+ public void closeConnection()
+ {
+ database.close();
+ }
+
+ public boolean isOpen()
+ {
+ if(database!=null)
+ return database.isOpen();
+ else
+ return false;
+ }
+
+ // get all vehicles
+ public ArrayList getAllVehicle()
+ {
+ ArrayList allVehicles = new ArrayList();
+
+ // build iterator
+ Cursor cursor = null;
+ if(database == null)
+ Log.d("NULL", "Database is null");
+ else
+ {
+ cursor = database.rawQuery("SELECT * from vehicle",new String [] {});
+ Log.d("CURSOR", "cursor created");
+
+ cursor.moveToFirst();
+ while (cursor.isAfterLast() == false)
+ {
+ //old = new Vehicle(int lp, String name, long driver_id, int time_route, int GPS_reporting_interval, int is_stolen)
+ // new = Vehicle(int sc_id, String imei, int lp, String name, long driver_id, int time_route, int GPS_reporting_interval, int is_stolen)
+ allVehicles.add(new Vehicle(0, "imei", cursor.getInt(1), cursor.getString(2), cursor.getInt(3), cursor.getInt(4), cursor.getInt(5), cursor.getInt(6)));
+ // move to next record
+ cursor.moveToNext();
+ }
+ cursor.close();
+ }
+ allVehicles.add(new Vehicle(0, "imei", 1, "Demo103", 89, 0, 0, 0));
+ allVehicles.add(new Vehicle(0, "imei", 1, "Demo104", 101, 0, 0, 0));
+ allVehicles.add(new Vehicle(0, "imei", 1, "Demo105", 95, 0, 0, 0));
+ allVehicles.add(new Vehicle(0, "imei", 1, "Demo106", 118, 0, 0, 0));
+ allVehicles.add(new Vehicle(0, "imei", 1, "Demo107", 111, 0, 0, 0));
+
+ return allVehicles;
+ }
+
+
+ // get all users
+ public ArrayList getAllSMS()
+ {
+ ArrayList allSMS = new ArrayList();
+ Cursor cursor = null;
+ if(database == null)
+ SM.Debug("DBQuery","Database is null");
+ else
+ {
+ cursor = database.rawQuery("SELECT _id, timeGMT, imei_sour, imei_dest, mess, status from SMS",new String [] {});
+ cursor.moveToFirst();
+ while (cursor.isAfterLast() == false)
+ {
+ SMS sms = new SMS();//cursor.getInt(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4), cursor.getInt(5), cursor.getInt(6));
+ sms.idx =cursor.getInt(0);
+ sms.timeGMT = cursor.getInt(1);
+ sms.sc_id_sour = cursor.getInt(2);
+ sms.sc_id_dest = cursor.getInt(3);
+ sms.mess = cursor.getString(4);
+ sms.status = cursor.getInt(5);
+ sms.seq_idx = "";
+
+ allSMS.add(sms);
+ // move to next record
+ cursor.moveToNext();
+ }
+ cursor.close();
+ }
+ return allSMS;
+ }
+
+ public ArrayList getSMS_4Imei(long imei)
+ {
+ ArrayList allSMS = new ArrayList();
+ Cursor cursor = null;
+ if(database == null)
+ SM.Debug("DBQuery","Database is null");
+ else
+ {
+ cursor = database.rawQuery("SELECT _id, timeGMT, imei_sour, imei_dest, mess, status from SMS where imei_sour ="+imei+" OR imei_dest ="+imei+" ORDER BY timeGMT ASC",new String [] {});
+ cursor.moveToFirst();
+ while (cursor.isAfterLast() == false)
+ {
+ SMS sms = new SMS();
+ sms.idx =cursor.getInt(0);
+ sms.timeGMT = cursor.getInt(1);
+ sms.sc_id_sour = cursor.getInt(2);
+ sms.sc_id_dest = cursor.getInt(3);
+ sms.mess = cursor.getString(4);
+ sms.status = cursor.getInt(5);
+ sms.seq_idx = "";
+
+ allSMS.add(sms);
+ // move to next record
+ cursor.moveToNext();
+ }
+ cursor.close();
+ }
+ return allSMS;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public ArrayList getAllLastSMS()
+ {
+ ArrayList allLastSMS = new ArrayList();
+ Cursor cursor = null;
+ if(database == null)
+ SM.Debug("DBQuery","Database is null");
+ else
+ {
+ ArrayList imeis= new ArrayList();
+ cursor = database.rawQuery("SELECT B.imei FROM (SELECT DISTINCT imei_sour AS imei FROM SMS WHERE imei_sour>0 UNION SELECT DISTINCT imei_dest AS imei FROM SMS WHERE imei_dest>0) AS B",new String [] {});
+ cursor.moveToFirst();
+ while (cursor.isAfterLast() == false)
+ {
+ /*
+ Integer imei_sour =cursor.getInt(0);
+ Integer imei_dest = cursor.getInt(1);
+
+ if(imei_sour != 0)
+ if(!imeis.contains(imei_sour))
+ {
+ imeis.add(imei_sour);
+ }
+ if(imei_dest != 0)
+ if(!imeis.contains(imei_dest))
+ {
+ imeis.add(imei_dest);
+ }
+ */
+ imeis.add(cursor.getInt(0));
+ // move to next record
+ cursor.moveToNext();
+ }
+ cursor.close();
+
+ for(Integer imei:imeis)
+ {
+ ArrayList smss = getSMS_4Imei(imei);
+ if(smss.size() > 0)
+ allLastSMS.add(smss.get(smss.size() - 1));
+ }
+
+ Collections.sort(allLastSMS, new Comparator(){
+
+ public int compare(Object o1, Object o2) {
+ SMS sms1 = (SMS) o1;
+ SMS sms2 = (SMS) o2;
+ if(sms1.timeGMT < sms2.timeGMT)
+ return -1;
+ else if (sms1.timeGMT > sms2.timeGMT)
+ return 1;
+ else
+ return 0;
+ // return sms1.timeGMT.compareToIgnoreCase(p2.getFirstName());
+ }
+
+ });
+
+ }
+ return allLastSMS;
+ }
+
+ public boolean insertSMS(SMS sms)
+ {
+ long id = -1;
+ if(database == null)
+ SM.Debug("DBQuery","Database is null");
+ else
+ {
+ ContentValues values = new ContentValues();
+ values.put("timeGMT", sms.timeGMT);
+ values.put("imei_sour", sms.sc_id_sour);
+ values.put("imei_dest", sms.sc_id_dest);
+ values.put("mess", sms.mess);
+ values.put("status", sms.status);
+ id = database.insert("SMS", "", values); //.rawQuery("SELECT imei_sour, imei_dest from SMS",new String [] {});
+ SM.Debug("DBQuery","Database Insert result: " + id);
+ }
+ //INSERT into SMS (timeGMT, imei_sour, imei_dest, mess, status) VALUES( 1324016412, 0, 101, 'two', 1)
+ return (id == -1)? false: true;
+ }
+
+
+ // get all users
+ public ArrayList getAllRecordings()
+ {
+ ArrayList allRecordings = new ArrayList();
+ Cursor cursor = null;
+ if(database == null)
+ SM.Debug("DBQuery","Database is null");
+ else
+ {
+ cursor = database.rawQuery("SELECT _id, id_sour, id_dest, date, duration, filename, type from Recordings order by _id desc",new String [] {});
+ cursor.moveToFirst();
+ while (cursor.isAfterLast() == false)
+ {
+ Recording rec = new Recording();
+ rec.ID =cursor.getInt(0);
+ rec.sourceRadioID = cursor.getInt(1);
+ rec.destinationRadioID = cursor.getInt(2);
+ rec.date = cursor.getInt(3);
+ rec.duration = cursor.getInt(4);
+ rec.filename = cursor.getString(5);
+ rec.type = cursor.getInt(6);
+
+ allRecordings.add(rec);
+ // move to next record
+ cursor.moveToNext();
+ }
+ cursor.close();
+ }
+ return allRecordings;
+ }
+
+ // get all users
+ public Recording getLastRecording()
+ {
+ Cursor cursor = null;
+ if(database == null)
+ SM.Debug("DBQuery","Database is null");
+ else
+ {
+ cursor = database.rawQuery("SELECT _id, id_sour, id_dest, date, duration, filename, type from Recordings order by _id desc",new String [] {});
+ cursor.moveToFirst();
+ if(cursor.getCount() > 0)
+ {
+ Recording rec = new Recording();
+ rec.ID =cursor.getInt(0);
+ rec.sourceRadioID = cursor.getInt(1);
+ rec.destinationRadioID = cursor.getInt(2);
+ rec.date = cursor.getInt(3);
+ rec.duration = cursor.getInt(4);
+ rec.filename = cursor.getString(5);
+ rec.type = cursor.getInt(6);
+ return rec;
+ }
+ }
+ return null;
+ }
+
+
+ public long insertRecording(Recording rec)
+ {
+ long id = -1;
+ if(database == null)
+ SM.Debug("Database is null");
+ else
+ {
+ ContentValues values = new ContentValues();
+ values.put("id_sour", rec.sourceRadioID);
+ values.put("id_dest", rec.destinationRadioID);
+ values.put("date", rec.date);
+ values.put("duration", rec.duration);
+ values.put("filename", rec.filename);
+ values.put("type", rec.type);
+ id = database.insert("Recordings", "", values); //.rawQuery("SELECT imei_sour, imei_dest from SMS",new String [] {});
+ SM.Debug("DBQuery","Database Insert result: " + id);
+ }
+ //INSERT into SMS (timeGMT, imei_sour, imei_dest, mess, status) VALUES( 1324016412, 0, 101, 'two', 1)
+ return id;
+ }
+
+ public boolean removeRecording(Recording rec)
+ {
+ long id = -1;
+ if(database == null)
+ SM.Debug("Database is null");
+ else
+ {
+ ContentValues values = new ContentValues();
+ values.put("id_sour", rec.sourceRadioID);
+ values.put("id_dest", rec.destinationRadioID);
+ values.put("date", rec.date);
+ values.put("duration", rec.duration);
+ values.put("filename", rec.filename);
+ values.put("type", rec.type);
+ id = database.delete("Recordings", "_id=" + rec.ID, null);
+ SM.Debug("DBQuery","Database Remove result: " + id);
+ }
+ //INSERT into SMS (timeGMT, imei_sour, imei_dest, mess, status) VALUES( 1324016412, 0, 101, 'two', 1)
+ return (id == -1)? false: true;
+ }
+
+
+ // get all Contacts
+ public ArrayList getAllContacts(boolean TRBO)
+ {
+ ArrayList allContacts = new ArrayList();
+ Cursor cursor = null;
+ if(database == null)
+ SM.Debug("DBQuery","Database is null");
+ else
+ {
+ try
+ {
+ cursor = database.rawQuery("SELECT _id, call_id, name, call_type from contacts order by call_id asc",new String [] {});
+ if(cursor!=null)
+ {
+ cursor.moveToFirst();
+ while (cursor.isAfterLast() == false)
+ {
+ Contact contact = new Contact();
+ contact.id = cursor.getInt(1);
+ contact.name = cursor.getString(2);
+ String type = cursor.getString(3);
+ if(type.equals("Private Call"))
+ contact.contactType = Contact.PRIVATE;
+ else if (type.equals("Group Call"))
+ contact.contactType = Contact.GROUP;
+
+ allContacts.add(contact);
+ // move to next record
+ cursor.moveToNext();
+ }
+ cursor.close();
+ }
+ }
+ catch(Exception ex)
+ {
+ // table doesn't exist so I have to create and populate it
+ createContactsTable();
+ populateContactsTable(TRBO);
+ }
+ }
+ return allContacts;
+ }
+
+
+ // get all Contacts
+ public ArrayList getAllZones(boolean TRBO)
+ {
+ ArrayList allZones = new ArrayList();
+ Cursor cursor = null;
+ if(database == null)
+ SM.Debug("DBQuery","Database is null");
+ else
+ {
+ try
+ {
+ cursor = database.rawQuery("SELECT _id, position, name, type, zone_id from zonechannel order by zone_id asc, type desc",new String [] {});
+ if(cursor!=null)
+ {
+ cursor.moveToFirst();
+ ArrayList listChannels = new ArrayList();
+
+ while (cursor.isAfterLast() == false)
+ {
+ // add zone to list
+ if(cursor.getString(3).equals("zone"))
+ {
+ Zone z = new Zone();
+ z.channelList = new ArrayList();
+ z.dbID = cursor.getInt(1);
+ z.ZoneName = cursor.getString(2);
+ z.id = cursor.getInt(4);
+
+ // add channels to zone
+ z.channelList = listChannels;
+
+ // clear channels list
+ listChannels = new ArrayList();
+
+ // add zone
+ allZones.add(z);
+
+ }
+ else
+ {
+ // add channel to corresponding list
+ Channel c = new Channel();
+ c.id = cursor.getInt(1);
+ c.chName = cursor.getString(2);
+ c.id = cursor.getInt(1);
+
+ // add channel to zone if exists or add it to the list
+ for(Zone zone: allZones)
+ {
+ // if channel is in this zone
+ if(zone.id == cursor.getInt(4))
+ {
+ // create list if not exists
+ if(zone.channelList == null)
+ zone.channelList = new ArrayList();
+
+ // add channel to list;
+ zone.channelList.add(c);
+ }
+ }
+ }
+
+ // move to next record
+ cursor.moveToNext();
+ }
+ cursor.close();
+ }
+ }
+ catch(Exception ex)
+ {
+ // table doesn't exist so I have to create and populate it
+ createZoneChannelTable();
+ populateZoneChannelTable(TRBO);
+ }
+ }
+
+ return allZones;
+ }
+
+
+ public void writeConfigFileZonesAndChannels(ArrayList zones) {
+
+ // delete all values from zonechannel table
+ database.execSQL("DELETE FROM zonechannel where 1=1");
+
+ for(Zone zone:zones) {
+ // insert zone into database
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (" + zone.id + ",'" + zone.ZoneName + "'," +
+ "'zone'" + "," + zone.id + ")");
+
+ // add channels for current zone
+ for(Channel ch: zone.channelList) {
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (" + ch.id + ",'" + ch.chName + "'," +
+ "'channel'" + "," + ch.id + ")");
+ }
+
+
+ }
+
+ }
+
+ public void writeConfigFileContacts(ArrayList contacts) {
+ // delete all values from contacts table
+ database.execSQL("DELETE FROM contacts where 1=1");
+
+ for(Contact contact: contacts) {
+ // insert contact into database
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (" + contact.id + ",'" + contact.name +"','" +
+ contact.contactType + "')");
+ }
+ }
+
+
+ public void createZoneChannelTable()
+ {
+ // create table
+ String sqlDataStore = "create table if not exists " +
+ "zonechannel" + " ("+ BaseColumns._ID + " integer primary key autoincrement,"
+ + "position" + " INTEGER ,"
+ + "name" + " text not null,"
+ + "type" + " text not null,"
+ + "zone_id" + " INTEGER not null)";
+ database.execSQL(sqlDataStore);
+
+ }
+
+ public void populateZoneChannelTable(boolean TRBO)
+ {
+ // populate table
+
+ if(TRBO)
+ {
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (1,'Zone1','zone',1)");
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (1,'Channel1','channel',1)");
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (2,'Channel2','channel',1)");
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (3,'Channel3','channel',1)");
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (4,'Channel4','channel',1)");
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (5,'Channel5','channel',1)");
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (6,'Channel6','channel',1)");
+
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (3,'Zone2','zone',3)");
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (1,'Ch5[Z2]','channel',3)");
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (2,'Ch6[Z2]','channel',3)");
+ }
+
+ else
+ {
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (1,'Zone1','zone',1)");
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (456,'DMO TG1','channel',1)");
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (457,'DMO TG2','channel',1)");
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (458,'DMO TG3','channel',1)");
+ database.execSQL("INSERT INTO zonechannel (position, name, type, zone_id) VALUES (459,'DMO TG4','channel',1)");
+ }
+ }
+
+
+ public void createContactsTable()
+ {
+ // create table
+ String sqlDataStore = "create table if not exists " +
+ "contacts" + " ("+ BaseColumns._ID + " integer primary key autoincrement,"
+ + "call_id" + " INTEGER ,"
+ + "name" + " text not null,"
+ + "call_type" + " text not null)";
+ database.execSQL(sqlDataStore);
+ }
+
+
+ public void populateContactsTable(boolean TRBO)
+ {
+
+ if(TRBO)
+ {
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (101,'UNIT101','Private Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (102,'UNIT102','Private Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (103,'UNIT103','Private Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (104,'BASE104','Private Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (114,'BASE114','Private Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (124,'BASE124','Private Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (1,'Call1','Group Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (2,'Call2','Group Call')");
+ }
+
+ else
+ {
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (101,'UNIT101','Private Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (102,'UNIT102','Private Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (103,'UNIT103','Private Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (456,'DMO TG1','Group Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (457,'DMO TG2','Group Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (458,'DMO TG3','Group Call')");
+ database.execSQL("INSERT INTO contacts (call_id, name, call_type) VALUES (459,'DMO TG4','Group Call')");
+ }
+ }
+
+
+ public long insertContact(Contact contact)
+ {
+ long id = -1;
+ if(database == null)
+ SM.Debug("Database is null");
+ else
+ {
+ try
+ {
+ ContentValues values = new ContentValues();
+ values.put("call_id", contact.id);
+ values.put("name", contact.name);
+ values.put("call_type", contact.contactType);
+ id = database.insert("contacts", "", values); //.rawQuery("SELECT imei_sour, imei_dest from SMS",new String [] {});
+ SM.Debug("DBQuery","Database Insert result: " + id);
+ }
+ catch(Exception ex)
+ {
+ SM.Exception("DB[Insert Contact]","Could not insert into DB");
+ }
+ }
+ //INSERT into SMS (timeGMT, imei_sour, imei_dest, mess, status) VALUES( 1324016412, 0, 101, 'two', 1)
+ return id;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/enums/MapType.java b/libSafeMobile/src/main/java/com/safemobile/enums/MapType.java
new file mode 100644
index 0000000..ef9774c
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/enums/MapType.java
@@ -0,0 +1,99 @@
+package com.safemobile.enums;
+
+public enum MapType {
+ NONE(0),
+ STYLE_NORMAL(1),
+ SATELLITE(2),
+ TERRAIN(3),
+ HYBRID(4),
+
+ STYLE_RETRO(10),
+ STYLE_GRAYSCALE(11),
+ STYLE_NIGHT(12),
+ STYLE_DARK(13),
+ STYLE_AUBERGINE(14);
+
+
+ private int value;
+
+
+ MapType(int value) {
+ this.value = value;
+ }
+
+
+ /**
+ * Convert an integer value to the corresponding Map Type enum value
+ * @param x Desired value to be converted
+ * @return Map Type enum value that corresponds to the int value
+ */
+ public static MapType fromInteger(int x) {
+ switch (x) {
+ case 0:
+ return NONE;
+ case 1:
+ return STYLE_NORMAL;
+ case 2:
+ return SATELLITE;
+ case 3:
+ return TERRAIN;
+ case 4:
+ return HYBRID;
+ case 10:
+ return STYLE_RETRO;
+ case 11:
+ return STYLE_GRAYSCALE;
+ case 12:
+ return STYLE_NIGHT;
+ case 13:
+ return STYLE_DARK;
+ case 14:
+ return STYLE_AUBERGINE;
+ default:
+ return STYLE_NORMAL;
+ }
+ }
+
+
+ /**
+ * Convert a string value to the corresponding GPS Provider enum value
+ * @param mapType Desired value to be converted
+ * @return Map Type enum value that corresponds to the string value
+ */
+ public static MapType fromString(String mapType) {
+ switch (mapType) {
+ case "NONE":
+ return NONE;
+ case "STYLE_NORMAL":
+ return STYLE_NORMAL;
+ case "SATELLITE":
+ return SATELLITE;
+ case "TERRAIN":
+ return TERRAIN;
+ case "HYBRID":
+ return HYBRID;
+ case "STYLE_RETRO":
+ return STYLE_RETRO;
+ case "STYLE_GRAYSCALE":
+ return STYLE_GRAYSCALE;
+ case "STYLE_NIGHT":
+ return STYLE_NIGHT;
+ case "STYLE_DARK":
+ return STYLE_DARK;
+ case "STYLE_AUBERGINE":
+ return STYLE_AUBERGINE;
+ default:
+ return STYLE_NORMAL;
+ }
+ }
+
+
+ /**
+ * Get the int value of current Map Type enum instance
+ * @return Corresponding int value of the enum instance
+ */
+ public int getValue() {
+ return this.value;
+ }
+
+}
\ No newline at end of file
diff --git a/libSafeMobile/src/main/java/com/safemobile/interfaces/AudioEvent.java b/libSafeMobile/src/main/java/com/safemobile/interfaces/AudioEvent.java
new file mode 100644
index 0000000..64e9095
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/interfaces/AudioEvent.java
@@ -0,0 +1,23 @@
+package com.safemobile.interfaces;
+
+import java.util.EventObject;
+
+public class AudioEvent extends EventObject {
+
+ private static final long serialVersionUID = 1L;
+ private byte[] data;
+ private int len;
+ public AudioEvent(Object source, byte[] _data, int _len) {
+ super(source);
+ data =_data;
+ len = _len;
+ }
+ public byte[] data() {
+ return data;
+ }
+
+ public int len()
+ {
+ return len;
+ }
+}
\ No newline at end of file
diff --git a/libSafeMobile/src/main/java/com/safemobile/interfaces/IAudioListener.java b/libSafeMobile/src/main/java/com/safemobile/interfaces/IAudioListener.java
new file mode 100644
index 0000000..ba7054b
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/interfaces/IAudioListener.java
@@ -0,0 +1,6 @@
+package com.safemobile.interfaces;
+
+public interface IAudioListener {
+ public void soundReceived( AudioEvent event );
+ public void soundSent( AudioEvent event );
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/interfaces/ICallStatusListener.java b/libSafeMobile/src/main/java/com/safemobile/interfaces/ICallStatusListener.java
new file mode 100644
index 0000000..d1fee8c
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/interfaces/ICallStatusListener.java
@@ -0,0 +1,15 @@
+package com.safemobile.interfaces;
+
+import com.safemobile.lib.radio.IncCall;
+
+public interface ICallStatusListener {
+
+ public void decoded ( IncCall call );
+ public void initiated ( IncCall call );
+ public void inProgress ( IncCall call );
+ public void hangtime ( IncCall call );
+ public void ended ( IncCall call );
+
+ /** Event used when any incoming Call message is received */
+ public void incoming (IncCall call );
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/interfaces/IMap.java b/libSafeMobile/src/main/java/com/safemobile/interfaces/IMap.java
new file mode 100644
index 0000000..91db74d
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/interfaces/IMap.java
@@ -0,0 +1,210 @@
+package com.safemobile.interfaces;
+
+import android.view.LayoutInflater;
+
+import com.google.android.gms.maps.model.LatLng;
+import com.safemobile.enums.MapType;
+import com.safemobile.lib.Position;
+import com.safenet.lib.Geofence;
+import com.safenet.lib.Landmark;
+import com.safenet.lib.Unit;
+
+import java.util.ArrayList;
+
+/**
+ * Created by Adi on 3/25/2016.
+ */
+public interface IMap {
+
+ interface MapInteraction
+ {
+ void onMapLocationChanged(double latitude, double longitude, float zoomLevel);
+ void onInfoBubbleClosed(long assetId, LatLng position);
+ void onInfoBubbleOpened(long assetId, LatLng position);
+ }
+
+ void setMapInteractionListener(MapInteraction delegate);
+
+ long MYSELF = 0l;
+ long LABEL_START = 16777215;
+
+
+ int MAPBOX = 1;
+ int GOOGLE = 2;
+ int OSM = 3;
+
+
+ /** INTENTS **/
+ String MAP_TERRAIN_REQ = "MAP_TERRAIN_REQ";
+ String MAP_SATELLITE_REQ = "MAP_SATELLITE_REQ";
+ String MAP_NORMAL_REQ = "MAP_NORMAL_REQ";
+ String MAP_HYBRID_REQ = "MAP_HYBRID_REQ";
+ String MAP_SHOW_ME = "MAP_SHOW_ME";
+ String MAP_LOCATION_REQUEST = "MAP_LOCATION_REQUEST";
+
+ /** GOOGLE MAP TYPE **/
+ int MAP_TYPE_NONE = 0;
+ int MAP_TYPE_NORMAL = 1;
+ int MAP_TYPE_SATELLITE = 2;
+ int MAP_TYPE_TERRAIN = 3;
+ int MAP_TYPE_HYBRID = 4;
+
+ /**
+ * Display the contacts that are flaged as onMap to be drawn on the
+ * Google map. The list is available on the AppParams .
+ * The same function will remove previous contacts that were on the map
+ * @param units The list of assets that needs to be displayed
+ */
+ void showContactsOnMap(ArrayList units);
+
+
+ /**
+ * Update the marker icon/location if displayed else do nothing. This method is called
+ * whenever the asset position is changed, or when the asset goes offline/online or in emergency
+ * @param unit The asset that changed the state or position
+ */
+ void updateMarkerPosition(Unit unit);
+
+
+
+ /**
+ * Change the map type to one of the following options
+ * GoogleMap.MAP_TYPE_HYBRID
+ * GoogleMap.MAP_TYPE_NORMAL
+ * GoogleMap.MAP_TYPE_SATELLITE
+ * GoogleMap.MAP_TYPE_TERRAIN
+ * @param mapType The mapType value of the map
+ */
+ void setMapType(MapType mapType);
+
+
+ /**
+ * Change the map type to one of the following options
+ * Style.MAPBOX_STREETS
+ * Style.EMERALD
+ * Style.LIGHT
+ * Style.DARK
+ * Style.SATELLITE
+ * Style.SATELLITE_STREETS
+ * @param mapType The int value of the map
+ */
+ void setMapType(String mapType);
+
+
+ /**
+ * Center map and then zoom to the location of a specific contact
+ * @param unit The contact which needs to be focused. It contains the
+ * gps location
+ */
+ void centerZoomContact(Unit unit);
+
+ /**
+ * Center the map on a particular position represented by a LatLng point
+ * @param mapLocation Location to which the map needs to center
+ */
+ void centerZoomMapOnLocation(LatLng mapLocation);
+
+
+ /**
+ * Center the map on a particular position represented by a LatLng point
+ * @param mapLocation Location to which the map needs to center
+ * @param zoomLevel The zoom at which the map needs to be set
+ *
+ */
+ void centerZoomMapOnLocation(LatLng mapLocation, float zoomLevel);
+
+
+ /**
+ * Show a custom marker on the map representing the current user
+ * @param position The location at which the user is
+ * @param shouldOpenInfoBubble Specify if the info bubble for the myself location should be opened
+ * @param shouldCenterNow Specify if the map needs to be animated to that location
+ */
+ void showMyselfOnMap(Position position, boolean shouldOpenInfoBubble,
+ boolean shouldCenterNow);
+
+
+ /**
+ * Hide the marker for myself from the map
+ */
+ void hideMyselfFromMap();
+
+
+ /**
+ * Open the info bubble for a specific marker
+ * @param markerKey The marker identifier from the hashtable
+ */
+ void openInfoBubbleForMarker(Long markerKey);
+
+
+ /**
+ * Open the info bubble for the last opened marker if it wasn't closed by the user explicitly
+ */
+ void openInfoBubble();
+
+ /**
+ * Show or hide the landmarks on the map
+ * @param isShown Boolean that will flag if the landmarks should be
+ * displayed. True is affirmative
+ * @param landmarks The landmarks that needs to be shown, Empty if none
+ */
+ void onShowLandmarksChangedHandler(boolean isShown, ArrayList landmarks);
+
+
+ /**
+ * Show or hide the geofence on the map
+ * @param isShown Boolean that will flag if the geofence should be
+ * displayed. True is affirmative
+ * @param geofences The geofences that needs to be shown. Empty if none
+ */
+ void onShowGeofencesChangedHandler(boolean isShown, ArrayList geofences);
+
+
+
+ /**
+ * Show or hide the traffic on the map
+ * @param isShown Boolean that will flag if the traffic should be
+ * displayed. True is affirmative
+ */
+ void onShowTrafficChangedHandler(boolean isShown);
+
+
+ /**
+ * Handler for when the map is ready and bound to the UI
+ * @param map The received map
+ * @param layoutInflater Inflater needed to inflate the InfoBubble
+ */
+ void onMapReceived(Object map, LayoutInflater layoutInflater);
+
+
+ /**
+ * Handler for when the map is ready and bound to the UI
+ * @param map The received map
+ * @param tileServer Map tile server used for OSM or other private environments
+ */
+ void onMapReceived(Object map, String tileServer);
+
+ /**
+ * Change the map center and zoom level to allow the display of all the displayed markers
+ */
+ void panZoomMap();
+
+
+ /**
+ * On activity paused
+ */
+ void onPause();
+
+ /**
+ * On activity resumed
+ */
+ void onResume();
+
+ /**
+ * Handler for when the map needs to be refreshed/invalidated
+ */
+ void refresh();
+
+
+ boolean isMapAvailable();
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/interfaces/IPlaybackListener.java b/libSafeMobile/src/main/java/com/safemobile/interfaces/IPlaybackListener.java
new file mode 100644
index 0000000..cc51177
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/interfaces/IPlaybackListener.java
@@ -0,0 +1,8 @@
+package com.safemobile.interfaces;
+
+public interface IPlaybackListener {
+ public void finishedPlaying();
+ public void startPlaying();
+ public void stopedPlaying();
+ public void failedPlaying();
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/interfaces/ITCPListener.java b/libSafeMobile/src/main/java/com/safemobile/interfaces/ITCPListener.java
new file mode 100644
index 0000000..4b38556
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/interfaces/ITCPListener.java
@@ -0,0 +1,33 @@
+package com.safemobile.interfaces;
+
+public interface ITCPListener {
+ public void onLoginReceived( TCPEvent event );
+ public void onGPSReceived( TCPEvent event );
+ public void onVehiclesReceived( TCPEvent event );
+
+ public void onLastSMSsReceived( TCPEvent event );
+ public void onSMSReceived( TCPEvent event );
+ public void onSMSAckReceived( TCPEvent event );
+ public void onNewSMSReceived( TCPEvent event );
+
+ public void onLastPositionsReceived( TCPEvent event );
+ public void onRadioMsgReceived( TCPEvent event );
+ public void onHistoryPositionsReceived( TCPEvent event );
+ public void onHistoryPositionsCountReceived( TCPEvent event );
+ public void onAlarmsReceived( TCPEvent event );
+ public void onAlarmAckReceived(TCPEvent event);
+ public void alarmLiveRecv(TCPEvent event);
+
+ public void onRecordingPlayReceived(TCPEvent event);
+ public void onPollReceived(TCPEvent event);
+ public void onConnectionReplyReceived (TCPEvent event);
+
+ public void onContactsListReceived (TCPEvent event);
+ public void onTextMessagesListReceived (TCPEvent event);
+ public void onRecordingsListReceived(TCPEvent event);
+
+ public void onPONGReceived();
+ public void onTCPConnectionDown(boolean previuosWasConnectionUp);
+ public void onTCPConnectionUp(boolean previuosWasConnectionUp);
+ public void onTCPConnectionStatusReceived(boolean isConnectionUp, boolean previuosWasConnectionUp);
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/interfaces/IUDPListener.java b/libSafeMobile/src/main/java/com/safemobile/interfaces/IUDPListener.java
new file mode 100644
index 0000000..3d59eb8
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/interfaces/IUDPListener.java
@@ -0,0 +1,5 @@
+package com.safemobile.interfaces;
+
+public interface IUDPListener {
+ public void dataRecv( UDPevent event );
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/interfaces/TCPEvent.java b/libSafeMobile/src/main/java/com/safemobile/interfaces/TCPEvent.java
new file mode 100644
index 0000000..2cdf4b3
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/interfaces/TCPEvent.java
@@ -0,0 +1,20 @@
+package com.safemobile.interfaces;
+
+import java.util.EventObject;
+
+import com.safemobile.lib.TCPmsg;
+
+public class TCPEvent extends EventObject {
+
+ private static final long serialVersionUID = 1L;
+ private TCPmsg _msg;
+
+ public TCPEvent(Object source, TCPmsg msg ) {
+ super( source );
+ _msg = msg;
+ }
+ public TCPmsg msg() {
+ return _msg;
+ }
+
+}
\ No newline at end of file
diff --git a/libSafeMobile/src/main/java/com/safemobile/interfaces/UDPevent.java b/libSafeMobile/src/main/java/com/safemobile/interfaces/UDPevent.java
new file mode 100644
index 0000000..37d6e49
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/interfaces/UDPevent.java
@@ -0,0 +1,23 @@
+package com.safemobile.interfaces;
+
+import java.util.EventObject;
+
+public class UDPevent extends EventObject {
+
+ private static final long serialVersionUID = 1L;
+ private byte[] data;
+ private int len;
+ public UDPevent(Object source, byte[] _data, int _len) {
+ super(source);
+ data =_data;
+ len = _len;
+ }
+ public byte[] data() {
+ return data;
+ }
+
+ public int len()
+ {
+ return len;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/Alarm.java b/libSafeMobile/src/main/java/com/safemobile/lib/Alarm.java
new file mode 100644
index 0000000..2f5fbd9
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/Alarm.java
@@ -0,0 +1,47 @@
+package com.safemobile.lib;
+
+public class Alarm {
+ public int idx;
+ public String unitName;
+ public int type;
+ public String typestr;
+ public String description;
+ public long timeGMT;
+ public int ack;
+ public long sc_id;
+
+ public Alarm()
+ {
+ }
+
+ public Alarm(int idx, int type, String description, int timeGMT, int ack, int sc_id)
+ {
+ this.idx = idx;
+ this.sc_id = sc_id;
+ this.type = type;
+ this.description = description;
+ this.timeGMT = timeGMT;
+ this.ack = ack;
+ switch (this.type)
+ {
+ case 0: typestr = "emergency";
+ break;
+ case 1: typestr = "landmark";
+ break;
+ case 2: typestr = "zone";
+ break;
+ case 3: typestr = "speed";
+ break;
+ case 4: typestr = "telemetry";
+ break;
+ default:
+ typestr = "emergency";
+ }
+ this.unitName = "Empty";
+ }
+
+ public String toString()
+ {
+ return "idx: " + idx + " | sc_id: " + sc_id + " | type: " + type + " | description: " + description + " | timeGMT: " + timeGMT + " | ack:" + ack + " | typestr:" + typestr+" | unitName:" + unitName;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/AlarmMSG.java b/libSafeMobile/src/main/java/com/safemobile/lib/AlarmMSG.java
new file mode 100644
index 0000000..2adde54
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/AlarmMSG.java
@@ -0,0 +1,34 @@
+package com.safemobile.lib;
+
+import java.util.ArrayList;
+
+public class AlarmMSG extends TCPmsg {
+
+ public ArrayList alarmList;
+ public static int count=0;
+ public AlarmMSG(TCPmsg tcp) {
+ super(tcp);
+ alarmList = new ArrayList();
+ String date4parsing = super.data;
+ //SM.Debug("SMS date4parsing:"+date4parsing);
+ String[] tempArr = date4parsing.split(";");
+
+ //SM.Debug("SMS tempArr.length:" +tempArr.length);
+ for(int i =0; i allUsers = new ArrayList();
+ public static Theme theme = Theme.SAFENET; // the Theme type
+
+
+ /* ***************************************** */
+ /* ********** Radio Status Params ********** */
+ /* ***************************************** */
+ public static RadioStatus crtRadioStatus = new RadioStatus();
+ public static Zone_and_channel crtZoneAndChannel = new Zone_and_channel();
+ public static Emerg crtEmergencyState = new Emerg();
+ public static IncCall crtIncCall = new IncCall();
+ public static PadRecording crtPlayingRecording = new PadRecording();
+ public static ByteBuffer recordingBuffer = null;
+ //public static ArrayList listTextMessages = new ArrayList();
+ public static Hashtable hashNotAckMsg = new Hashtable();
+
+ // the text message hash table will have the first key the radioID, and the second key the textMessage DB ID
+ public static Hashtable> hashTextMessagesByRadioID = new Hashtable>();
+
+ //public static ArrayList listRecordings = new ArrayList();
+ public static Hashtable listRecordings = new Hashtable();
+ public static ArrayList recordings = new ArrayList();
+ public static ArrayList listContacts = new ArrayList();
+ public static ArrayList listZones = new ArrayList();
+ public static ArrayList listRadios = new ArrayList();
+ public static Radio crtRadio = new Radio();
+ public static Zone crtZone = new Zone();
+ public static Channel crtChannel;
+
+ public static PadTextMessage crtSentTextMessage = new PadTextMessage();
+ public static PadTextMessage crtAckedTextMessage = new PadTextMessage();
+ public static PadTextMessage crtReceivedTextMessage = new PadTextMessage();
+
+ public static Contact crtContact = new Contact();
+ public static Contact crtTetraContact = new Contact();
+ public static Contact crtTetraGroup = new Contact();
+ public static PadRecording crtRecording = new PadRecording();
+
+
+ public static final int TRBOO = 1, TETRA = 2, SEPURAA = 3;
+ public static final int NOT_ACK = 1;
+ public static final int ACK = 2;
+ public static int APPLICATION_TYPE = TRBOO; // WILL BE MODIFIED AT CONNECTION
+ public static final String FIRMWARE_VERSION = "2.3.1";
+
+ public static boolean DEMO = false; // DEMO is set by package name (contains OR !contains "demo")
+
+ /** Safenet Login */
+ public static long USERID = -1;
+ public static String USERNAME = "";
+ public static String PASSWORD = "";
+ public static boolean REMEMBER = false;
+ public static String DEFAULT = "";
+
+ //private String[] Types = {"AIR", "RADIOPAD", "MOTOPAD-TRBO", "MOTOPAD-TETRA"};
+ public static String TYPE = "RADIOPAD"; // blue or red version (SafeMobile or AIR version)
+ //public static boolean AIR = false; // blue or red version (SafeMobile or AIR version)
+ public static boolean TABLET = false; // flag if device is a TABLET or PHONE (inconsistent - 06.Nov.2012)
+ public static boolean PAUSED = false; // application status: PAUSED or RUNNING
+
+ public static boolean SEPURA = false;
+ public static boolean PRINTER = false;
+
+ public static int UPDATE_SIZE = 20;
+
+ public static String Database = ""; //"de"; // database language
+ public static boolean online = false;
+
+ /** Tabs */
+ public static Tabs crtTab = Tabs.radio;
+
+ public static int CallState = 3; // tablet state: 7 - Hangtime, 3 - Ended, Other - inCall
+ public static long CallSourId = -1;
+ public static long CallDestId = -1;
+ public static int CallType = 101;
+ public static long selCallId = -1;
+ public static int selCallType = 101;
+ public static long CallStartTime = -1;
+ public static int prevCallState = 4;
+ public static boolean inCall = false;
+ public static boolean externalSource = false;
+
+ /** Configuration File */
+ //public static ConfigFile configFile = null; // config file
+
+ /** Database */
+ //public static DatabaseCommunication databaseCommunication = null;
+
+ /** SharedPreferences */
+ public static SharedPreferences prefs; // project preferences
+ public static String LANGUAGE; // displaying language
+ public static String LANGUAGETMP = "en"; // temporary displayed language
+ public static String STREAM = "MUSIC"; // AudioHandler's AudioTrack default stream
+ public static String SOURCE = "TCP"; // AudioHandler's AudioTrack default source
+ public static boolean EXTERNALMIC = false; // external mic used with what-a-pair systems
+ public static boolean TETHERSOUND = false; // allow BlueTooth tethering
+ public static boolean TRBO = true;
+ public static boolean NOTIFICATIONS = true;
+ public static boolean RECORDINGS = true;
+ public static String RECORDINGS_LOCATION = "Internal Storage";
+ public static boolean MANDOWN = false;
+ public static int MANDOWNTHRESHOLD = 25;
+ public static boolean MOTIONLESS = false;
+ public static int MOTIONLESSTIME = 300;
+ public static int RADIOID = 100;
+ public static String RADIOIP = "192.168.10.40";
+ public static String IP="n/a"; // SafeBridge's IP
+ public static String PORT="13570"; // SafeBridge's PORT
+ public static String PATH = "n/a"; // ConfigFile PATH
+
+ /** BluComm
+ * states : 0 - disconnected; 1 - connected but not pressed; 2 - pressed; */
+ public static int BluCommState = 0; // remembers BluComm Microphone state
+ public static final int PTTON = 1;
+ public static final int PTTOFF = 0;
+
+ /** Call Types */
+ public static final int AllCall = 101;
+ public static final int PrivateCall = 102;
+ public static final int GroupCall = 103;
+ public static final int EndAllCall = AllCall+10;
+ public static final int EndPrivateCall = PrivateCall+10;
+ public static final int EndGroupCall = GroupCall+10;
+ public static final int PTTBUTTON = 999;
+ public static final int VOXON = 555;
+ public static final int VOXOFF = 000;
+
+ /* Old Values
+ public static final int Decoded = 1;
+ public static final int InProgress = 2;
+ public static final int Initiated = 4;
+ public static final int Hangtime = 7;
+ public static final int Ended = 3;
+ public static final int InitButton = 5;
+ public static final int MotoPrivate = 4;
+ public static final int MotoGroup = 6;
+ public static final int MotoAllCall = 16777215;
+ //*/
+
+ //* New Values
+ public static final int Initiated = 0;
+ public static final int Decoded = 1;
+ public static final int InProgress = 2;
+ public static final int Hangtime = 3;
+ public static final int Ended = 4;
+ public static final int InitEnded = 5;
+ public static final int InitHangtime = 6;
+ public static final int MotoPrivate = 1;
+ public static final int MotoGroup = 2;
+ public static final int MotoAllCall = 3;
+ public static final int MotoManualDial = 4;
+ //*/
+
+
+ /** BlueTooth Headset MAC */
+ public static String BluCom = "00:15:45:";
+ /*
+ public static String MotorolaH730 = "00:24:1C:";
+ public static String SamsungWep460 = "18:46:17:";
+ */
+
+ /** Notification values */
+ public static final int messageNotif = 1;
+ public static final int alertNotif = 2;
+ public static final int pollNotif = 3;
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/ConfigFile.java b/libSafeMobile/src/main/java/com/safemobile/lib/ConfigFile.java
new file mode 100644
index 0000000..5230a3a
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/ConfigFile.java
@@ -0,0 +1,34 @@
+package com.safemobile.lib;
+
+import java.util.ArrayList;
+
+import com.safemobile.lib.radio.Zone;
+
+public class ConfigFile {
+ public ArrayList contacts;
+ public Radio radio;
+ public ArrayList zones;
+
+ public ConfigFile()
+ {
+ contacts = new ArrayList();
+ zones = new ArrayList();
+ }
+
+ public String toString()
+ {
+ return "Contacts: " + contacts.size() + " | Radio: " + radio.toString() + " | Zones: " + zones.size();
+ }
+
+ public String toLongString()
+ {
+ String cont = "", zone="";
+ for(Contact contact: contacts)
+ cont += "Name: " + contact.name + " | Id: " + contact.id + "\n";
+
+ for(Zone zonee: zones)
+ zone += "Name: " + zonee.ZoneName + " | Id: " + zonee.id + "\n";
+
+ return "# Contacts #\n" + cont + "# Radio #\n" + radio.toString() + "\n# Zones #\n" + zone;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/Contact.java b/libSafeMobile/src/main/java/com/safemobile/lib/Contact.java
new file mode 100644
index 0000000..d3e8555
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/Contact.java
@@ -0,0 +1,94 @@
+package com.safemobile.lib;
+
+import java.util.ArrayList;
+
+public class Contact {
+ public int dbID = 0;
+ public long id = 0;
+ public String name = "";
+ public int contactType = 0;
+ public int parentDB_ID = 0;
+
+ public static final int PRIVATE = 1;
+ public static final int GROUP = 2;
+ public static final int ALL = 3;
+ public static final int ZONE = 4;
+ public static final int CHANNEL = 5;
+
+
+
+ public Contact()
+ {
+
+ }
+
+ public Contact(long _id, String _name, int _contactType, int dbID, int parentDB_id)
+ {
+ id = _id;
+ name = _name;
+ contactType = _contactType;
+ this.dbID = dbID;
+ this.parentDB_ID = parentDB_id;
+ }
+
+ public String toString()
+ {
+ return id + ". " + name + " [" + getContactType(contactType) + "]";
+ }
+
+
+ private String getContactType(int contactType) {
+ switch(contactType) {
+ case PRIVATE: return "PRIVATE";
+ case GROUP: return "GROUP";
+ case ALL: return "ALL CALL";
+ case ZONE: return "ZONE";
+ case CHANNEL: return "CHANNEL";
+ default: return "UNKNOWN";
+ }
+ }
+
+ public static ArrayList parseTCPMsg(String msg) {
+
+ ArrayList contacts = new ArrayList();
+ try
+ {
+ msg = msg.replace("#", "");
+ // split payload to get contacts
+
+ // split contact by /
+ String[] contArr = msg.split("/");
+ Contact ct = new Contact();
+ ct.dbID = Integer.parseInt(contArr[0]);
+ ct.id = Long.parseLong(contArr[1]);
+ ct.name = contArr[2];
+ ct.contactType = Integer.parseInt(contArr[4]);
+ ct.parentDB_ID = Integer.parseInt(contArr[3]);
+
+ contacts.add(ct);
+ }
+ catch(Exception ex)
+ {
+ SM.Exception("Exception parse Contacts", ex.toString());
+ }
+
+ return contacts;
+ /*
+ int id = 1;
+
+ // this will select the type
+ switch(AppParams.APPLICATION_TYPE * 10 + id) {
+
+ }
+ */
+ }
+
+ public static String getNameForRadioID(ArrayList listUnits, long radioID) {
+ for(Contact ctc: listUnits)
+ if(ctc.id == radioID && (ctc.contactType == Contact.PRIVATE))
+ return ctc.name;
+
+ // if contact wasn't found I should return it's radioID
+ return radioID+"";
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/GPS.java b/libSafeMobile/src/main/java/com/safemobile/lib/GPS.java
new file mode 100644
index 0000000..a735080
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/GPS.java
@@ -0,0 +1,19 @@
+package com.safemobile.lib;
+
+public class GPS {
+
+ public long imei=0;
+ public double lat=0;
+ public double lng=0;
+ public int speed=0;
+ public long timeGMT=0;
+
+ public GPS(){
+
+ }
+
+ public String toString()
+ {
+ return "imei: " + imei + " | LAT: " + lat + " | LNG: " + lng + " | speed: " + speed + " | timeGMT: " + timeGMT;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/GPSmsg.java b/libSafeMobile/src/main/java/com/safemobile/lib/GPSmsg.java
new file mode 100644
index 0000000..4a8c5e3
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/GPSmsg.java
@@ -0,0 +1,24 @@
+package com.safemobile.lib;
+
+public class GPSmsg extends TCPmsg {
+
+ public GPS gpsValue;
+ public static int count=0;
+ public GPSmsg(TCPmsg tcp)
+ {
+ super(tcp);
+ String date4parsing = super.data;
+ //SM.Debug("SMS date4parsing:"+date4parsing);
+ String[] tempVeh = date4parsing.split("#");
+ gpsValue = new GPS();
+ gpsValue.imei = Long.parseLong(tempVeh[0]);
+ gpsValue.lat = Double.parseDouble(tempVeh[3]);
+ gpsValue.lng = Double.parseDouble(tempVeh[4]);
+ gpsValue.speed = Integer.parseInt(tempVeh[2]);
+ gpsValue.timeGMT = Long.parseLong(tempVeh[1]);
+
+ }
+
+}
+
+
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/HistCount.java b/libSafeMobile/src/main/java/com/safemobile/lib/HistCount.java
new file mode 100644
index 0000000..b133f5d
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/HistCount.java
@@ -0,0 +1,22 @@
+package com.safemobile.lib;
+
+public class HistCount {
+ public String seq_id;
+ public long count;
+
+ public HistCount()
+ {
+
+ }
+
+ public HistCount(String _seq_id, long _count)
+ {
+ seq_id = _seq_id;
+ count = _count;
+ }
+
+ public String toString()
+ {
+ return "seq_id: " + seq_id + " | count: " + count;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/HistCountmsg.java b/libSafeMobile/src/main/java/com/safemobile/lib/HistCountmsg.java
new file mode 100644
index 0000000..b96b17e
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/HistCountmsg.java
@@ -0,0 +1,18 @@
+package com.safemobile.lib;
+
+public class HistCountmsg extends TCPmsg {
+
+ public HistCount histcountValue;
+ public long count=0;
+ public HistCountmsg(TCPmsg tcp)
+ {
+ super(tcp);
+ String date4parsing = super.data;
+ //SM.Debug("SMS date4parsing:"+date4parsing);
+ //String[] tempVeh = date4parsing.split("#");
+ date4parsing = date4parsing.replace("#", "");
+ histcountValue = new HistCount();
+ histcountValue.count = Long.parseLong(date4parsing);
+ histcountValue.seq_id = super.seqID;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/HistPos.java b/libSafeMobile/src/main/java/com/safemobile/lib/HistPos.java
new file mode 100644
index 0000000..0798de2
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/HistPos.java
@@ -0,0 +1,75 @@
+package com.safemobile.lib;
+
+
+public class HistPos {
+
+ public double lat=0;
+ public double lng=0;
+ public int speed=0;
+ public long timeGMT=0;
+ public String Address="";
+ public int heading=0;
+
+ public HistPos(){
+
+ }
+
+ public HistPos(double _lat, double _lng, int _speed, long _timeGMT){
+ lat = _lat;
+ lng = _lng;
+ speed = _speed;
+ timeGMT = _timeGMT;
+ }
+
+ public String toString()
+ {
+ return " LAT: " + lat + " | LNG: " + lng + " | speed: " + speed + " | timeGMT: " + timeGMT + " | Address: " + Address;
+ }
+
+
+ public int GetIconHead()
+ {
+ try
+ {
+ if (((heading >= 0) && (heading < 11.25)) || ((heading > 348.75) && (heading <= 360)))
+ return R.drawable.arrow_e;
+ else if ((heading >= 11.25) && (heading < 33.75))
+ return R.drawable.arrow_ene;
+ else if ((heading >= 33.75) && (heading < 56.25))
+ return R.drawable.arrow_ne;
+ else if ((heading >= 56.25) && (heading < 78.75))
+ return R.drawable.arrow_nne;
+ else if ((heading >= 78.75) && (heading < 101.25))
+ return R.drawable.arrow_n;
+ else if ((heading >= 101.25) && (heading < 123.75))
+ return R.drawable.arrow_nnv;
+ else if ((heading >= 123.75) && (heading < 146.25))
+ return R.drawable.arrow_nv;
+ else if ((heading >= 146.25) && (heading < 168.75))
+ return R.drawable.arrow_vnv;
+ else if ((heading >= 168.75) && (heading < 191.25))
+ return R.drawable.arrow_v;
+ else if ((heading >= 191.25) && (heading < 213.75))
+ return R.drawable.arrow_vsv;
+ else if ((heading >= 213.75) && (heading < 236.25))
+ return R.drawable.arrow_sv;
+ else if ((heading >= 236.25) && (heading < 258.75))
+ return R.drawable.arrow_ssv;
+ else if ((heading >= 258.75) && (heading < 281.25))
+ return R.drawable.arrow_s;
+ else if ((heading >= 281.25) && (heading < 303.75))
+ return R.drawable.arrow_sse;
+ else if ((heading >= 303.75) && (heading < 326.25))
+ return R.drawable.arrow_se;
+ else if ((heading >= 326.25) && (heading < 348.75))
+ return R.drawable.arrow_ese;
+ else
+ return -1;
+ }
+ catch (Exception e) {
+ SM.Debug("Erorr on select Arrows");
+ return -1;
+ }
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/HistPosmsg.java b/libSafeMobile/src/main/java/com/safemobile/lib/HistPosmsg.java
new file mode 100644
index 0000000..100233f
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/HistPosmsg.java
@@ -0,0 +1,126 @@
+package com.safemobile.lib;
+
+import java.util.ArrayList;
+
+//Date data = Calendar.getInstance().getTime();
+//data.getTime();
+
+public class HistPosmsg extends TCPmsg {
+
+ public ArrayList PosList;
+ public int count=0;
+ public HistPosmsg(TCPmsg tcp) {
+ super(tcp);
+ PosList = new ArrayList();
+ try{
+ String date4parsing = super.data;
+ //SM.Debug("SMS date4parsing:"+date4parsing);
+ String[] tempArr = date4parsing.split(";");
+ //SM.Debug("SMS tempArr.length:" +tempArr.length);
+ for(int i =0; i CalcHeadingForArray(ArrayList list)
+ {
+ this.PosList = list;
+ if (PosList.size()>1)
+ {
+ HistPos oldPos = PosList.get(0);
+ HistPos tmpPos = null;
+ int Headingtmp =0;
+ for (int i=1;i mdelta_min) && (dlat < delta_min) && ((mdelta_min < dlng) && dlng < (delta_min))) headcalc = heading;
+ else
+ {
+ if ((mdelta_min < dlat) && (dlat < delta_min))
+ {
+ blng = 1;
+ if (dlng < 0) headcalc = 180;
+ else headcalc = 0;
+ }
+ else
+ {
+ blat = 1;
+ if (dlat > 0) headcalc = 90;
+ else headcalc = 270;
+ }
+ }
+ if ((mdelta_min < dlng) && (dlng < delta_min))
+ {
+ if (blat == 0)
+ {
+ if (dlat > 0)
+ {
+ if (headcalc == 180) headcalc = 135;
+ if (headcalc == 0) headcalc = 45;
+ }
+ else
+ {
+ if (headcalc == 180) headcalc = 225;
+ if (headcalc == 0) headcalc = 315;
+ }
+ }
+ }
+ else
+ {
+ if (blng == 0)
+ {
+ if (dlng < 0)
+ {
+ if (headcalc == 90) headcalc = 135;
+ if (headcalc == 270) headcalc = 225;
+ }
+ else
+ {
+ if (headcalc == 90) headcalc = 45;
+ if (headcalc == 270) headcalc = 315;
+ }
+ }
+ }
+ return headcalc;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/LastPos.java b/libSafeMobile/src/main/java/com/safemobile/lib/LastPos.java
new file mode 100644
index 0000000..dea4378
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/LastPos.java
@@ -0,0 +1,22 @@
+package com.safemobile.lib;
+
+public class LastPos {
+
+ public long imei=0;
+ public double lat=0;
+ public double lng=0;
+ public int speed=0;
+ public long timeGMT=0;
+ public String Address="";
+ public boolean isON=false;
+
+ public LastPos(){
+
+ }
+
+ public String toString()
+ {
+ return "imei: " + imei + " | LAT: " + lat + " | LNG: " + lng + " | speed: " + speed + " | timeGMT: " + timeGMT + " | Address: " + Address + " | isON: " + isON;
+ }
+}
+
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/LastPosmsg.java b/libSafeMobile/src/main/java/com/safemobile/lib/LastPosmsg.java
new file mode 100644
index 0000000..9115194
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/LastPosmsg.java
@@ -0,0 +1,42 @@
+package com.safemobile.lib;
+
+import java.util.ArrayList;
+
+public class LastPosmsg extends TCPmsg {
+
+ public ArrayList PosList;
+ public static int count=0;
+ public LastPosmsg(TCPmsg tcp) {
+ super(tcp);
+ PosList = new ArrayList();
+ String date4parsing = super.data;
+ //SM.Debug("SMS date4parsing:"+date4parsing);
+ String[] tempArr = date4parsing.split(";");
+ //SM.Debug("SMS tempArr.length:" +tempArr.length);
+ for(int i =0; i userList;
+
+ public LoginMSG(TCPmsg m) {
+ super(m);
+
+ userList = new ArrayList();
+ String date4parsing = super.data;
+ //SM.Debug("date4parsing:"+date4parsing);
+ String[] tempArr = date4parsing.split(";");
+
+ for(int i =0; i{
+ // region private fields
+ public double latitude;
+ public double longitude;
+ public Date positionTime;
+ public double speed;
+ public String address;
+ public float accuracy;
+ //endregion
+
+ /**
+ * Default constructor
+ */
+ public Position()
+ {
+ latitude = 0;
+ longitude = 0;
+ positionTime = new Date(0);
+ speed = 0;
+ address = "";
+ accuracy = 0;
+ }
+
+ public Position(String json)
+ {
+ try {
+ JSONObject posObj = new JSONObject(json);
+ speed = posObj.isNull("speed")
+ ? 0 : posObj.getDouble("speed");
+ latitude = posObj.isNull("latitude")
+ ? 0 : posObj.getDouble("latitude");
+ longitude = posObj.isNull("longitude")
+ ? 0 : posObj.getDouble("longitude");
+ address = posObj.isNull("address")
+ ? "" : posObj.getString("address");
+
+ accuracy = posObj.isNull("accuracy")
+ ? 0 : (float) posObj.getDouble("accuracy");
+
+ String posTime = posObj.isNull("positionTime")
+ ? "" : posObj.getString("positionTime");
+ if(posTime.length() > 0)
+ {
+ //May 16, 2018 12:01:47
+ try
+ {
+ String timeFormat = "MMMMM d, yyyy HH:mm:ss";
+ DateFormat format = new SimpleDateFormat(timeFormat, Locale.ENGLISH);
+ positionTime = format.parse(posTime);
+ }
+ catch (ParseException e)
+ {
+ String timeFormat = "MMM d, yyyy HH:mm:ss";
+ DateFormat format = new SimpleDateFormat(timeFormat, Locale.ENGLISH);
+ positionTime = format.parse(posTime);
+ }
+ }
+
+ } catch (JSONException e) {
+ e.printStackTrace();
+ positionTime = new Date(0);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ positionTime = new Date(0);
+ }
+
+ }
+
+
+ public Position(double latitude, double longitude)
+ {
+ this.latitude = latitude;
+ this.longitude = longitude;
+ positionTime = new Date(0);
+ speed = 0;
+ address = "";
+ accuracy = 0;
+ }
+
+ /**
+ * Constructor from Parcel, reads back fields IN THE ORDER they were
+ * written
+ */
+ public Position(Parcel parcel){
+ latitude = parcel.readDouble();
+ longitude = parcel.readDouble();
+ positionTime = new Date(parcel.readLong());
+ speed = parcel.readDouble();
+ address = parcel.readString();
+ accuracy = parcel.readFloat();
+ }
+
+
+ /**
+ * Method from Parcelable class, left as auto-generated
+ * @return A default value
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+
+ /**
+ * Method to create the Parcel object from the main class that
+ * will be passed when a Parcelable object is used
+ * @param dest Parcel object in which all the object values will
+ * be added
+ * @param flags Additional flags about how the object should be
+ * written. May be 0 or PARCELABLE_WRITE_RETURN_VALUE.
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeDouble(latitude);
+ dest.writeDouble(longitude);
+ dest.writeLong(positionTime.getTime());
+ dest.writeDouble(speed);
+ dest.writeString(address);
+ dest.writeFloat(accuracy);
+ }
+
+ /**
+ * Static field used to regenerate object, individually or as arrays
+ */
+ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
+ public Position createFromParcel(Parcel in) {
+ return new Position(in);
+ }
+
+ @Override
+ public Position[] newArray(int size) {
+ return new Position[size];
+ }
+ };
+
+ /**
+ * Override of the method that returns a string representation of the object which
+ * contains all the useful information about the object
+ * @return String representation of the object
+ */
+ @Override
+ public String toString()
+ {
+ return "Latitude: " + latitude + " | "
+ + "Longitude: " + longitude + " | "
+ + "Speed: " + speed + " | "
+ + "PositionTime: " + (positionTime!= null ? positionTime.toString() : "null" ) + " | "
+ + "Address " + (address!= null ? address.toString() : "null" )
+ + "Accuracy " + accuracy;
+ }
+
+ @Override
+ public int compareTo(@NonNull Position o) {
+ return (latitude == o.latitude
+ && longitude == o.longitude
+ ) ? 0 : 1;
+ }
+
+ // Overriding equals() to compare two Complex objects
+ @Override
+ public boolean equals(Object o) {
+ Position pos = (Position) o;
+
+ return compareTo(pos) == 0;
+ }
+
+
+ // just omitted null checks
+ @Override
+ public int hashCode() {
+ double res = latitude * longitude * 100000;
+ int hash = (int)(latitude );
+ hash = (int)(longitude) * hash;
+ return (int)res;
+ }
+
+
+ public String toJson()
+ {
+ return new Gson().toJson(this);
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/Radio.java b/libSafeMobile/src/main/java/com/safemobile/lib/Radio.java
new file mode 100644
index 0000000..12c62e2
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/Radio.java
@@ -0,0 +1,22 @@
+package com.safemobile.lib;
+
+public class Radio {
+ public int id = 100;
+ public String ip = "192.168.10.40";
+
+ public Radio()
+ {
+
+ }
+
+ public Radio(int _id, String _ip)
+ {
+ id = _id;
+ ip = _ip;
+ }
+
+ public String toString()
+ {
+ return "id: " + id + " | ip: " + ip;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/RadioMSG.java b/libSafeMobile/src/main/java/com/safemobile/lib/RadioMSG.java
new file mode 100644
index 0000000..9e2f70c
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/RadioMSG.java
@@ -0,0 +1,344 @@
+package com.safemobile.lib;
+
+import java.util.ArrayList;
+
+import com.safemobile.lib.radio.Channel;
+import com.safemobile.lib.radio.Emerg;
+import com.safemobile.lib.radio.IncCall;
+import com.safemobile.lib.radio.RadioGW;
+import com.safemobile.lib.radio.RadioStatus;
+import com.safemobile.lib.radio.SUstatus;
+import com.safemobile.lib.radio.Zone;
+import com.safemobile.lib.radio.Zone_and_channel;
+
+public class RadioMSG extends TCPmsg {
+
+ public int rOpcode;
+ public String payload="";
+ public ArrayList RadioGWList=null;
+
+ //zone and channel;
+ public Zone_and_channel zac= null;
+
+ //radio status
+ public RadioStatus rStatus = null;
+
+ //SU stauts
+ public SUstatus suStatus = null;
+
+ //Incomming call
+ public IncCall incCall = null;
+
+ //Emerg
+ public Emerg emerg = null;
+
+ // Contacts list
+ public ArrayList contacts;
+
+
+ public RadioMSG(TCPmsg tcp) {
+ super(tcp);
+ String date4parsing = super.data;
+
+ String[] arr = date4parsing.split("#");
+
+ rOpcode = Integer.parseInt(arr[0]);
+ payload = arr[1];
+
+ switch(rOpcode)
+ {
+ case 200:
+ {
+ RadioGWList = new ArrayList();
+ String[] tempArr = payload.split(";");
+
+ int count = 0;
+ for(int i =0; i recordList;
+ public static int count=0;
+ public RecordMSG(TCPmsg tcp)
+ {
+ super(tcp);
+ recordList = new ArrayList();
+ String date4parsing = super.data;
+ //SM.Debug("SMS date4parsing:"+date4parsing);
+ String[] tempArr = date4parsing.split(";");
+
+ //SM.Debug("SMS tempArr.length:" +tempArr.length);
+ for(int i =0; i smsList;
+ public static int count=0;
+ public SMSmsg(TCPmsg tcp) {
+ super(tcp);
+ smsList = new ArrayList();
+ String date4parsing = super.data;
+ //SM.Debug("SMS date4parsing:"+date4parsing);
+ String[] tempArr = date4parsing.split(";");
+
+ //SM.Debug("SMS tempArr.length:" +tempArr.length);
+ for(int i =0; i vehList;
+
+ public VehMSG(TCPmsg m) {
+ super(m);
+
+ vehList = new ArrayList();
+ String date4parsing = super.data;
+ SM.Debug("date4parsing:"+date4parsing);
+ String[] tempArr = date4parsing.split(";");
+
+ SM.Debug("tempArr.length:" +tempArr.length);
+ for(int i =0; i xmlPath;
+
+ public XMLParser()
+ {
+
+ }
+
+ public ArrayList getXMLPath()
+ {
+ // reset xmlPath
+ xmlPath = new ArrayList();
+ File file[] = Environment.getExternalStorageDirectory().listFiles();
+ recursiveFileFind(file);
+
+ return xmlPath;
+ }
+
+ public ConfigFile parseXML(InputStream input)
+ {
+ XmlPullParser parser = Xml.newPullParser();
+ ArrayList contacts = new ArrayList();
+ ArrayList zones = new ArrayList();
+ Radio radio = new Radio();
+ try
+ {
+ parser.setInput(input, null);
+ Contact contact = null;
+ Zone zone = null;
+ Channel channel = null;
+ int eventType = parser.getEventType();
+ boolean done = false;
+ while (eventType != XmlPullParser.END_DOCUMENT && !done){
+ String name = null;
+ switch (eventType){
+ // build config object on xml start
+ case XmlPullParser.START_DOCUMENT:
+ config = new ConfigFile();
+ break;
+ // if start tag (ex. , , )
+ case XmlPullParser.START_TAG:
+ name = parser.getName();
+ if (name.equalsIgnoreCase("contact"))
+ {
+
+ try {
+ String section = parser.getAttributeValue(3);
+ if(section.equalsIgnoreCase("Digital"))
+ {
+ /* */
+ contact = new Contact(0,"", 0,1,1);
+ // get id and name for Contact
+ contact.name = parser.getAttributeValue(0);
+ String type = parser.getAttributeValue(1);
+
+ if(type.equals("Private Call"))
+ contact.contactType = Contact.PRIVATE;
+ else if (type.equals("Group Call"))
+ contact.contactType = Contact.GROUP;
+ contact.id = Integer.parseInt(parser.getAttributeValue(2));
+ }
+ else
+ contact = null;
+ }
+ catch (Exception e) {
+ SM.Exception(e.toString());
+ contact.id = 0;
+ }
+ }
+ else if (name.equalsIgnoreCase("radio-id"))
+ {
+ /* 101 */
+ try {
+ // get radio id
+ radio.id = Integer.parseInt(parser.nextText());
+ }
+ catch(Exception ex) {
+ SM.Debug(ex.toString());
+ }
+ }
+ else if (name.equalsIgnoreCase("radio-ip"))
+ {
+ /* 192.168.10.1 */
+ // get radio ip
+ radio.ip = parser.nextText();
+ }
+ else if (name.equalsIgnoreCase("zone"))
+ {
+ /* */
+ zone = new Zone();
+ try {
+ // set zone Id, Number and Name
+ zone.dbID = Integer.valueOf(parser.getAttributeValue(0));
+ zone.id = Integer.valueOf(parser.getAttributeValue(0));
+ zone.ZoneName = parser.getAttributeValue(1);
+ }
+ catch(Exception ex) {
+ SM.Debug(ex.toString());
+ }
+ }
+ else if(name.equalsIgnoreCase("channel"))
+ {
+ /* */
+ channel = new Channel();
+ try {
+ // set channel Id, Number and Name
+ channel.chName = parser.getAttributeValue(1);
+ channel.dbID = Integer.valueOf(parser.getAttributeValue(0));
+ channel.id = Integer.valueOf(parser.getAttributeValue(0));
+ }
+ catch(Exception ex) {
+ SM.Debug(ex.toString());
+ }
+ }
+ break;
+ // if end tag (ex. , , )
+ case XmlPullParser.END_TAG:
+ name = parser.getName();
+ if (name.equalsIgnoreCase("contact") && contact != null)
+ {
+ if(contact.contactType == Contact.PRIVATE || contact.contactType == Contact.GROUP)
+ contacts.add(contact); // add contact to Contacts list
+ }
+ else if (name.equalsIgnoreCase("channel"))
+ zone.channelList.add(channel); // add channel to Channels List
+ else if (name.equalsIgnoreCase("zone"))
+ zones.add(zone); // add zone to Zones List
+ else if (name.equalsIgnoreCase("configuration"))
+ done = true; // flag finish parsing
+ break;
+ }
+ eventType = parser.next();
+ }
+
+ // add Lists to config
+ config.contacts = contacts;
+ config.radio = radio;
+
+ // check if every zone has at least a channel and if not, create one
+ for(Zone zn :zones)
+ {
+ if(zn.channelList==null || (zn.channelList!=null && zn.channelList.size()== 0))
+ {
+ zn.channelList = new ArrayList();
+ Channel ch = new Channel();
+ ch.dbID = 0;
+ ch.chName = "N/A";
+ ch.id = 0;
+ zn.channelList.add(ch);
+ }
+ }
+
+ config.zones = zones;
+
+ //SM.Debug("CONFIG", config.toLongString());
+ }
+ catch (XmlPullParserException e) {
+ //e.printStackTrace();
+ SM.Exception(e.toString());
+
+ config = null;
+ }
+ catch (IOException e) {
+ //e.printStackTrace();
+ SM.Exception(e.toString());
+
+ config = null;
+ }
+
+ return config;
+ }
+
+ // get files and directory for crt Directory (file1)
+ private void recursiveFileFind(File[] crtFile){
+ int i = 0;
+ String filePath="";
+ if(crtFile!=null)
+ {
+ while(i != crtFile.length)
+ {
+ // get absolute path for crtFile
+ filePath = crtFile[i].getPath();
+ if(crtFile[i].isDirectory()){
+ // if crt file is a Directory get files for new file
+ File file[] = crtFile[i].listFiles();
+ recursiveFileFind(file);
+ }
+ i++;
+ // if crtFile path extension is xml, add to ArrayList
+ if(filePath.substring(filePath.length()-4, filePath.length()).equalsIgnoreCase(".xml"))
+ {
+ xmlPath.add(filePath);
+ }
+ }
+ }
+ }
+
+ public boolean downloadXMLFile(String Path)
+ {
+ try {
+ //set the download URL, a url that points to a file on the internet
+ //this is the file to be downloaded
+ //Path = "http://www.safemobile.com/upload/codeplugs/037TMA2140.xml";
+ URL url = new URL(Path);
+ //create the new connection
+ HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+
+ //set up some things on the connection
+ urlConnection.setRequestMethod("GET");
+ urlConnection.setDoOutput(true);
+
+ //and connect!
+ urlConnection.connect();
+
+ //set the path where we want to save the file
+ //in this case, going to save it on the root directory of the
+ //sd card.
+ File SDCardRoot = Environment.getExternalStorageDirectory();
+ //create a new file, specifying the path, and the filename
+ //which we want to save the file as.
+ File file = new File(SDCardRoot,"radioConfigFile.xml");
+
+ //this will be used to write the downloaded data into the file we created
+ FileOutputStream fileOutput = new FileOutputStream(file);
+
+ //this will be used in reading the data from the internet
+ InputStream inputStream = urlConnection.getInputStream();
+
+ //this is the total size of the file
+ //int totalSize = urlConnection.getContentLength();
+ //variable to store total downloaded bytes
+ int downloadedSize = 0;
+
+ //create a buffer...
+ byte[] buffer = new byte[1024];
+ int bufferLength = 0; //used to store a temporary size of the buffer
+
+ //now, read through the input buffer and write the contents to the file
+ while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
+ //add the data in the buffer to the file in the file output stream (the file on the sd card
+ fileOutput.write(buffer, 0, bufferLength);
+ //add up the size so we know how much is downloaded
+ downloadedSize += bufferLength;
+ }
+ //close the output stream when done
+ fileOutput.close();
+ SM.Debug(" ############## FINISH " + downloadedSize);
+ return true;
+
+ //catch some possible errors...
+ } catch (MalformedURLException e) {
+ e.printStackTrace();
+ SM.Exception(e.toString());
+
+ File SDCardRoot = Environment.getExternalStorageDirectory();
+ //delete file is failed to download
+ File file = new File(SDCardRoot,"radioConfigFile.xml");
+ Boolean result = file.delete();
+ SM.Debug("DELETE FILE: " + result);
+ return false;
+ } catch (IOException e) {
+ e.printStackTrace();
+ SM.Exception(e.toString());
+
+ File SDCardRoot = Environment.getExternalStorageDirectory();
+ //delete file is failed to download
+ File file = new File(SDCardRoot,"radioConfigFile.xml");
+ Boolean result = file.delete();
+ SM.Debug("DELETE FILE: " + result);
+
+ return false;
+ }
+ }
+
+
+ /*
+ private InputStream getTextFile(FileInputStream inputStream)
+ {
+ InputStream input = inputStream;
+
+ int read;
+ FileOutputStream fos = new FileOutputStream(new File(path + ".tmp"));
+
+ //DataOutputStream os = new DataOutputStream(new FileOutputStream("\\data\\data\\com.safemobile.radiopadd\\files\\"));
+ try {
+ input = new DataInputStream(new FileInputStream("c:\\binary.smc"));
+ while (true) { // exception deals catches EOF
+ read = input.r
+ fos.write(read);
+ //os.writeInt(is.readByte());
+ }
+ } catch (EOFException eof) {
+ System.out.println("Normal program termination.");
+ } catch (FileNotFoundException noFile) {
+ System.err.println("File not found! " + noFile);
+ } catch (IOException io) {
+ System.err.println("I/O error occurred: " + io);
+ } catch (Throwable anything) {
+ System.err.println("Abnormal exception caught !: " + anything);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ os.close();
+ } catch (IOException ignored) {
+ }
+ }
+ }
+ }
+ */
+
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/radio/Channel.java b/libSafeMobile/src/main/java/com/safemobile/lib/radio/Channel.java
new file mode 100644
index 0000000..b3682fd
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/radio/Channel.java
@@ -0,0 +1,26 @@
+package com.safemobile.lib.radio;
+
+public class Channel {
+
+ public int dbID;
+ public int id;
+ public String chName;
+
+ public Channel()
+ {
+
+ }
+
+ public Channel(int dbId, int id, String chName) {
+ this.dbID = dbId;
+ this.id = id;
+ this.chName = chName;
+ }
+
+ public String toString()
+ {
+ return "dbID: " + dbID + " | id: " + id + " | chName: " + chName ;
+
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/radio/Emerg.java b/libSafeMobile/src/main/java/com/safemobile/lib/radio/Emerg.java
new file mode 100644
index 0000000..56ce9db
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/radio/Emerg.java
@@ -0,0 +1,14 @@
+package com.safemobile.lib.radio;
+
+public class Emerg {
+ public int function = 0;
+ public int status = 0;
+
+ public Emerg(){
+
+ }
+ public String toString()
+ {
+ return "function: " + function + " | status: " + status ;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/radio/IncCall.java b/libSafeMobile/src/main/java/com/safemobile/lib/radio/IncCall.java
new file mode 100644
index 0000000..2196446
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/radio/IncCall.java
@@ -0,0 +1,58 @@
+package com.safemobile.lib.radio;
+
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.Mic;
+
+public class IncCall {
+ public int gwID;
+ public int rgwID;
+ public long Imei;
+ public int callStatus;
+ public int callType;
+ public int groupId;
+ public int userID;
+ public int opCode;
+ public Mic mic = null;
+
+ public long callerID = 0;
+ public long callDestID = 0;
+
+ public IncCall(){
+
+ }
+ public String toString()
+ {
+ return " Imei: " + Imei + " | opCode: " + opCode
+ + " | callStatus: " + callStatus+ " | callType: " + callType
+ + " | groupId: " + groupId + " | userID: " + userID;
+ }
+
+ public static String getCallTypeAsString(int type) {
+ switch (type) {
+ case AppParams.MotoAllCall: return "All Call";
+ case AppParams.MotoGroup: return "Group Call";
+ case AppParams.MotoPrivate: return "Private Call";
+ default: return "";
+ }
+ }
+
+ public static String getCallStatusAsString(int status) {
+ switch (status) {
+ case AppParams.InProgress: return "In Progress";
+ case AppParams.Initiated: return "Initiated";
+ case AppParams.Decoded: return "Decoded";
+ case AppParams.Hangtime: return "Hangtime";
+ case AppParams.Ended: return "Ended";
+ default: return "unknown";
+ }
+ }
+
+ public static String getCallInitiatorAsString(final long myID, int userID) {
+ if(userID == myID)
+ return "my Android";
+ else if (userID == 0)
+ return "Portable";
+ else
+ return "other Android";
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/radio/RadioGW.java b/libSafeMobile/src/main/java/com/safemobile/lib/radio/RadioGW.java
new file mode 100644
index 0000000..b8e7038
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/radio/RadioGW.java
@@ -0,0 +1,44 @@
+package com.safemobile.lib.radio;
+
+import java.util.ArrayList;
+
+public class RadioGW {
+ public int ID;
+ public int GW_ID;
+ public String IP;
+ public String IMEI;
+ public ArrayList zoneList;
+ public int lastZoneNr = 0;
+ public int lastChannelNr = 0;
+ public boolean isOnline = false;
+
+ public RadioGW(){zoneList = new ArrayList();}
+
+ public String toString()
+ {
+ return "ID: " + ID + " | GW_ID: " + GW_ID + " | IP: " + IP
+ + " | IMEI: " + IMEI ;
+ }
+
+ public String getChannelName() {
+ for(Zone zone: zoneList) {
+ if(zone.id == lastZoneNr) {
+ for(Channel ch: zone.channelList) {
+ if(ch.id == lastChannelNr)
+ return ch.chName;
+ }
+ }
+ }
+
+ return "";
+ }
+
+ public String getZoneName() {
+ for(Zone zone: zoneList) {
+ if(zone.id == lastZoneNr)
+ return zone.ZoneName;
+ }
+ return "";
+ }
+
+}
\ No newline at end of file
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/radio/RadioStatus.java b/libSafeMobile/src/main/java/com/safemobile/lib/radio/RadioStatus.java
new file mode 100644
index 0000000..f1cc947
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/radio/RadioStatus.java
@@ -0,0 +1,17 @@
+package com.safemobile.lib.radio;
+
+public class RadioStatus {
+ public int gwID = 0;
+ public int rgwID = 0;
+ public int status = 0;
+
+ public IncCall incCall = new IncCall();
+
+ public RadioStatus(){
+
+ }
+ public String toString()
+ {
+ return "gwID: " + gwID + " | rgwID: " + rgwID + " | status: " + status;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/radio/SUstatus.java b/libSafeMobile/src/main/java/com/safemobile/lib/radio/SUstatus.java
new file mode 100644
index 0000000..0350938
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/radio/SUstatus.java
@@ -0,0 +1,14 @@
+package com.safemobile.lib.radio;
+
+public class SUstatus {
+ public int imei;
+ public int status;
+
+ public SUstatus(){
+
+ }
+ public String toString()
+ {
+ return "imei: " + imei + " | status: " + status ;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/radio/Zone.java b/libSafeMobile/src/main/java/com/safemobile/lib/radio/Zone.java
new file mode 100644
index 0000000..9420967
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/radio/Zone.java
@@ -0,0 +1,51 @@
+package com.safemobile.lib.radio;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+public class Zone {
+ public int dbID;
+ public int id;
+ public String ZoneName="";
+
+ public ArrayList channelList = new ArrayList();
+ public Zone()
+ {
+ channelList = new ArrayList();
+ }
+
+ public String toString()
+ {
+ return "zoneDbID: " + id +" |zoneID: " + dbID + " | ZoneName: " + ZoneName ;
+ }
+
+ /**
+ * sort the list of channels based on their names
+ */
+ public void sortChannelListByName() {
+ //Sorting
+ Collections.sort(channelList, new Comparator() {
+ @Override
+ public int compare(Channel channel1, Channel channel2)
+ {
+ return channel1.chName.compareTo(channel2.chName);
+ }
+ });
+ }
+
+
+ /**
+ * sort the list of channels based on their ids
+ */
+ public void sortChannelListByChannelID() {
+ //Sorting
+ Collections.sort(channelList, new Comparator() {
+ @Override
+ public int compare(Channel channel1, Channel channel2)
+ {
+ return (channel1.id < channel2.id ? 1 : 0);
+ }
+ });
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/radio/ZoneChannel.java b/libSafeMobile/src/main/java/com/safemobile/lib/radio/ZoneChannel.java
new file mode 100644
index 0000000..1d691fd
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/radio/ZoneChannel.java
@@ -0,0 +1,46 @@
+package com.safemobile.lib.radio;
+
+public class ZoneChannel {
+
+ private Zone zone;
+ private Channel channel;
+ private boolean isSection = false;
+
+ public ZoneChannel(Zone zone) {
+ setZone(zone);
+ setSection(true);
+ }
+
+ public ZoneChannel(Zone zone, Channel channel) {
+ setZone(zone);
+ setChannel(channel);
+ if(channel != null)
+ setSection(false);
+ else
+ setSection(true);
+ }
+
+ public Zone getZone() {
+ return zone;
+ }
+
+ public void setZone(Zone zone) {
+ this.zone = zone;
+ }
+
+ public Channel getChannel() {
+ return channel;
+ }
+
+ public void setChannel(Channel channel) {
+ this.channel = channel;
+ }
+
+ public boolean isSection() {
+ return isSection;
+ }
+
+ public void setSection(boolean isSection) {
+ this.isSection = isSection;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/lib/radio/Zone_and_channel.java b/libSafeMobile/src/main/java/com/safemobile/lib/radio/Zone_and_channel.java
new file mode 100644
index 0000000..4081b2c
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/lib/radio/Zone_and_channel.java
@@ -0,0 +1,18 @@
+package com.safemobile.lib.radio;
+
+public class Zone_and_channel {
+ public int gwID = 0;
+ public int rgwID = 0;
+ public int zoneNr = 0;
+ public int channelNr = 0;
+
+ public Zone_and_channel(){
+
+ }
+ public String toString()
+ {
+ return "gwID: " + gwID + " | rgwID: " + rgwID + " | zoneNr: " + zoneNr
+ + " | mechannelNrss: " + channelNr ;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/libpad/PadRecording.java b/libSafeMobile/src/main/java/com/safemobile/libpad/PadRecording.java
new file mode 100644
index 0000000..3157770
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/libpad/PadRecording.java
@@ -0,0 +1,70 @@
+package com.safemobile.libpad;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import com.safemobile.lib.SM;
+
+
+public class PadRecording implements Serializable {
+
+ private static final long serialVersionUID = 7819490854198306882L;
+ public int dbID = 0;
+ public int userID = 0;
+ public long radioID = 0;
+ public long initRadioID = 0;
+ public int callType = 0;
+ public boolean isOutgoing = false;
+ public long timeGMT = 0;
+ public int duration = 0;
+
+
+ public long bytes_length = 0;
+ public long bytes_received = 0;
+ public int result = 0;
+
+ public PadRecording() {
+
+ }
+
+ public PadRecording(int dbID, int userID, long radioID, boolean isOutgoing, long initRadioID, int callType, long timeGMT, int duration) {
+ this.dbID = dbID;
+ this.userID = userID;
+ this.radioID = radioID;
+ this.isOutgoing = isOutgoing;
+ this.initRadioID = initRadioID;
+ this.callType = callType;
+ this.timeGMT = timeGMT;
+ this.duration = duration;
+ }
+
+ public static ArrayList parseTCPMsg(String msg) {
+
+ ArrayList recordings = new ArrayList();
+ try
+ {
+ msg = msg.replace("#", "");
+ // split payload to get contacts
+
+ // split contact by /
+ String[] contArr = msg.split("/");
+ PadRecording rec = new PadRecording();
+ rec.dbID = Integer.parseInt(contArr[0]);
+ rec.userID = Integer.parseInt(contArr[1]);
+ rec.radioID = Long.parseLong(contArr[2]);
+ rec.initRadioID = Long.parseLong(contArr[3]);
+ rec.callType = Integer.parseInt(contArr[4]);
+ rec.isOutgoing = (Integer.parseInt(contArr[5]) == 1 ? true: false);
+ rec.timeGMT = Long.parseLong(contArr[6]);
+ rec.duration = Integer.parseInt(contArr[7]);
+
+ recordings.add(rec);
+ }
+ catch(Exception ex)
+ {
+ SM.Exception("Exception parse Recording", ex.toString());
+ }
+
+ return recordings;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/libpad/PadTextMessage.java b/libSafeMobile/src/main/java/com/safemobile/libpad/PadTextMessage.java
new file mode 100644
index 0000000..4a2c649
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/libpad/PadTextMessage.java
@@ -0,0 +1,70 @@
+package com.safemobile.libpad;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import com.safemobile.lib.SM;
+
+public class PadTextMessage implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ public long dbID = 0;
+ public int userID = 0;
+ public long radioID = 0;
+ public String message = "";
+ public boolean isOutgoing = false;
+ public long timeGMT = 0;
+ public int status = 0;
+ public String seqID = "";
+ public Integer tmSeqID = 0;
+
+ public PadTextMessage() {
+
+ }
+
+ public PadTextMessage(long dbID, int usedID, long radioId, boolean isOutgoing, String msg, long timeGMT, int status, String seqID) {
+ this.dbID = dbID;
+ this.userID = usedID;
+ this.radioID = radioId;
+ this.isOutgoing = isOutgoing;
+ this.message = msg;
+ this.timeGMT = timeGMT;
+ this.status = status;
+ this.seqID = seqID;
+ }
+
+ public String toString() {
+ return dbID + "." + radioID + "[" + message + "]";
+ }
+
+ public static ArrayList parseTCPMsg(String msg) {
+
+ ArrayList messages = new ArrayList();
+ try
+ {
+ msg = msg.replace("#", "");
+ // split payload to get contacts
+
+ // split contact by /
+ String[] contArr = msg.split("/");
+ PadTextMessage message = new PadTextMessage();
+ message.dbID = Integer.parseInt(contArr[0]);
+ message.userID = Integer.parseInt(contArr[1]);
+ message.radioID = Long.parseLong(contArr[2]);
+ message.message = contArr[3];
+ message.timeGMT = Long.parseLong(contArr[4]);
+ message.isOutgoing = (Integer.parseInt(contArr[5]) == 1 ? true: false);
+ message.status = Integer.parseInt(contArr[6]);
+
+ messages.add(message);
+ }
+ catch(Exception ex)
+ {
+ SM.Exception("Exception parse Message", ex.toString());
+ }
+
+ return messages;
+
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/maps/MapGoogle.java b/libSafeMobile/src/main/java/com/safemobile/maps/MapGoogle.java
new file mode 100644
index 0000000..c2396e9
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/maps/MapGoogle.java
@@ -0,0 +1,172 @@
+package com.safemobile.maps;
+
+import android.view.LayoutInflater;
+
+import androidx.annotation.NonNull;
+
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.Marker;
+import com.safemobile.enums.MapType;
+import com.safemobile.interfaces.IMap;
+import com.safemobile.lib.Position;
+import com.safenet.lib.Geofence;
+import com.safenet.lib.Landmark;
+import com.safenet.lib.Unit;
+
+import java.util.ArrayList;
+
+public class MapGoogle implements
+ IMap,
+ GoogleMap.OnCameraIdleListener,
+ GoogleMap.OnCameraMoveStartedListener,
+ GoogleMap.OnMarkerClickListener,
+ GoogleMap.OnInfoWindowClickListener,
+ GoogleMap.OnInfoWindowLongClickListener,
+ GoogleMap.OnInfoWindowCloseListener,
+ GoogleMap.OnCameraMoveListener {
+ @Override
+ public void onCameraIdle() {
+
+ }
+
+ @Override
+ public void onCameraMove() {
+
+ }
+
+ @Override
+ public void onCameraMoveStarted(int i) {
+
+ }
+
+ @Override
+ public void onInfoWindowClick(@NonNull Marker marker) {
+
+ }
+
+ @Override
+ public void onInfoWindowClose(@NonNull Marker marker) {
+
+ }
+
+ @Override
+ public void onInfoWindowLongClick(@NonNull Marker marker) {
+
+ }
+
+ @Override
+ public boolean onMarkerClick(@NonNull Marker marker) {
+ return false;
+ }
+
+ @Override
+ public void setMapInteractionListener(MapInteraction delegate) {
+
+ }
+
+ @Override
+ public void showContactsOnMap(ArrayList units) {
+
+ }
+
+ @Override
+ public void updateMarkerPosition(Unit unit) {
+
+ }
+
+ @Override
+ public void setMapType(MapType mapType) {
+
+ }
+
+ @Override
+ public void setMapType(String mapType) {
+
+ }
+
+ @Override
+ public void centerZoomContact(Unit unit) {
+
+ }
+
+ @Override
+ public void centerZoomMapOnLocation(LatLng mapLocation) {
+
+ }
+
+ @Override
+ public void centerZoomMapOnLocation(LatLng mapLocation, float zoomLevel) {
+
+ }
+
+ @Override
+ public void showMyselfOnMap(Position position, boolean shouldOpenInfoBubble, boolean shouldCenterNow) {
+
+ }
+
+ @Override
+ public void hideMyselfFromMap() {
+
+ }
+
+ @Override
+ public void openInfoBubbleForMarker(Long markerKey) {
+
+ }
+
+ @Override
+ public void openInfoBubble() {
+
+ }
+
+ @Override
+ public void onShowLandmarksChangedHandler(boolean isShown, ArrayList landmarks) {
+
+ }
+
+ @Override
+ public void onShowGeofencesChangedHandler(boolean isShown, ArrayList geofences) {
+
+ }
+
+ @Override
+ public void onShowTrafficChangedHandler(boolean isShown) {
+
+ }
+
+ @Override
+ public void onMapReceived(Object map, LayoutInflater layoutInflater) {
+
+ }
+
+ @Override
+ public void onMapReceived(Object map, String tileServer) {
+
+ }
+
+ @Override
+ public void panZoomMap() {
+
+ }
+
+ @Override
+ public void onPause() {
+
+ }
+
+ @Override
+ public void onResume() {
+
+ }
+
+ @Override
+ public void refresh() {
+
+ }
+
+ @Override
+ public boolean isMapAvailable() {
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/libSafeMobile/src/main/java/com/safemobile/services/TCPService.java b/libSafeMobile/src/main/java/com/safemobile/services/TCPService.java
new file mode 100644
index 0000000..b734c77
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/services/TCPService.java
@@ -0,0 +1,180 @@
+package com.safemobile.services;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.safemobile.interfaces.ITCPListener;
+import com.safemobile.lib.AppParams;
+
+import android.annotation.SuppressLint;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.widget.Toast;
+
+public class TCPService extends Service {
+
+ private int[] startModes = {START_STICKY, START_NOT_STICKY, START_REDELIVER_INTENT};
+ private int mStartMode = startModes[0]; // indicates how to behave if the service is killed
+ private IBinder mBinder = new TCPBinder(); // interface for clients that bind
+ private boolean mAllowRebind = true; // indicates whether onRebind should be used
+ private TCPhandler tcp = null;
+ private TCPmsgParser tcpParser = null;
+
+ @Override
+ public void onCreate() {
+ // create a TCP connection and a TCP msg Parser
+ int port = 13589;
+ try {
+ port = Integer.parseInt(AppParams.PORT);
+ }
+ catch(Exception ex) { }
+
+ tcpParser = new TCPmsgParser();
+
+ if(tcp == null && !AppParams.IP.equalsIgnoreCase("n/a"))
+ {
+ tcp = new TCPhandler(getApplicationContext(), AppParams.IP, port);
+ }
+
+ }
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ // The service is starting, due to a call to startService()
+ return mStartMode;
+ }
+ @Override
+ public IBinder onBind(Intent intent) {
+ // A client is binding to the service with bindService()
+ return mBinder;
+ }
+ @Override
+ public boolean onUnbind(Intent intent) {
+ // All clients have unbound with unbindService()
+ return mAllowRebind;
+ }
+ @Override
+ public void onRebind(Intent intent) {
+ // A client is binding to the service with bindService(),
+ // after onUnbind() has already been called
+ }
+
+ @Override
+ public void onDestroy() {
+ // The service is no longer used and is being destroyed
+ Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
+ }
+
+ /** get TCP Connection in order to send messages through TCP */
+ public TCPhandler getTCPConnection()
+ {
+ return tcp;
+ }
+
+ /** Add TCP Listener to TCPmsgParser */
+ public boolean addITCPListener(ITCPListener listener)
+ {
+ if(tcpParser != null)
+ tcpParser.addTCPListener(listener);
+ else
+ return false;
+ return true;
+ }
+
+ /** remove all TCP Listeners */
+ public boolean clearITCPListeners()
+ {
+ if(tcpParser != null)
+ tcpParser.clearITCPListeners();
+ else
+ return false;
+ return true;
+ }
+
+
+ /** get TCP msg Parser in order to add a new TCP Listener */
+ public TCPmsgParser getTCPmsgParser()
+ {
+ if(tcpParser == null)
+ tcpParser = new TCPmsgParser();
+
+ return tcpParser;
+ }
+
+
+ /** Stop TCP Connection */
+ public void stopTCPConnection()
+ {
+ if(tcp != null)
+ {
+ tcp.Stop();
+ tcp = null;
+ }
+ }
+
+ /** restart the TCP Connection after the connection parameters had been changed */
+ public void recreateTCPConnection()
+ {
+ /*
+ Thread t = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(1000*2);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ */
+ // create a tcp connection
+ int port = 13589;
+ try {
+ port = Integer.parseInt(AppParams.PORT);
+ }
+ catch(Exception ex) { }
+ tcp = new TCPhandler(getApplicationContext(), AppParams.IP, port);
+ /* }
+ });
+ t.start();
+ */
+ }
+
+ public void recreateTCPConnection(String _ip, String _port)
+ {
+ // create a tcp connection
+ int port = 13589;
+ try {
+ port = Integer.parseInt(_port);
+ }
+ catch(Exception ex) { }
+ tcp = new TCPhandler(getApplicationContext(), _ip, port);
+ }
+
+ public void updateTCPparameters(String ip, String _port)
+ {
+ if(tcp!=null)
+ tcp.updateTCPparameters(ip, _port);
+ else
+ recreateTCPConnection();
+ }
+
+ /** recreate a TCPmsgParser */
+ public void recreateTCPmsgParser()
+ {
+ tcpParser = new TCPmsgParser();
+ }
+
+ @SuppressLint("SimpleDateFormat")
+ public String getCurrentTime() {
+ SimpleDateFormat dateformat =
+ new SimpleDateFormat("HH:mm:ss MM/dd/yyyy");
+ return (dateformat.format(new Date()));
+ }
+
+ /** get TCPService Binder */
+ public class TCPBinder extends Binder {
+ public TCPService getService() {
+ return TCPService.this;
+ }
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/services/TCPhandler.java b/libSafeMobile/src/main/java/com/safemobile/services/TCPhandler.java
new file mode 100644
index 0000000..038ca86
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/services/TCPhandler.java
@@ -0,0 +1,704 @@
+package com.safemobile.services;
+import java.io.*;
+import java.net.*;
+import java.nio.charset.Charset;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiManager;
+
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.SM;
+import com.safemobile.lib.TCPmsg;
+
+
+public class TCPhandler implements Runnable
+{
+ private boolean alive = true;
+
+ public String serverHostname = new String ("10.120.1.114");//
+ private int port = 13579;
+ private Thread listenThread;
+ private Socket soc =null;
+
+ //private BufferedReader recv;
+ //private PrintWriter writer;
+
+ private DataInputStream input;
+ private DataOutputStream output;
+ private Timer timer;
+
+ private String leftOver = "";
+
+ public static LinkedList msgList;
+ private volatile int n=0;
+
+ public Boolean isConnectionUP = false;
+ public Boolean previousConnectionWasUP = false;
+
+ private Context context;
+ private boolean isWiFiOn = true;
+
+ public TCPhandler(Context context, String hostName, int p)
+ {
+
+ this.context = context;
+ serverHostname=hostName;
+ port=p;
+
+ msgList = new LinkedList();
+ SM.Debug("---TCPhandler constructor [" + hostName + "," + p + "] ---");
+ listenThread = new Thread(this, "TCPlisten");
+ listenThread.start(); // (2) Start the thread.
+
+
+ // create timer to check socket status
+ timer = new Timer();
+ timer.scheduleAtFixedRate(new TimerTask() {
+ @Override
+ public void run() {
+ try {
+ //Looper.prepare();
+ //mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ // get if is authenticated
+ //Write("0.0", "d");
+ previousConnectionWasUP = isConnectionUP;
+
+ // try to send something
+ TCPmsgParser._fireonTCPConnectionStatusEvent(isConnectionUP, previousConnectionWasUP);
+ }
+ catch (Exception e) {
+ //e.printStackTrace();
+ SM.Exception("TIMERException", e.toString());
+ }
+ }
+ }, 0, 3000);
+
+ // get WiFi state
+ ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ if(mWifi.isConnectedOrConnecting())
+ isWiFiOn = true;
+
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ context.registerReceiver(mReceived, intentFilter);
+ }
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ if(soc!=null)
+ soc.close();
+
+ soc = new Socket();
+ soc.connect(new InetSocketAddress(serverHostname, port), 5000);
+
+ //soc.setSoTimeout(3000);
+ //SM.Debug("Socket timeout:" + soc.getSoTimeout() );
+ //soc.setSoTimeout(5000);
+
+ input = new DataInputStream(soc.getInputStream());
+ output = new DataOutputStream(soc.getOutputStream());
+
+ //recv= new BufferedReader(new InputStreamReader(soc.getInputStream()));
+ //writer =new PrintWriter(soc.getOutputStream()) ;
+
+
+ if(soc !=null) {
+ //previousConnectionWasUP = isConnectionUP;
+ isConnectionUP = true;
+ triggerTCPConnectionStateEvent();
+ }
+
+ }
+ catch (UnknownHostException e)
+ {
+ SM.Debug("UnknownHostException", "TCPhandler break:"+e.toString());
+ }
+ catch (IllegalArgumentException e)
+ {
+ SM.Debug("IllegalArgumentException", "TCPhandler break:"+e.toString());
+ }
+ catch (IOException e)
+ {
+ SM.Debug("IOException", "TCPhandler break:"+e.toString());
+ }
+
+ while(alive)
+ {
+ //SM.Debug("Waiting for data...");
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ SM.Debug("TCPhandler Crash1 on sleep:"+e.toString());
+ }
+
+ while(isConnectionUP)
+ {
+ try
+ {
+ Thread.sleep(100);
+ //SM.Debug("Waiting for data...");
+ //process leftover
+ try
+ {
+ boolean FinishLeftOver =true;
+ while (FinishLeftOver)
+ {
+ // add this replacement if message length doesn't contain the last #
+ // leftOver = leftOver.replace("##", "#");
+ String[] tempArr2 = leftOver.split("#");
+ if (tempArr2.length > 1)
+ {
+ int messLen;
+ try
+ {
+ messLen = Integer.parseInt(tempArr2[1]);
+
+ //TODO talk to Gaby to fix this on Bridge
+
+ }
+ catch (Exception e)
+ {
+ SM.Debug("leftovers", "incorect msg len leftOver =" + tempArr2[1]);
+ messLen =-1;
+ }
+
+ if(messLen>leftOver.length())
+ {
+ FinishLeftOver =false;
+ break;
+ }
+ else if(messLen==leftOver.length())
+ {
+ TCPmsg msg = new TCPmsg(leftOver.toCharArray());
+ SM.Debug("leftovers", "RX from leftOver:"+msg.allData);
+
+ if(msg.allData.contains("#92#"))
+ prioritizePongReceived();
+
+ msgList.add(msg);
+ leftOver ="";
+ FinishLeftOver =false;
+ break;
+ }
+ else // we have more message in leftover
+ {
+ TCPmsg msg = new TCPmsg(leftOver.substring(0,messLen).toCharArray());
+ SM.Debug("leftovers", "RX from leftOver:"+msg.allData);
+
+ if(msg.allData.contains("#92#"))
+ prioritizePongReceived();
+
+ msgList.add(msg);
+ leftOver = leftOver.substring(messLen,leftOver.length());
+ }
+ }
+ else FinishLeftOver = false;
+ }
+ }
+ catch (Exception e)
+ {
+ SM.Debug("leftovers", "Error on process leftover"+e.toString());
+ }
+ //end process leftover
+
+ String data ="";
+ n=0;
+ //char[] buf = new char[1024];
+ //n = recv.read(buf);
+
+ byte[] buf = new byte[1024];
+ // read data into buffer
+ n = input.read(buf);
+ //connection closed by server
+ if(n==-1)
+ {
+ SM.Debug("TCP Client", "Connection closed by server!");
+ soc.close();
+ //previousConnectionWasUP = isConnectionUP;
+ isConnectionUP = false;
+ triggerTCPConnectionStateEvent();
+ soc = null;
+ break;
+ }
+
+
+ byte[] temp = new byte[n];
+ for(int i=0;i1) // avoid case with only one #
+ {
+ data = leftOver+data;
+ leftOver = "";
+ }
+
+ //search for overflow message
+ String[] tempArr = data.split("#");
+ if ((tempArr.length == 0) || (tempArr.length == 1))
+ {
+ SM.Debug("TCP Client", "incorect messagebuss message=" + data);
+ continue;
+ }
+ //get msg len
+ // for(int i=0;idata.length())
+ //if(messLen>n)
+ {
+ //SM.Debug("duda","messLen=" + messLen +" data.length():" +data.length()+"n:"+n);
+ leftOver = data; // Add by bigu
+ continue;
+ }
+ //perform cut
+ //SM.Debug("We got leftover ....message length("+messLen+") != actual length("+data.length()+")");
+ temMSG = data.substring(0,messLen).toCharArray();
+ //SM.Debug("temMSG:"+temMSG.toString());
+ leftOver = data.substring(messLen,data.length());
+ //SM.Debug("leftOver:"+leftOver);
+ //leftOver = data.substring(messLen,n);
+ //SM.Debug("left over string:"+leftOver);
+ }
+ //decode TCP msg
+ TCPmsg msg = new TCPmsg(temMSG);
+
+ SM.Debug("������� RX �������", msg.allData);
+
+ if(msg.allData.contains("#92#"))
+ prioritizePongReceived();
+
+ msgList.add(msg);
+
+ }
+ catch(Exception ex)
+ {
+ SM.Debug("TCPHandler", "TCPhandler/run/break:"+ex.toString());
+ //previousConnectionWasUP = isConnectionUP;
+ isConnectionUP = false;
+ triggerTCPConnectionStateEvent();
+ }
+ }//while(connOK)
+
+
+ //
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ SM.Debug("TCPhandler Crash2 on sleep:"+e.toString());
+ //previousConnectionWasUP = isConnectionUP;
+ }
+
+ //try to restart connection
+ if(alive && isWiFiOn)
+ RestartTCP();
+
+ }//while(alive)
+ SM.Debug("==================================");
+ SM.Debug("TCP listenThread stoped!! alive = false");
+ SM.Debug("==================================");
+ }
+
+
+ /**
+ * Create a bypass in order to trigger the ping received event
+ */
+ private void prioritizePongReceived() {
+ TCPmsgParser._firePONGReceivedEvent();
+ }
+
+
+ /* Broadcast Received for WiFi Connect/Disconnect */
+ public BroadcastReceiver mReceived = new BroadcastReceiver() {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ SM.Debug("WIFI STATE", action);
+
+ if(action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){
+ NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+ // close socket if the wifi is disconnecting or disconnected
+ if(!info.isConnectedOrConnecting()) {
+ closeSocket();
+ isWiFiOn = false;
+ }
+ else
+ isWiFiOn = true;
+ }
+ }
+ };
+
+
+
+ /** Send a message through the TCP Socket
+ * @param seqID The messages's sequence ID (a number of order)
+ * @param msg The messages which will be sent
+ * @return True if the message was sent
+ */
+ public boolean Write(String seqID, String msg)
+ {
+
+ try
+ {
+
+ /*
+ if(writer != null)
+ {
+ String cmdok = "#" + seqID + msg;
+ Integer tmp = cmdok.length() + 1;
+ //SM.Debug("tmp:"+tmp);
+
+ tmp += Integer.toString(tmp).length();// tmp.ToString().Length;
+ if((tmp==10)||(tmp==100)||(tmp==1000)) tmp++;
+ cmdok = "#" + Integer.toString(tmp) + cmdok;
+ writer.write(encryptTEA(cmdok));
+ writer.flush();
+ SM.Debug("TX:"+encryptTEA(cmdok));
+ return true;
+ }*/
+
+ if(output != null)
+ {
+ try {
+ Thread.sleep(10);
+ String cmdok = "#" + seqID + msg;
+ Integer tmp = cmdok.length() + 1;
+ //SM.Debug("tmp:"+tmp);
+
+ tmp += Integer.toString(tmp).length();// tmp.ToString().Length;
+ if((tmp==10)||(tmp==100)||(tmp==1000)) tmp++;
+ cmdok = "#" + Integer.toString(tmp) + cmdok;
+
+ byte[] mess = encryptTEA(cmdok);
+
+
+ output.write(mess);
+ output.flush();
+
+ // show only notACK messages
+ //if(mess[3] != 0x0C)
+ SM.Debug(" ", new String(mess));
+ return true;
+ }
+ catch (IOException e) {
+ //e.printStackTrace();
+ SM.Exception("TCPClient[Send]", e.toString());
+ } catch (InterruptedException e) {
+ SM.Exception("TCPClient[Send]", e.toString());
+ } catch (NoSuchElementException e) {
+ SM.Exception("TCPClient[Send]", e.toString());
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ SM.Debug("TCPhandler Write Procedure:"+e.toString());
+ }
+ return false;
+ }
+
+
+ public void setConnectionIsDown() {
+ if(input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ }
+ finally {
+ input = null;
+ }
+ }
+
+ isConnectionUP = false;
+ }
+
+ /* Encrypt a string using an encryption algorithm,
+ * in this case TEA */
+ public static byte[] encryptTEA(String toEncryptData) {
+ byte[] encryptedByteArray = new byte[]{};
+
+ /*
+ //encrypt message using TEA
+ try {
+ encryptedByteArray = TEA.encrypt(toEncryptData);
+ } catch (UnsupportedEncodingException e) {
+ SM.Exception("encryptTEA Exception(UEE): " + e.toString());
+ } catch (IndexOutOfBoundsException e) {
+ SM.Exception("encryptTEA Exception(IOoBE): " + e.toString());
+ } catch (NullPointerException e) {
+ SM.Exception("encryptTEA Exception(NPE): " + e.toString());
+ }
+ //*/
+
+ // no encryption
+ encryptedByteArray = toEncryptData.getBytes();
+
+ return encryptedByteArray;
+ }
+
+ /* Decrypt a string using an encryption algorithm,
+ * in this case TEA */
+ public static byte[] decryptTEA(byte[] toDecryptData) {
+ byte[] decryptedByteArray = new byte[]{};
+
+ /*
+ String sm = "";
+ for(int i=0; i _listeners = new ArrayList();
+ private Thread TCPmsgParserThread;
+
+ public TCPmsgParser()
+ {
+ TCPmsgParserThread = new Thread(this, "TCPmsgParserThread");
+ TCPmsgParserThread.start(); // (2) Start the thread.
+ }
+
+ public synchronized void addTCPListener( ITCPListener l ) {
+ _listeners.add( l );
+ }
+
+ public synchronized void removeTCPListener( ITCPListener l ) {
+ _listeners.remove( l );
+ }
+
+ public synchronized void clearITCPListeners() {
+ _listeners.clear();
+ }
+
+ public int getListenersSize()
+ {
+ return _listeners.size();
+ }
+
+ private synchronized void _fireLoginEvent() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onLoginReceived( event );
+ }
+ }
+ private synchronized void _fireGPSEvent() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onGPSReceived(event);
+ }
+ }
+ private synchronized void _fireSMSEvent() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onSMSReceived( event );
+ }
+ }
+
+ private synchronized void _fireLastSMSEvent() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onLastSMSsReceived(event);
+ }
+ }
+
+ private synchronized void _fireVehEvent() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onVehiclesReceived( event );
+ }
+ }
+
+ private synchronized void _fireNewSMS() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onNewSMSReceived(event);
+ }
+ }
+
+ private synchronized void _fireSMSconfirm() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onSMSAckReceived(event);
+ }
+ }
+
+ private synchronized void _fireLastPos() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onLastPositionsReceived(event);
+ }
+ }
+
+ private synchronized void _fireRadioEvent() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onRadioMsgReceived(event);
+ }
+ }
+
+ private synchronized void _fireHistPos() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onHistoryPositionsReceived(event);
+ }
+ }
+
+ private synchronized void _fireHistCount() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onHistoryPositionsCountReceived(event);
+ }
+ }
+
+ private synchronized void _fireAlarmList() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onAlarmsReceived(event);
+ }
+ }
+
+ private synchronized void _fireAlarmACK() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).onAlarmAckReceived(event);
+ }
+ }
+
+ private synchronized void _fireAlarmLive() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next() ).alarmLiveRecv(event);
+ }
+ }
+
+ private synchronized void _fireRecordList() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next()).onRecordingsListReceived(event);
+ }
+ }
+
+ private synchronized void _fireRecordPlay() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next()).onRecordingPlayReceived(event);
+ }
+ }
+
+ private synchronized void _firePOLLEvent() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next()).onPollReceived(event);
+ }
+ }
+
+ private synchronized void _fireConnectionReplyEvent() {
+ TCPEvent event = new TCPEvent( this, _msg );
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next()).onConnectionReplyReceived(event);
+ }
+ }
+
+ private synchronized void _fireContactsReceivedEvent() {
+ TCPEvent event = new TCPEvent( this, _msg );
+
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next()).onContactsListReceived(event);
+ }
+ }
+
+ private synchronized void _fireRecordingsReceivedEvent() {
+ TCPEvent event = new TCPEvent( this, _msg );
+
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next()).onRecordingsListReceived(event);
+ }
+ }
+
+ private synchronized void _fireTextMessagesReceivedEvent() {
+ TCPEvent event = new TCPEvent( this, _msg );
+
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next()).onTextMessagesListReceived(event);
+ }
+ }
+
+
+ private synchronized void _fireRecordingPlayReceivedEvent() {
+ TCPEvent event = new TCPEvent( this, _msg );
+
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next()).onRecordingPlayReceived(event);
+ }
+ }
+
+
+ public static synchronized void _fireTCPConnectionDownEvent(boolean previuosWasConnectionUp) {
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next()).onTCPConnectionDown(previuosWasConnectionUp);
+ }
+ }
+
+ public static synchronized void _fireTCPConnectionUpEvent(boolean previuosWasConnectionUp) {
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next()).onTCPConnectionUp(previuosWasConnectionUp);
+ }
+ }
+
+
+ public static synchronized void _fireonTCPConnectionStatusEvent(boolean isConnectionUp, boolean previuosWasConnectionUp) {
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next()).onTCPConnectionStatusReceived(isConnectionUp, previuosWasConnectionUp);
+ }
+ }
+
+ public static synchronized void _firePONGReceivedEvent() {
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (ITCPListener) listeners.next()).onPONGReceived();
+ }
+ }
+
+
+ @Override
+ public void run()
+ {
+ while(run)
+ {
+ //SM.Debug("TCPmsgParser waiting for data...");
+ sleep(1);
+
+ if(TCPhandler.msgList==null)
+ continue;
+ if(!TCPhandler.msgList.isEmpty())
+ {
+ try
+ {
+ _msg = TCPhandler.msgList.poll();
+ if(_msg == null)
+ continue;
+ if(_msg.OK == false)
+ continue;
+ //parse the rest of the message;
+
+ switch(_msg.opCode)
+ {
+ case 40:{
+ _fireLoginEvent();
+ break;
+ }
+
+ case 41:{
+ _fireVehEvent();
+ break;
+ }
+
+ case 42:{
+ _fireSMSEvent();
+ break;
+ }
+
+ case 43:{
+ _fireLastSMSEvent();
+ break;
+ }
+
+ case OperationCodes.TM_ACK:{
+ _fireSMSconfirm();
+ break;
+ }
+ case OperationCodes.TM_ACK_SD:{
+ _fireSMSconfirm();
+ break;
+ }
+
+ case OperationCodes.RECEIVED_TM:{
+ _fireNewSMS();
+ break;
+ }
+
+ case 45:{
+ _fireLastPos();
+ break;
+ }
+
+ case 131:{
+ _fireGPSEvent();
+ break;
+ }
+
+ case 231:{
+ _firePOLLEvent();
+ break;
+ }
+
+ case 50:{
+ _fireRadioEvent();
+ break;
+ }
+
+ case 46:{
+ _fireHistPos();
+ break;
+ }
+
+ case 86:{
+ _fireHistCount();
+ break;
+ }
+
+ case 47:{
+ _fireAlarmList();
+ break;
+ }
+
+ case 48:{
+ _fireAlarmACK();
+ break;
+ }
+
+ case 49:{
+ _fireRecordList();
+ break;
+ }
+
+ case 38:{
+ _fireRecordPlay();
+ break;
+ }
+
+ case 135:
+ case 136:
+ case 137:
+ case 138:
+ case 140:{
+ _fireAlarmLive();
+ break;
+ }
+
+ case OperationCodes.PONG: {
+ //_firePONGReceivedEvent();
+ break;
+ }
+
+ case OperationCodes.CONNECTION_REP: {
+ _fireConnectionReplyEvent();
+ break;
+ }
+
+ case OperationCodes.CONTACTS_REP: {
+ sleep(15);
+ _fireContactsReceivedEvent();
+ break;
+ }
+
+ case OperationCodes.TM_LIST_REP: {
+ _fireTextMessagesReceivedEvent();
+ break;
+ }
+
+ case OperationCodes.RECORDINGS_LIST_REP: {
+ _fireRecordingsReceivedEvent();
+ break;
+ }
+
+ case OperationCodes.RECORDING_REP: {
+ _fireRecordingPlayReceivedEvent();
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ catch(Exception ex)
+ {
+ try {
+ if(TCPhandler.msgList.size() > 0)
+ _msg = TCPhandler.msgList.remove(0);
+ }
+ catch(NoSuchElementException exe)
+ {
+ SM.Exception("TCP msg Parser", "NoSuchElementException");
+ }
+ }
+ }
+
+
+ }
+ /*
+ catch (Exception e)
+ {
+ SM.Debug("Error on fire Event:"+e.toString());
+ break;
+ }
+
+ }*/
+ SM.Debug("TCPmsgParser listen thread stoped.");
+ }
+
+ private void sleep(int miliseconds) {
+ try {
+ Thread.sleep(miliseconds);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ public void clearMsgList()
+ {
+ TCPhandler.msgList.clear();
+ }
+
+ public void Stop()
+ {
+ run = false;
+ // stop thread
+ if(TCPmsgParserThread != null)
+ {
+ Thread moribund = TCPmsgParserThread;
+ TCPmsgParserThread = null;
+ moribund.interrupt();
+ }
+ SM.Debug("Stoping TCPmsgParser");
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/services/TEA.java b/libSafeMobile/src/main/java/com/safemobile/services/TEA.java
new file mode 100644
index 0000000..f767a18
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/services/TEA.java
@@ -0,0 +1,280 @@
+package com.safemobile.services;
+import java.io.UnsupportedEncodingException;
+
+public class TEA {
+
+ private final static long DELTA = 0x9E3779B9L;
+ private final static long STEPS = 32;
+ private final static long UNDELTA = 0xC6EF3720L;
+ private static final String password = "SafeMobileBridge";
+ private static String encoding = "UTF-8";
+ private static long[] encrypted;
+ private static long[] decrypted;
+ private static long[] key;
+
+ public TEA(String password, String encoding) throws UnsupportedEncodingException {
+ // convert key to long
+ key = convertByteArrayToLongArray(password.getBytes(encoding));
+ TEA.encoding = encoding;
+ }
+
+ public TEA(String password) throws UnsupportedEncodingException {
+ // convert key to long
+ key = convertByteArrayToLongArray(password.getBytes(encoding));
+ }
+
+
+ public static byte[] encrypt(String toEncrypt) throws UnsupportedEncodingException {
+ encrypted = new long[200];
+
+ key = convertByteArrayToLongArray(password.getBytes(encoding));
+
+ // convert String to long array
+ long[] values = convertByteArrayToLongArray(toEncrypt.getBytes(encoding));
+
+ encrypted = new long[values.length];
+
+ // encipher the long array
+ for(int i=0; i 0)
+ {
+ /*
+ sum += DELTA;
+ y += ((z << 4)+a) ^ (z+sum) ^ ((z >> 5)+b);
+ z += ((y << 4)+c) ^ (y+sum) ^ ((y >> 5)+d);
+ */
+ sum = (long)((int)(sum + DELTA) & 0xFFFFFFFFL);
+
+ /*
+ System.out.println("left: " + (ctu(z<<4) + a));
+ System.out.println("center: " + ctu(z + sum));
+ System.out.println("right: " + (ctu(z>>>5) + b));
+ */
+ y = ctu(y + ((ctu(z<<4) + a) ^ (z + sum) ^ (ctu(z>>>5) + b)));
+ z = ctu(z + ((ctu(y<<4) + c) ^ (y + sum) ^ (ctu(y>>>5) + d)));
+
+ //System.out.println("Y = " + y + " | " + "Z = " + z) ;
+ }
+ w[0]=y; w[1]=z;
+
+ //System.out.println("Encrypted: " + y + " | " + z);
+ }
+
+ private static void decipher(long v[], long w[], long k[])
+ {
+ long y=v[0],z=v[1],sum=UNDELTA, a=k[0],b=k[1], c=k[2],d=k[3],n=STEPS;
+ /* sum = delta<<5, in general sum = delta * n */
+ while(n-->0)
+ {
+ z = ctu(z - ((ctu(y << 4)+c) ^ (y+sum) ^ (ctu(y >>> 5)+d)));
+ y = ctu(y - ((ctu(z << 4)+a) ^ (z+sum) ^ (ctu(z >>> 5)+b)));
+
+ //System.out.println("Y = " + y + " | " + "Z = " + z) ;
+
+ sum -= DELTA;
+ }
+ w[0]=y; w[1]=z;
+ //System.out.println("Y = " + y + " | " + "Z = " + z) ;
+ }
+
+ /*
+ private long convertToUnsigned(long value) {
+ return (((int) value) & 0xFFFFFFFFL);
+ }
+ */
+
+ private static long ctu (long value) {
+ return (((int) value) & 0xFFFFFFFFL);
+ }
+
+
+ private static long[] convertByteArrayToLongArray(byte[] toConvert) {
+ // convert string in an array of bytes
+ byte[] by = toConvert;
+
+
+ // get the size of long array considering that a long has 4bytes
+ int size = (int) Math.ceil(by.length / 4);
+
+ // if the size of the array is an odd number I should increase it because
+ // encryption needs an array of two long values
+ if(size % 2 != 0)
+ size++;
+
+ long[] values = new long[size];
+
+ // convert every string value to a long one by shifting 4 chars
+ // a long is 4 bytes
+ for(int i=0; i= by.length ) ? 0 : (byte) by[i+3]);
+ byte c3 = ((i+2 >= by.length ) ? 0 : (byte) by[i+2] );
+ byte c2 = ((i+1 >= by.length ) ? 0 : (byte) by[i+1] );
+ byte c1 = ((i >= by.length ) ? 0 : (byte) by[i] );
+
+ //System.out.println("###" + c4 + " | " + c3 + " | " + c2 + " | " + c1);
+
+ values[i/4] = ctu(((c4 & 0x00FFL) << 24) + ((c3 & 0x00FFL) << 16) + ((c2 & 0x00FFL) << 8) + ((c1 & 0x00FFL)));
+ //System.out.println("##### " + (encrypted == null ? 0 : encrypted[i/4]) + " | " + values[i/4]);
+ }
+ return values;
+ }
+
+
+ private static byte[] convertLongArrayToByteArray(long[] array, boolean isDecrypt) {
+ //String myString = "";
+ byte[] byteArray = new byte[array.length * 4];
+ byte[] byteArrayReduced;
+ int sizeToReduce = 0;
+
+ // convert every bytes from a long into a char using masks
+ for(int i=0; i> 8);
+ byte c3 = (byte) ((array[i] & 0x00FF0000) >> 16);
+ byte c4 = (byte) ((array[i] & 0xFF000000) >> 24);
+
+ //System.out.println("###" + array[i] + " | c4: " + c4 + " | " + c3 + " | " + c2 + " | " + c1);
+ //*
+ // remove last bytes containing 0 because they are unwanted information
+ if(array.length > 1 && i==(array.length-1) && isDecrypt)
+ {
+ System.out.println("LAST Chunck of four");
+ if (c4 != 0)
+ byteArray[i*4+3] = c4;
+ else
+ sizeToReduce++;
+ if (c3 != 0)
+ byteArray[i*4+2] = c3;
+ else
+ sizeToReduce++;
+ if (c2 != 0)
+ byteArray[i*4+1] = c2;
+ else
+ sizeToReduce++;
+ if (c1 != 0)
+ byteArray[i*4] = c1;
+ else
+ sizeToReduce++;
+ }
+ // add value because it's not the last long value
+
+ else //*/
+ {
+ byteArray[i*4] = c1;
+ byteArray[i*4+1] = c2;
+ byteArray[i*4+2] = c3;
+ byteArray[i*4+3] = c4;
+ }
+
+ }
+
+ // remove the 0's from the string, they were added when converting long
+ //System.out.println("#### Syze to reduce : " + sizeToReduce);
+ byteArrayReduced = new byte[byteArray.length - sizeToReduce];
+ for(int i=0; i<(byteArray.length - sizeToReduce); i++)
+ byteArrayReduced[i] = byteArray[i];
+
+ /*
+ try {
+ myString = new String ( byteArray, encoding);
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }*/
+
+ //myString = new String(byteArray);
+
+ return byteArrayReduced;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/uicomponents/EnhancedTextView.java b/libSafeMobile/src/main/java/com/safemobile/uicomponents/EnhancedTextView.java
new file mode 100644
index 0000000..1aa5b0f
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/uicomponents/EnhancedTextView.java
@@ -0,0 +1,84 @@
+package com.safemobile.uicomponents;
+
+import java.util.Hashtable;
+
+import com.safemobile.lib.R;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Typeface;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+public class EnhancedTextView extends TextView {
+
+ private static final Hashtable cache = new Hashtable();
+
+ public EnhancedTextView(Context context) {
+ super(context);
+ }
+
+ public EnhancedTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setCustomFont(context, attrs);
+ }
+
+ public EnhancedTextView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setCustomFont(context, attrs);
+ }
+
+ /**
+ * Set a custom TypeFace that is specified in the XML attrs of the object
+ * @param ctx The context of the application
+ * @param attrs The attributes which are passed from the XML
+ */
+ private void setCustomFont(Context ctx, AttributeSet attrs) {
+ TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.EnhancedTextView);
+ String customFont = a.getString(R.styleable.EnhancedTextView_setFont);
+ setCustomFont(ctx, customFont);
+ a.recycle();
+ }
+
+ /**
+ * Function to change the TypeFace/Font of a textView
+ * @param ctx The context of the application
+ * @param fontName The name of the TypeFace which needs to be set
+ * @return A boolean telling if the TypeFace was set, or false in case of error
+ */
+ public boolean setCustomFont(Context ctx, String fontName) {
+ Typeface tf = getTypeFace(ctx, fontName);
+ if(tf == null)
+ return false;
+
+ setTypeface(tf);
+ return true;
+ }
+
+
+ /**
+ * In the Android versions previous than 4.0 there is a memory leak that won't free TypeFaces.
+ * In order to fix this issue, a HashMap (cache) of TypeFaces will be created that will fetch a TypeFace
+ * if it exists, or it will create it and then return it.
+ * @param c The context of the application
+ * @param fontName The name of the typeface which needs to be fetched
+ * @return The desired Typeface object, or null if the typeface wasn't in the cache and could not be created
+ */
+ public static Typeface getTypeFace(Context c, String fontName){
+ synchronized(cache){
+ if (cache == null || fontName == null)
+ return null;
+
+ if(!cache.containsKey(fontName)){
+ try {
+ Typeface t = Typeface.createFromAsset(c.getAssets(), fontName);
+ cache.put(fontName, t);
+ }
+ catch(Exception ex) {
+ return null;
+ }
+ }
+ return cache.get(fontName);
+ }
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safemobile/uicomponents/TitledComboBox.java b/libSafeMobile/src/main/java/com/safemobile/uicomponents/TitledComboBox.java
new file mode 100644
index 0000000..afed1cb
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safemobile/uicomponents/TitledComboBox.java
@@ -0,0 +1,621 @@
+package com.safemobile.uicomponents;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.ConcurrentModificationException;
+import java.util.Iterator;
+
+import com.safemobile.adapters.ContactsComboBoxAdapter;
+import com.safemobile.adapters.ZoneChannelComboBoxAdapter;
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.Contact;
+import com.safemobile.lib.R;
+import com.safemobile.lib.SM;
+import com.safemobile.lib.radio.Channel;
+import com.safemobile.lib.radio.Zone;
+import com.safemobile.lib.radio.ZoneChannel;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Typeface;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.InputType;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class TitledComboBox extends RelativeLayout {
+
+ private enum SortMode {NAME, CALL_TYPE};
+ public enum ComboType {CONTACT, ZONE, STRING};
+ private ComboType type = ComboType.CONTACT;
+
+ private Context context;
+ private ArrayList listValues = new ArrayList();
+ private Contact selectedContact = null;
+ private ZoneChannel selectedZoneChannel = null;
+ private ArrayList contacts = new ArrayList();
+ private ArrayList zoneChannels = new ArrayList();
+ //private DialDialog manualDialDialog;
+
+ /* UI Elements */
+ private AlertDialog alert;
+ private LinearLayout layoutCombo;
+ private TextView titleCombo;
+ private TextView textViewComboValue;
+ private ImageView imageViewCombo;
+
+ public TitledComboBox(Context context) {
+ super(context);
+
+ inflateUI(context);
+ }
+
+ public TitledComboBox(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ inflateUI(context);
+ }
+
+ public TitledComboBox(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ inflateUI(context);
+ }
+
+
+ private void inflateUI(Context context) {
+ this.context = context;
+
+ LayoutInflater inflater = (LayoutInflater) context
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.titled_combobox, this);
+
+ layoutCombo = (LinearLayout) findViewById(R.id.layoutCombo);
+ if(layoutCombo != null)
+ layoutCombo.setOnClickListener(layoutComboClickListener);
+
+ titleCombo = (TextView) findViewById(R.id.titleCombo);
+ imageViewCombo = (ImageView) findViewById(R.id.imageViewCombo);
+ textViewComboValue = (TextView) findViewById(R.id.textViewComboValue);
+
+ if(textViewComboValue != null)
+ textViewComboValue.setTypeface(EnhancedTextView.getTypeFace(context, "tahoma.ttf"));
+ if(titleCombo != null) {
+ titleCombo.setTypeface(EnhancedTextView.getTypeFace(context, "tahoma.ttf"));
+ }
+ }
+
+
+ public void setComboBoxTitle(String title) {
+ titleCombo.setText(title);
+ }
+
+ public void setTitleFontFace(Typeface typeface) {
+ titleCombo.setTypeface(typeface);
+ }
+
+ public void setTitleFontSize(int size) {
+ titleCombo.setTextSize(size);
+ }
+
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ layoutCombo.setEnabled(enabled);
+ }
+
+ public void setValues(ArrayList values) {
+ if(values == null)
+ return;
+
+ // detect the type of contacts used in the generic
+ if(values.size() > 0) {
+ if(values.get(0) instanceof Contact)
+ type = ComboType.CONTACT;
+ else if (values.get(0) instanceof Zone)
+ type = ComboType.ZONE;
+ else if (values.get(0) instanceof String)
+ type = ComboType.STRING;
+ }
+
+
+ this.listValues = values;
+
+ // if size of new array is 0
+ if (values.size() == 0 && type == ComboType.CONTACT){
+ textViewComboValue.setText("N/A");
+ imageViewCombo.setImageResource(R.drawable.call_private_blue_small);
+
+ // add manual dial values and all call
+ contacts.add(new Contact(16774215, context.getString(R.string.AllCall), AppParams.MotoAllCall, 0, 0));
+ contacts.add(new Contact(0, context.getString(R.string.dialGroup), AppParams.MotoManualDial, 0, 0));
+ contacts.add(new Contact(0, context.getString(R.string.dialPrivate), AppParams.MotoManualDial, 0, 0));
+ }
+ else if (values.size() == 0 && type == ComboType.ZONE){
+ // do nothing
+ }
+ // check if current selected value still exists in the array list
+ else if (type == ComboType.CONTACT) {
+ try {
+ boolean hasManual = false, hasAllCall = false;
+ contacts = new ArrayList();
+
+ Iterator iterator = values.iterator();
+ while(iterator.hasNext()){
+ T c = iterator.next();
+ Contact contact = (Contact) c;
+ contacts.add(contact);
+
+ if(contact.contactType == AppParams.MotoAllCall)
+ hasAllCall = true;
+
+ if(contact.name.equals(context.getString(R.string.manualDial)))
+ hasManual = true;
+ }
+
+ // add manual dial if not present
+ if(!hasManual) {
+ contacts.add(new Contact(0, context.getString(R.string.dialGroup), AppParams.MotoManualDial, 0, 0));
+ contacts.add(new Contact(0, context.getString(R.string.dialPrivate), AppParams.MotoManualDial, 0, 0));
+ }
+
+ // add all call if not present
+ if(!hasAllCall)
+ contacts.add(new Contact(16774215, context.getString(R.string.AllCall), AppParams.MotoAllCall, 0, 0));
+
+ // sort contacts list based on it's type
+ sortContacts(SortMode.CALL_TYPE, true);
+
+ boolean found = false;
+
+ if(selectedContact!= null){
+ iterator = values.iterator();
+ while(iterator.hasNext()){
+ T c = iterator.next();
+ if(((Contact) c).equals(selectedContact)) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if(found) {
+ textViewComboValue.setText(selectedContact.name);
+ imageViewCombo.setImageResource(getImageResourceFromGenericType(selectedContact));
+ _fireOnContactItemClick(selectedContact);
+ }
+ else {
+ selectedContact = contacts.get(0);
+ textViewComboValue.setText(contacts.get(0).name);
+ imageViewCombo.setImageResource(getImageResourceFromGenericType(contacts.get(0)));
+ _fireOnContactItemClick(contacts.get(0));
+ }
+ }
+ catch(ConcurrentModificationException ex) {
+ SM.Debug("TitledComboBox", "Concurrent Modification Exception for Contact");
+ }
+ }
+ else if (type == ComboType.ZONE) {
+ try {
+ zoneChannels = new ArrayList();
+
+ Iterator iterator = values.iterator();
+ while(iterator.hasNext()){
+ T c = iterator.next();
+ Zone z = (Zone) c;
+ // add section header to the list
+ zoneChannels.add(new ZoneChannel(z));
+
+ // add channelZone Cartesian product
+ for(Channel ch : z.channelList)
+ zoneChannels.add(new ZoneChannel(z, ch));
+ }
+
+ boolean found = false;
+
+ if(selectedZoneChannel!= null) {
+ iterator = values.iterator();
+ while(iterator.hasNext()){
+ T c = iterator.next();
+ Zone z = (Zone) c;
+ if(z.equals(selectedZoneChannel.getZone()) && z.channelList.contains(selectedZoneChannel.getChannel())) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if(found) {
+ textViewComboValue.setText(selectedZoneChannel.getChannel().chName);
+ imageViewCombo.setImageResource(getImageResourceFromGenericType(selectedContact));
+ }
+ else {
+ for(ZoneChannel zc: zoneChannels)
+ {
+ if(!zc.isSection()) {
+ selectedZoneChannel = new ZoneChannel(zc.getZone(), zc.getChannel());
+ textViewComboValue.setText(zc.getChannel().chName);
+ imageViewCombo.setImageResource(R.drawable.channel_small);
+ break;
+ }
+ }
+
+ }
+ }
+ catch(ConcurrentModificationException ex) {
+ SM.Debug("TitledComboBox", "Concurrent Modification Exception for Zone");
+ }
+ }
+
+ }
+
+ private void sortContacts(SortMode sortCategory, final boolean isAsc){
+ final int orderCompensation = (isAsc ? 1 : -1);
+
+ if(sortCategory == SortMode.CALL_TYPE) {
+ Collections.sort(contacts, new Comparator() {
+ @Override
+ public int compare(Contact contact1, Contact contact2)
+ {
+ if( contact1.contactType > contact2.contactType)
+ return orderCompensation * 1;
+ else if( contact1.contactType == contact2.contactType) {
+ return orderCompensation * (contact1.id < contact2.id ? -1 : 1);
+ //return orderCompensation * contact1.name.compareTo(contact2.name);
+ }
+ else
+ return orderCompensation * -1;
+ }
+ });
+ }
+ else if(sortCategory == SortMode.NAME)
+ Collections.sort(contacts, new Comparator() {
+ @Override
+ public int compare(Contact contact1, Contact contact2)
+ {
+ return orderCompensation * contact1.name.compareTo(contact2.name);
+ }
+ });
+ }
+
+
+ /**
+ * Return a Image Resource (int value) depending on the value passed. The value can be a Contact,
+ * a Zone, or a String.
+ * Contact = the call type image: private, group, all, manual
+ * Zone = to be reedited
+ * @param value The contact for which I will get the image
+ * @return an integer which will correspond to a resource image
+ */
+ private int getImageResourceFromGenericType(Object value)
+ {
+ if(value instanceof Contact) {
+ Contact ctc = (Contact) value;
+ switch(ctc.contactType) {
+ case AppParams.MotoManualDial: return R.drawable.dial;
+ case AppParams.MotoAllCall: return R.drawable.call_all_green_small;
+ case AppParams.MotoGroup: return R.drawable.call_group_green_small;
+ case AppParams.MotoPrivate: return R.drawable.call_private_green_small;
+ }
+ }
+ else if (value instanceof String)
+ return R.drawable.call_private_blue_small;
+ else if (value instanceof Zone)
+ return R.drawable.zone_small;
+
+ return R.drawable.call_private_blue_small;
+ }
+
+
+ /**
+ * Convert an Generic ArrayList into a String one. This is used to populate a simple ArrayAdapter
+ * with the names of contacts or zones
+ * @param list The generic list which will be converted
+ * @return a corresponding list of String objects (usually the names of the objects)
+ */
+ private ArrayList getStringListFromArray(ArrayList list) {
+ ArrayList result = new ArrayList();
+ for(T ctc: list)
+ switch (type) {
+ case CONTACT: result.add(((Contact) ctc).name); break;
+ case ZONE: result.add(((Zone) ctc).ZoneName); break;
+ case STRING: result.add((String) ctc); break;
+ }
+
+ return result;
+ }
+
+ /**
+ * Display a manual dial which will wait for the user to insert a number
+ */
+ private void showManualDial(final boolean isPrivate)
+ {
+
+ /*
+ // selected Manual Dial
+ manualDialDialog = new DialDialog(context);
+ manualDialDialog.dialog.setTitle(context.getString(R.string.manualDial));
+ manualDialDialog.dialog.setCancelable(true);
+ manualDialDialog.dialog.setCanceledOnTouchOutside(false);
+ manualDialDialog.dialog.setOnCancelListener(new OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ //SM.Debug("CLOSED DIALOG", "AM INCHIS " + dialDialog.getNumber());
+ if(manualDialDialog.getNumber()!=0)
+ {
+ int manualDialValue = manualDialDialog.getNumber();
+ AppParams.crtContact = new Contact(manualDialValue, textViewCallType.getText().toString(), Contact.GROUP, 0, 0);
+ }
+ }
+ });
+
+ manualDialDialog.dialog.show();*/
+
+ final EditText input = new EditText(context);
+ input.setSelectAllOnFocus(true);
+ input.setText("");
+ input.setInputType(InputType.TYPE_CLASS_NUMBER);
+
+ // set max number of values
+ InputFilter[] filterArray = new InputFilter[1];
+ filterArray[0] = new InputFilter.LengthFilter(8);
+ input.setFilters(filterArray);
+
+ new AlertDialog.Builder(context)
+ .setTitle(context.getString(isPrivate ? R.string.dialPrivate : R.string.dialGroup))
+ .setView(input)
+
+ .setPositiveButton(context.getString(R.string.ok), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ Editable value = input.getText();
+
+ long val = Long.parseLong(value.toString());
+ if(val > 16777215)
+ Toast.makeText(context, context.getString(R.string.radioIDValues), Toast.LENGTH_SHORT).show();
+
+ Contact manualContact = null;
+ // check if contact already exists
+ if( (manualContact = checkContactWithIDExists(val)) == null)
+ {
+ manualContact = new Contact(val, val+"", isPrivate ? AppParams.MotoPrivate : AppParams.MotoGroup, 0, 0);
+ contacts.add(0, manualContact);
+ }
+
+ textViewComboValue.setText(manualContact.name);
+ selectedContact = manualContact;
+ imageViewCombo.setImageResource(getImageResourceFromGenericType(selectedContact));
+ _fireOnContactItemClick(selectedContact);
+
+ }
+ }).setNegativeButton(context.getString(R.string.cancel), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ // close dialog
+ dialog.dismiss();
+
+ }
+ }).show();
+ }
+
+
+ private Contact checkContactWithIDExists(long val) {
+ for(Contact ctc: contacts)
+ if(ctc.id == val)
+ return ctc;
+
+ return null;
+ }
+
+ private OnClickListener layoutComboClickListener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+
+ // close previous dialog if it was showind
+ if(alert != null && alert.isShowing())
+ alert.dismiss();
+
+
+ final ArrayList stringList = getStringListFromArray(listValues);
+
+
+ //ImagedSpinnerAdapter adapterImaged = new ImagedSpinnerAdapter(context, android.R.layout.simple_list_item_1, AppParams.listContacts);
+ ArrayAdapter adapter = new ArrayAdapter(context, android.R.layout.simple_list_item_1, stringList);
+ ContactsComboBoxAdapter adapterImaged = null;
+ ZoneChannelComboBoxAdapter adapterZone = null;
+
+ if(type == ComboType.CONTACT) {
+ adapterImaged = new ContactsComboBoxAdapter(context, R.layout.spinner, contacts);
+ }
+ else if(type == ComboType.ZONE) {
+ adapterZone = new ZoneChannelComboBoxAdapter(context, R.layout.spinner, zoneChannels);
+ }
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(type == ComboType.CONTACT ? context.getString(R.string.selectContact) : context.getString(R.string.selChannel));
+ builder.setAdapter(type == ComboType.CONTACT ? adapterImaged : (type == ComboType.ZONE ? adapterZone : adapter) , new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // update UI and fire event
+ if(type == ComboType.CONTACT && contacts.size() > which) {
+ if(contacts.get(which).contactType == AppParams.MotoManualDial ||
+ (contacts.get(which).name == context.getString(R.string.dialGroup) ||
+ contacts.get(which).name == context.getString(R.string.dialPrivate))) {
+ //show manual dialog
+ showManualDial(contacts.get(which).name == context.getString(R.string.dialGroup) ? false : true);
+ }
+ else {
+
+ textViewComboValue.setText(contacts.get(which).name);
+ selectedContact = contacts.get(which);
+ imageViewCombo.setImageResource(getImageResourceFromGenericType(selectedContact));
+ _fireOnContactItemClick(contacts.get(which));
+ }
+ }
+ else if (type == ComboType.ZONE && zoneChannels.size() > which) {
+ // if a header was selected i will do nothing
+ if(zoneChannels.get(which).getChannel() == null)
+ return;
+ /*
+ textViewComboValue.setText(zoneChannels.get(which).getChannel().chName);
+ selectedZoneChannel = zoneChannels.get(which);
+ imageViewCombo.setImageResource(R.drawable.channel_small);*/
+ _fireOnZoneItemClick(zoneChannels.get(which));
+ }
+
+ }
+ });
+
+ alert = builder.create();
+ alert.show();
+ }
+ };
+
+
+ /**
+ * Set the type of elements that will be used with this ComboBox and the elements
+ * which needs to be added to ComboBox if no element if added
+ * @param type The type of ComboBox, it can be Zone, Contact
+ */
+ public void setType(ComboType type) {
+ this.type = type;
+ }
+
+ /**
+ * Get the selected Channel
+ * @return the channel object or null if no channel is selected
+ */
+ public Channel getSelectedChannel() {
+ if(selectedZoneChannel == null)
+ return null;
+
+ return selectedZoneChannel.getChannel();
+ }
+
+ /**
+ * Get the selected Zone, it contains the list of channels
+ * @return the zone object or null if no zone is selected
+ */
+ public Zone getSelectedZone() {
+ if(selectedZoneChannel == null)
+ return null;
+
+ return selectedZoneChannel.getZone();
+ }
+
+
+ /**
+ * Update the selected zone and channel as a result of a change directly on the radio stations
+ * @param zone The selected zone onto the station
+ * @param channel The selected channel onto the station
+ */
+ public void setSelectedZoneAndChannel(Zone zone, Channel channel) {
+ selectedZoneChannel = new ZoneChannel(zone, channel);
+
+ textViewComboValue.setText(channel.chName);
+ imageViewCombo.setImageResource(R.drawable.channel_small);
+ }
+
+
+ /**
+ * Get the selected contact, this can be a manualdial generated one
+ * @return The contact which is selected, or null if no contact is selected
+ */
+ public Contact getSelectedContact() {
+ return selectedContact;
+ }
+
+
+ /**
+ * Update the selected contact as a result of a call made from a portable device
+ * @param contact The contact which needs to be selected
+ */
+ public void setSelectedContact(Contact contact) {
+ selectedContact = contact;
+
+ textViewComboValue.setText(selectedContact.name);
+ imageViewCombo.setImageResource(getImageResourceFromGenericType(selectedContact));
+ }
+
+ /**
+ * Update the selected contact as a result of a call made from a portable device
+ * @param id The contact id
+ * @param contactType The contact type, which can be private, group, allcall
+ */
+ public void setSelectedContact(long id, int contactType) {
+ boolean wasFound = false;
+
+ for(Contact ctc: contacts) {
+ // if contact type is all call or I have found the contact that I was searching for
+ if((ctc.contactType == contactType && contactType == AppParams.MotoAllCall ) ||
+ (ctc.id == id && ctc.contactType == contactType)) {
+ selectedContact = ctc;
+
+ textViewComboValue.setText(selectedContact.name);
+ imageViewCombo.setImageResource(getImageResourceFromGenericType(selectedContact));
+ wasFound = true;
+ break;
+ }
+ }
+
+ // create contact if it wasn't found and update the UI
+ if(!wasFound) {
+ Contact manualContact = new Contact(id, id+"", contactType, (int)id, (int) id);
+ contacts.add(0, manualContact);
+
+ textViewComboValue.setText(manualContact.name);
+ selectedContact = manualContact;
+ imageViewCombo.setImageResource(getImageResourceFromGenericType(selectedContact));
+ }
+ }
+
+ /**
+ * Hide all dialogs which are displayed. Usefull in case a call is received and
+ * the dialog for contacts/zones is displayed
+ */
+ public void hideVisibleDialogs() {
+ if(alert == null)
+ return;
+
+ if(alert.isShowing())
+ alert.dismiss();
+ }
+
+
+ /* SELECT ITEM EVENTS + LISTENERS */
+ private ArrayList _listeners = new ArrayList();
+
+ public synchronized void setOnComboItemClickListener( OnComboItemClickListener l ) {
+ _listeners.add( l );
+ }
+
+ /** this event will be fired when a contact will be selected in the spinner */
+ private synchronized void _fireOnContactItemClick(Contact selectedItem) {
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (OnComboItemClickListener) listeners.next() ).setOnContactItemClickListener(selectedItem);
+ }
+ }
+
+ /** this event will be fired when a zone will be selected in the spinner */
+ private synchronized void _fireOnZoneItemClick(ZoneChannel selectedItem) {
+ Iterator listeners = _listeners.iterator();
+ while( listeners.hasNext() ) {
+ ( (OnComboItemClickListener) listeners.next() ).setOnZoneItemClickListener(selectedItem);
+ }
+ }
+
+ public interface OnComboItemClickListener {
+ public void setOnContactItemClickListener(Contact selectedItem);
+ public void setOnZoneItemClickListener(ZoneChannel selectedItem);
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/Account.java b/libSafeMobile/src/main/java/com/safenet/lib/Account.java
new file mode 100644
index 0000000..72148b8
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/Account.java
@@ -0,0 +1,27 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class Account {
+ public long id;
+ public long version;
+ public String companyName;
+ public Date dateCreated;
+ public int emailGatewayId;
+ public int featuresId;
+ public Features features;
+ public boolean isCarrier;
+ public boolean isDeactivated;
+ public boolean isDemo;
+ public Date lastUpdated;
+
+
+ public Account() { }
+
+ public String toString()
+ {
+ return "id: " + id + " | companyName: " + companyName+ " | dateCreated: " + dateCreated + " | emailGatewayId: " + emailGatewayId + " | featuresId: " + featuresId
+ + " | isCarrier: " + isCarrier + " | isDeactivated: " + isDeactivated + " | isDemo: " + isDemo + " | lastUpdated: " + lastUpdated;
+ }
+
+}
\ No newline at end of file
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/AccountGateway.java b/libSafeMobile/src/main/java/com/safenet/lib/AccountGateway.java
new file mode 100644
index 0000000..348f7f4
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/AccountGateway.java
@@ -0,0 +1,17 @@
+package com.safenet.lib;
+
+public class AccountGateway {
+
+
+ public int accountGatewaysId;
+ public int gatewayId;
+
+ public AccountGateway(){
+
+ }
+ public String toString()
+ {
+ return "accountGatewaysId" + accountGatewaysId + " | gatewayId: " + gatewayId;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/Activity.java b/libSafeMobile/src/main/java/com/safenet/lib/Activity.java
new file mode 100644
index 0000000..37b227d
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/Activity.java
@@ -0,0 +1,24 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class Activity {
+
+
+ public long id;
+ public long version;
+ public String action;
+ public Date dateCreated;
+ public int userId;
+
+ public Activity(){
+
+ }
+
+
+ public String toString()
+ {
+ return "id" + id + "action" + action + "dateCreated" + dateCreated + "userId" + userId;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/Address.java b/libSafeMobile/src/main/java/com/safenet/lib/Address.java
new file mode 100644
index 0000000..93d430c
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/Address.java
@@ -0,0 +1,21 @@
+package com.safenet.lib;
+
+public class Address {
+ public long id;
+ public long version;
+ public Gateway gateway;
+ public double latitude;
+ public double longitude;
+ public String address;
+ public String addressHash;
+
+ public Address(){
+
+ }
+
+ public String toString()
+ {
+ return "id: " + id + " | lat: " + latitude + " | long: " + longitude + " | address: " + address + " | gtwCode: " + gateway.code;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/AlertDefinition.java b/libSafeMobile/src/main/java/com/safenet/lib/AlertDefinition.java
new file mode 100644
index 0000000..0c26750
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/AlertDefinition.java
@@ -0,0 +1,50 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class AlertDefinition {
+
+ public long id;
+ public long version;
+ public int accountId;
+ public int createdById;
+ public Date dateCreated;
+ public Date lastUpdated;
+ public int unitId;
+ public int userId;
+ public String mClass;
+ public boolean movesIn;
+ public boolean movesOut;
+ public int landmarkId;
+ public int rangeInMilesLandmark;
+ public int geofenceId;
+ public String digitalAlertDescription;
+ public int digitalValues;
+ public int maxSpeedInMiles;
+
+
+ public AlertDefinition(){
+
+ }
+
+
+ public String toString()
+ {
+ return "id" + id
+ + "accountId" + accountId
+ + "createdById" + createdById
+ + "dateCreated" + dateCreated
+ + "lastUpdated" + lastUpdated
+ + "unitId" + unitId
+ + "userId" + userId
+ + "mClass" + mClass
+ + "movesIn" + movesIn
+ + "movesOut" + movesOut
+ + "landmarkId" + landmarkId
+ + "rangeInMilesLandmark" + rangeInMilesLandmark
+ + "geofenceId" + geofenceId
+ + "digitalAlertDescription" + digitalAlertDescription
+ + "digitalValues" + digitalValues
+ + "maxSpeedInMiles" + maxSpeedInMiles;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/AlertDefinitionAlertDefinitionPeriod.java b/libSafeMobile/src/main/java/com/safenet/lib/AlertDefinitionAlertDefinitionPeriod.java
new file mode 100644
index 0000000..7ef7667
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/AlertDefinitionAlertDefinitionPeriod.java
@@ -0,0 +1,24 @@
+package com.safenet.lib;
+
+public class AlertDefinitionAlertDefinitionPeriod {
+
+
+ public int alertDefinitionActivePeriodsId;
+ public int alertDefinitionPeriodId;
+
+
+
+
+
+ public AlertDefinitionAlertDefinitionPeriod(){
+
+ }
+
+
+ public String toString()
+ {
+ return "alertDefinitionActivePeriodsId" + alertDefinitionActivePeriodsId
+ + "alertDefinitionPeriodId" + alertDefinitionPeriodId;
+ }
+
+}
\ No newline at end of file
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/AlertDefinitionContact.java b/libSafeMobile/src/main/java/com/safenet/lib/AlertDefinitionContact.java
new file mode 100644
index 0000000..59511ee
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/AlertDefinitionContact.java
@@ -0,0 +1,18 @@
+package com.safenet.lib;
+
+public class AlertDefinitionContact {
+
+ public int alertDefinitionRecipientsId;
+ public int ContactId;
+
+ public AlertDefinitionContact(){
+
+ }
+
+
+ public String toString()
+ {
+ return "alertDefinitionRecipientsId" + alertDefinitionRecipientsId
+ + "ContactId" + ContactId;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/AlertDefinitionPeriod.java b/libSafeMobile/src/main/java/com/safenet/lib/AlertDefinitionPeriod.java
new file mode 100644
index 0000000..af16c5a
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/AlertDefinitionPeriod.java
@@ -0,0 +1,25 @@
+package com.safenet.lib;
+
+public class AlertDefinitionPeriod {
+
+ public long id;
+ public long version;
+ public boolean allDay;
+ public int timeEnd;
+ public int timeStart;
+ public String weekday;
+
+ public AlertDefinitionPeriod(){
+
+ }
+
+
+ public String toString()
+ {
+ return "id" + id
+ + "allDay" + allDay
+ + "timeEnd" + timeEnd
+ + "timeStart" + timeStart
+ + "weekday" + weekday ;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/AlertEvent.java b/libSafeMobile/src/main/java/com/safenet/lib/AlertEvent.java
new file mode 100644
index 0000000..86379c2
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/AlertEvent.java
@@ -0,0 +1,36 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class AlertEvent {
+
+
+ public long id = -1;
+ public long version = 1;
+ public int alertTypeId = 88888;
+ public Date dateCreated = new Date(10000);
+ public boolean isAcknowledged = true;
+ public boolean isDisplayed = true;
+ public boolean isSent = true;
+ public int unitId;
+ public String unitName;
+
+ public Date position_message_message_time;
+ public int position_message_unit_id;
+ public String time;
+
+ public AlertEvent(){
+
+ }
+
+ public String toString()
+ {
+ return "id = " + id
+ + " | alertTypeId = " + alertTypeId
+ + " | dateCreated = " + dateCreated
+ + " | isAcknowledged = " + isAcknowledged
+ + " | isDisplayed = " + isDisplayed
+ + " | isSent = " + isSent
+ + " | unitId = " + unitId ;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/ArsMessage.java b/libSafeMobile/src/main/java/com/safenet/lib/ArsMessage.java
new file mode 100644
index 0000000..3c2489e
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/ArsMessage.java
@@ -0,0 +1,23 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class ArsMessage {
+
+
+ public Date message_time;
+ public long unitId;
+ public boolean isOn;
+ public String suid;
+
+
+
+ public ArsMessage(){
+
+ }
+
+ public String toString()
+ {
+ return "message_time: " + message_time + " | unitId: " + unitId + " | is_on: " + isOn ;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/CompanyAccount.java b/libSafeMobile/src/main/java/com/safenet/lib/CompanyAccount.java
new file mode 100644
index 0000000..b2f4365
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/CompanyAccount.java
@@ -0,0 +1,32 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class CompanyAccount {
+
+ public long id;
+ public long version;
+ public int accountId;
+ public Date dateCreated;
+ public int featuresId;
+ public boolean isDeactivated;
+ public Date lastUpdated;
+ public String name;
+
+
+ public CompanyAccount(){
+
+ }
+
+
+ public String toString()
+ {
+ return "id" + id
+ + "accountId" + accountId
+ + "dateCreated" + dateCreated
+ + "featuresId" + featuresId
+ + "isDeactivated" + isDeactivated
+ + "lastUpdated" + lastUpdated
+ + "name" + name ;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/Contact.java b/libSafeMobile/src/main/java/com/safenet/lib/Contact.java
new file mode 100644
index 0000000..a4032c2
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/Contact.java
@@ -0,0 +1,26 @@
+package com.safenet.lib;
+
+import java.sql.Date;
+
+public class Contact {
+
+ public long id;
+ public long version;
+ public Date dateCreated;
+ public int accountId;
+ public String firstName;
+ public String lastName;
+ public String email;
+ public String phoneNumber;
+
+ public Contact(){
+
+ }
+
+ public String toString()
+ {
+ return "# CONTACT # id: " + id + " | firstName: " + firstName + " | lastName: " + lastName + " | email: " + (email == null ? "null" : email) +
+ " | phoneNumber: " + (phoneNumber == null ? "null" : phoneNumber);
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/EmailGateway.java b/libSafeMobile/src/main/java/com/safenet/lib/EmailGateway.java
new file mode 100644
index 0000000..9a7bbb0
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/EmailGateway.java
@@ -0,0 +1,27 @@
+package com.safenet.lib;
+
+public class EmailGateway {
+
+
+
+ public long id;
+ public long version;
+ public boolean cannotConnect;
+ public String emailAddress;
+ public int pingIntervalSeconds;
+
+
+
+ public EmailGateway(){
+
+ }
+
+
+ public String toString()
+ {
+ return "id" + id
+ + "cannotConnect" + cannotConnect
+ + "emailAddress" + emailAddress
+ + "pingIntervalSeconds" + pingIntervalSeconds;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/Features.java b/libSafeMobile/src/main/java/com/safenet/lib/Features.java
new file mode 100644
index 0000000..8f35520
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/Features.java
@@ -0,0 +1,26 @@
+package com.safenet.lib;
+
+public class Features {
+ public long id;
+ public long version;
+
+ public boolean geofence = true;
+ public boolean landmarks = true;
+ public boolean textMessaging = true;
+ public boolean reports = true;
+ public boolean enhancedReports = false;
+ public boolean emailGateway = false;
+ public boolean live = true;
+ public boolean history = true;
+ public boolean alerts = false;
+
+ public Features(){
+
+ }
+
+ public String toString()
+ {
+ return "id: " + id + " | alerts: " + alerts + " | email: " + emailGateway + " | enRep: " + enhancedReports + " | reports: " + reports +
+ " | geofence: " + geofence + " | landmark: " + landmarks + " | history: " + history + " | live: " + live + " | text: " + textMessaging;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/Gateway.java b/libSafeMobile/src/main/java/com/safenet/lib/Gateway.java
new file mode 100644
index 0000000..358c752
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/Gateway.java
@@ -0,0 +1,20 @@
+package com.safenet.lib;
+
+public class Gateway {
+ public long id;
+ public long version;
+ public long code;
+ public long type_id;
+ public long account_id;
+ public long contr_id;
+ public Gateway(){
+
+ }
+
+ public String toString()
+ {
+ return "id: " + id + " | code: " + code + " | account_id: " + account_id +
+ " | contr_id: " + contr_id + " | type_id: " + type_id + " | version: " + version;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/GatewayStatus.java b/libSafeMobile/src/main/java/com/safenet/lib/GatewayStatus.java
new file mode 100644
index 0000000..e78a65f
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/GatewayStatus.java
@@ -0,0 +1,28 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class GatewayStatus {
+
+
+ public long id;
+ public long version;
+ public Date dateCreated;
+ public int gatewayId;
+ public boolean isOn;
+ public String radioip;
+
+ public GatewayStatus(){
+
+ }
+
+
+ public String toString()
+ {
+ return "id" + id
+ + "dateCreated" + dateCreated
+ + "gatewayId" + gatewayId
+ + "isOn" + isOn
+ + "radioip" + radioip;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/Geofence.java b/libSafeMobile/src/main/java/com/safenet/lib/Geofence.java
new file mode 100644
index 0000000..2b9d37c
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/Geofence.java
@@ -0,0 +1,27 @@
+package com.safenet.lib;
+
+import java.util.Date;
+import java.util.Vector;
+
+public class Geofence {
+ public long id = -1;
+ public long version = 1;
+ public Date dateCreated;
+ public String edge_color;
+ public String fill_color;
+ public Date lastUpdated;
+ public String name;
+ public String opacity;
+ public int type;
+ public Vector points = new Vector();
+ public Long userId;
+
+ public Geofence(){
+
+ }
+
+ public String toString()
+ {
+ return "# Geofence # name: " + name + " | points: " + points.size() + " | user_id: " + userId;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/GeofencePointsId.java b/libSafeMobile/src/main/java/com/safenet/lib/GeofencePointsId.java
new file mode 100644
index 0000000..c03fda3
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/GeofencePointsId.java
@@ -0,0 +1,21 @@
+package com.safenet.lib;
+
+public class GeofencePointsId {
+
+ public int geofencePointsId;
+ public int latLngPointId;
+ public int pointsIdx;
+
+
+ public GeofencePointsId(){
+
+ }
+
+
+ public String toString()
+ {
+ return "geofencePointsId" + geofencePointsId
+ + "latLngPointId" + latLngPointId
+ + "pointsIdx" + pointsIdx;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/HistoryIntervalData.java b/libSafeMobile/src/main/java/com/safenet/lib/HistoryIntervalData.java
new file mode 100644
index 0000000..de6e76a
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/HistoryIntervalData.java
@@ -0,0 +1,25 @@
+package com.safenet.lib;
+
+import java.util.Date;
+import java.util.Vector;
+
+public class HistoryIntervalData {
+
+ public Unit unit;
+ public Date from;
+ public Date to;
+ public String intervalName;
+ public Vector positionsGMT;
+ public long maxPositions=-1;
+ public boolean filtered=true;
+
+
+ public HistoryIntervalData(){
+
+ }
+
+ public String toString()
+ {
+ return "unit: " + unit + " | from: " + from + " | to: " + to + " | intervalName: " + intervalName + " | maxPositions: " + maxPositions;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/Landmark.java b/libSafeMobile/src/main/java/com/safenet/lib/Landmark.java
new file mode 100644
index 0000000..04a3983
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/Landmark.java
@@ -0,0 +1,26 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class Landmark {
+ public long id = -1;
+ public String name;
+ public LatLngPoint point;
+ public int radius;
+ public int color; //background color
+ public String icon="images/02/16/21.png";
+ public Date dateCreated;
+ public Date lastUpdated;
+ public Long userId;
+ public String schema;
+
+ public Landmark(){
+
+ }
+
+ public String toString()
+ {
+ return "# Landmark #\n name: " + name + " | radius: " + radius + " | " + point.toString();
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/LastPosition.java b/libSafeMobile/src/main/java/com/safenet/lib/LastPosition.java
new file mode 100644
index 0000000..7b53db8
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/LastPosition.java
@@ -0,0 +1,35 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class LastPosition {
+
+ // H7 LastPosition atributes
+ public long id;
+ public Date positionTime;
+ public double latitude;
+ public double longitude;
+ public int speed;
+ public boolean digitalIn;
+ public boolean digitalOut;
+ public Date arsTime;
+ public boolean isOn;
+ public long unit_id;
+ public String unitName ="";
+ public Address address = null;
+
+ // H7 Position && PositionMessage
+
+ public LastPosition(){
+
+ }
+
+ public String toString()
+ {
+ return "# POSITION #\n id: " + unit_id +
+ " | address: " + (address == null? "null" : address.address) +
+ " | lat: " + latitude + " | long: " + longitude +
+ " | speed: " + speed;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/LatLngPoint.java b/libSafeMobile/src/main/java/com/safenet/lib/LatLngPoint.java
new file mode 100644
index 0000000..c6686dd
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/LatLngPoint.java
@@ -0,0 +1,31 @@
+package com.safenet.lib;
+
+public class LatLngPoint {
+ public long id;
+ public double latitude;
+ public double longitude;
+ public String address = "";
+
+ public LatLngPoint(){
+
+ }
+
+ public LatLngPoint(long id, double lat, double lng)
+ {
+ this.id = id;
+ latitude = lat;
+ longitude = lng;
+ }
+
+
+ public LatLngPoint(double lat, double lng, String address){
+ latitude = lat;
+ longitude = lng;
+ this.address = address;
+ }
+
+ public String toString()
+ {
+ return "lat: " + latitude + " | long: " + longitude + " | address: " + address;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/LicensePack.java b/libSafeMobile/src/main/java/com/safenet/lib/LicensePack.java
new file mode 100644
index 0000000..c5f5219
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/LicensePack.java
@@ -0,0 +1,34 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class LicensePack {
+
+
+ public long id;
+ public long version;
+ public Date PODate;
+ public String PONumber;
+ public int POValue;
+ public int accountId;
+ public Date dateCreated;
+ public int numberOfRadioLicences;
+ public int numberOfUsuers;
+
+ public LicensePack(){
+
+ }
+
+
+ public String toString()
+ {
+ return "id" + id
+ + "PODate" + PODate
+ + "PONumber" + PONumber
+ + "POValue" + POValue
+ + "accountId" + accountId
+ + "dateCreated" + dateCreated
+ + "numberOfRadioLicences" + numberOfRadioLicences
+ + "numberOfUsuers" + numberOfUsuers;
+ }
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/Poll.java b/libSafeMobile/src/main/java/com/safenet/lib/Poll.java
new file mode 100644
index 0000000..7f51ce0
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/Poll.java
@@ -0,0 +1,34 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class Poll {
+
+ public long id = -1;
+ public long version;
+ public Date dateCreated;
+ public boolean isRead;
+ public boolean isSent;
+ public Date positionMessage_message_time;
+ public int positionMessageUnitId;
+ public PositionMessage positionMessage;
+ public boolean responded;
+ public long unitId;
+ public String unitName;
+
+ public Poll(){
+
+ }
+
+ public String toString()
+ {
+ return "id: " + id
+ + " | dateCreated: " + dateCreated
+ + " | isRead: " + isRead
+ + " | isSent: " + isSent
+ + " | responded: " + responded
+ + " | unitId: " + unitId
+ + " | unitName: "+ unitName;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/PositionMessage.java b/libSafeMobile/src/main/java/com/safenet/lib/PositionMessage.java
new file mode 100644
index 0000000..585dfc1
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/PositionMessage.java
@@ -0,0 +1,26 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class PositionMessage {
+
+ public Date messageTime;
+ public long unitId;
+ public String addressHash;
+ public boolean digitalIn;
+ public boolean digitalOut;
+ public double latitude;
+ public double longitude;
+ public int speed;
+ public int type = 33;
+
+ public PositionMessage(){
+
+ }
+
+ public String toString()
+ {
+ return "# PositionMessage #\n unitId: " + unitId + " | lat: " + latitude + " | long: " + longitude + " | speed: " + speed;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/Settings.java b/libSafeMobile/src/main/java/com/safenet/lib/Settings.java
new file mode 100644
index 0000000..61e9d46
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/Settings.java
@@ -0,0 +1,24 @@
+package com.safenet.lib;
+
+public class Settings {
+ public long id;
+ public long version;
+ public String language = "";
+ public String lastTab = "";
+ public boolean mph = true;
+ public String openedTabs = "";
+ public boolean militaryTime;
+ public int refreshIntervalSec;
+ public int historyLimit;
+ public int reportLimit;
+
+ public Settings(){
+
+ }
+
+ public String toString()
+ {
+ return "# SETTINGS # id: " + id + " | language: " + language + " | lastTab: " + lastTab + " | openedTabs: " + openedTabs + " | mph: " + mph;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/TextMessage.java b/libSafeMobile/src/main/java/com/safenet/lib/TextMessage.java
new file mode 100644
index 0000000..a29d116
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/TextMessage.java
@@ -0,0 +1,78 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class TextMessage {
+
+
+ public long id;
+ public long version;
+ public Date dateCreated;
+ public boolean isRead, isSent;
+ public String messageContent;
+ public String messageType;
+ public Date timeSentOrReceived;
+ public long unitId;
+ public String subscriber;
+
+ public TextMessage(){
+
+ }
+
+ public String toString()
+ {
+ return "id: " + id
+ + " | dateCreated: " + dateCreated
+ + " | type: " + messageType
+ + " | isRead: " + isRead
+ + " | isSent: " + isSent
+ + " | messageContent: " + messageContent
+ + " | timeSentOrReceived: " + timeSentOrReceived
+ + " | unitId: " + unitId;
+ }
+
+ @SuppressWarnings("deprecation")
+ public static long getLocalOffsetMs(){
+ //System.out.println("timezoneoffset = "+new Date().getTimezoneOffset()*60*1000);
+ return -(new Date().getTimezoneOffset()*60 *1000);
+
+ }
+
+ public static Date getUTC(Date local){
+
+ long offsetMs = getLocalOffsetMs();
+ Date res = local;
+ if (local!=null)
+ res = new Date(local.getTime()-offsetMs);
+ return res;
+ }
+
+ public static Date getLocal(Date gmt){
+ //System.out.print(getLocalOffsetMs()+" ");
+ //System.out.print(gmt+" ");
+ //System.out.println(new Date(gmt.getTime()+getLocalOffsetMs()));
+ //TimeZone gmttz = TimeZone.createTimeZone(0);
+ //String formatted = DateTimeFormat.getFormat("yyyy-MM-dd HH:mm:ss").format(gmt, gmttz);
+ //System.out.println(formatted);
+ return new Date(gmt.getTime()+getLocalOffsetMs());
+ }
+
+ /*
+ public static String getUTC(Date local)
+ {
+ DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ TimeZone gmtTime = TimeZone.getTimeZone("UTC");
+ utcFormat.setTimeZone(gmtTime);
+
+ return utcFormat.format(local);
+ }
+
+ public static Date getLocal(Date utc)
+ {
+ long utcMiliseconds = utc.getTime();
+ GregorianCalendar cal = new GregorianCalendar();
+ cal.setTimeInMillis(utcMiliseconds);
+ return new Date(utcMiliseconds + cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET));
+ }
+ */
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/Unit.java b/libSafeMobile/src/main/java/com/safenet/lib/Unit.java
new file mode 100644
index 0000000..6670200
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/Unit.java
@@ -0,0 +1,29 @@
+package com.safenet.lib;
+
+import java.util.Date;
+
+public class Unit {
+ public long id;
+ public String name;
+ public Date dateCreated;
+ public Date lastUpdated;
+
+ public int reportingSeconds = 60;
+ public boolean isDeactivated; //if User wants to create another one with the same name then resurrect this one
+ public String emailAddress;
+ public UnitIcon icon;
+ public UnitGroup group = null;
+ public UnitType type;
+ public Gateway gateway; //if it is radio then will have a gateway, otherwise is null
+ public long imei;
+
+ public Unit(){
+
+ }
+
+ public String toString()
+ {
+ return "id: " + id + " | name: " + name + " | imei:" + imei + " | repSec:" + reportingSeconds;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/UnitGroup.java b/libSafeMobile/src/main/java/com/safenet/lib/UnitGroup.java
new file mode 100644
index 0000000..b4bb49a
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/UnitGroup.java
@@ -0,0 +1,18 @@
+package com.safenet.lib;
+
+public class UnitGroup {
+ public long id;
+ public String name;
+ public long version = 1;
+ public long account_id;
+
+ public UnitGroup(){
+
+ }
+
+ public String toString()
+ {
+ return "id: " + id + " | name: " + name + " | version: " + version;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/UnitIcon.java b/libSafeMobile/src/main/java/com/safenet/lib/UnitIcon.java
new file mode 100644
index 0000000..1e7d40c
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/UnitIcon.java
@@ -0,0 +1,18 @@
+package com.safenet.lib;
+
+public class UnitIcon {
+ public long id;
+ public String name;
+ public String path;
+ public long version;
+
+ public UnitIcon(){
+
+ }
+
+ public String toString()
+ {
+ return "id: " + id + " | name: " + name + " | path: "+ path + " | version: " + version;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/UnitType.java b/libSafeMobile/src/main/java/com/safenet/lib/UnitType.java
new file mode 100644
index 0000000..6e66474
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/UnitType.java
@@ -0,0 +1,18 @@
+package com.safenet.lib;
+
+public class UnitType {
+ public long id;
+ public String name;
+ public long version;
+ public String logo;
+
+ public UnitType(){
+
+ }
+
+ public String toString()
+ {
+ return "id: " + id + " | name: " + name + " | version: " + version;
+ }
+
+}
diff --git a/libSafeMobile/src/main/java/com/safenet/lib/User.java b/libSafeMobile/src/main/java/com/safenet/lib/User.java
new file mode 100644
index 0000000..1c4f19c
--- /dev/null
+++ b/libSafeMobile/src/main/java/com/safenet/lib/User.java
@@ -0,0 +1,37 @@
+package com.safenet.lib;
+
+import java.sql.Date;
+
+public class User {
+ public long id;
+ public long version;
+ public Date dateCreated = new Date(1000);
+ public Date lastUpdated= new Date(1000);;
+ public String login = "test";
+ public String password = "test";
+ public Contact self;
+ public int tzoOffset = 1;
+ public int historyLimit = 1000;
+ public int reportLimit = 1000;
+
+ public boolean isDeactivated = false;
+ public boolean isAdmin = false; //will login to Account admin
+ public boolean isGod = false; //will login as Overall admin
+
+ public Features features;
+ public Settings settings;
+
+ public long account_id = 1;
+ public long company_id = 1;
+ public String note;
+
+ public User(){
+
+ }
+
+ public String toString()
+ {
+ return "# USER #\n id: " + id + " | login: " + login + " | password: " + password + " | " + (self!=null?self.toString():"");
+ }
+
+}
diff --git a/libSafeMobile/src/main/res/anim/slide_in_bottom.xml b/libSafeMobile/src/main/res/anim/slide_in_bottom.xml
new file mode 100644
index 0000000..de4b8d6
--- /dev/null
+++ b/libSafeMobile/src/main/res/anim/slide_in_bottom.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/libSafeMobile/src/main/res/anim/slide_in_top.xml b/libSafeMobile/src/main/res/anim/slide_in_top.xml
new file mode 100644
index 0000000..791c3eb
--- /dev/null
+++ b/libSafeMobile/src/main/res/anim/slide_in_top.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/libSafeMobile/src/main/res/anim/slide_out_bottom.xml b/libSafeMobile/src/main/res/anim/slide_out_bottom.xml
new file mode 100644
index 0000000..4d1106a
--- /dev/null
+++ b/libSafeMobile/src/main/res/anim/slide_out_bottom.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/libSafeMobile/src/main/res/anim/slide_out_top.xml b/libSafeMobile/src/main/res/anim/slide_out_top.xml
new file mode 100644
index 0000000..204d643
--- /dev/null
+++ b/libSafeMobile/src/main/res/anim/slide_out_top.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/alert.png b/libSafeMobile/src/main/res/drawable-hdpi/alert.png
new file mode 100644
index 0000000..f888dac
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/alert.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/alert_off.png b/libSafeMobile/src/main/res/drawable-hdpi/alert_off.png
new file mode 100644
index 0000000..22bfa71
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/alert_off.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/ambulance.png b/libSafeMobile/src/main/res/drawable-hdpi/ambulance.png
new file mode 100644
index 0000000..ce94817
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/ambulance.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/ambulance_large.png b/libSafeMobile/src/main/res/drawable-hdpi/ambulance_large.png
new file mode 100644
index 0000000..4f4f3d9
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/ambulance_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/ar.png b/libSafeMobile/src/main/res/drawable-hdpi/ar.png
new file mode 100644
index 0000000..75d37a4
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/ar.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/ar_grey.9.png b/libSafeMobile/src/main/res/drawable-hdpi/ar_grey.9.png
new file mode 100644
index 0000000..cf5b695
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/ar_grey.9.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/ara.png b/libSafeMobile/src/main/res/drawable-hdpi/ara.png
new file mode 100644
index 0000000..49023b8
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/ara.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/army.png b/libSafeMobile/src/main/res/drawable-hdpi/army.png
new file mode 100644
index 0000000..df0ad1b
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/army.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/army_large.png b/libSafeMobile/src/main/res/drawable-hdpi/army_large.png
new file mode 100644
index 0000000..1cabd49
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/army_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_e.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_e.png
new file mode 100644
index 0000000..f3aa186
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_e.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_ene.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_ene.png
new file mode 100644
index 0000000..abfb7c5
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_ene.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_ese.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_ese.png
new file mode 100644
index 0000000..6b94606
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_ese.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_menu_down.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_menu_down.png
new file mode 100644
index 0000000..d25c7f0
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_menu_down.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_menu_down_small.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_menu_down_small.png
new file mode 100644
index 0000000..049a22b
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_menu_down_small.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_n.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_n.png
new file mode 100644
index 0000000..6d4e198
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_n.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_ne.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_ne.png
new file mode 100644
index 0000000..3be5448
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_ne.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_nne.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_nne.png
new file mode 100644
index 0000000..f2ecffc
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_nne.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_nnv.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_nnv.png
new file mode 100644
index 0000000..74e715a
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_nnv.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_nv.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_nv.png
new file mode 100644
index 0000000..43ebc68
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_nv.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_s.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_s.png
new file mode 100644
index 0000000..bd48f63
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_s.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_se.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_se.png
new file mode 100644
index 0000000..6fc1257
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_se.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_spinner.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_spinner.png
new file mode 100644
index 0000000..203c1f0
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_spinner.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_sse.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_sse.png
new file mode 100644
index 0000000..95409a3
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_sse.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_ssv.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_ssv.png
new file mode 100644
index 0000000..5e0cbae
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_ssv.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_sv.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_sv.png
new file mode 100644
index 0000000..f026963
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_sv.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_v.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_v.png
new file mode 100644
index 0000000..f1398f1
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_v.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_vnv.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_vnv.png
new file mode 100644
index 0000000..1a496ea
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_vnv.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/arrow_vsv.png b/libSafeMobile/src/main/res/drawable-hdpi/arrow_vsv.png
new file mode 100644
index 0000000..654fdf0
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/arrow_vsv.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/bigcar0.png b/libSafeMobile/src/main/res/drawable-hdpi/bigcar0.png
new file mode 100644
index 0000000..1a2a74e
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/bigcar0.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/bigcar0_large.png b/libSafeMobile/src/main/res/drawable-hdpi/bigcar0_large.png
new file mode 100644
index 0000000..7feec29
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/bigcar0_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/bigcar1.png b/libSafeMobile/src/main/res/drawable-hdpi/bigcar1.png
new file mode 100644
index 0000000..6eb513a
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/bigcar1.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/bigcar1_large.png b/libSafeMobile/src/main/res/drawable-hdpi/bigcar1_large.png
new file mode 100644
index 0000000..26dea3e
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/bigcar1_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/bigcar2.png b/libSafeMobile/src/main/res/drawable-hdpi/bigcar2.png
new file mode 100644
index 0000000..e179a05
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/bigcar2.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/bigcar2_large.png b/libSafeMobile/src/main/res/drawable-hdpi/bigcar2_large.png
new file mode 100644
index 0000000..b47b050
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/bigcar2_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/bus.png b/libSafeMobile/src/main/res/drawable-hdpi/bus.png
new file mode 100644
index 0000000..2558935
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/bus.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/bus0.png b/libSafeMobile/src/main/res/drawable-hdpi/bus0.png
new file mode 100644
index 0000000..ce7792c
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/bus0.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/bus0_large.png b/libSafeMobile/src/main/res/drawable-hdpi/bus0_large.png
new file mode 100644
index 0000000..279b08e
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/bus0_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/bus2.png b/libSafeMobile/src/main/res/drawable-hdpi/bus2.png
new file mode 100644
index 0000000..79074e1
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/bus2.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/bus2_large.png b/libSafeMobile/src/main/res/drawable-hdpi/bus2_large.png
new file mode 100644
index 0000000..bec0a69
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/bus2_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/bus_large.png b/libSafeMobile/src/main/res/drawable-hdpi/bus_large.png
new file mode 100644
index 0000000..8c92e45
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/bus_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/cabrioletred.png b/libSafeMobile/src/main/res/drawable-hdpi/cabrioletred.png
new file mode 100644
index 0000000..56258ae
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/cabrioletred.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/cabrioletred_large.png b/libSafeMobile/src/main/res/drawable-hdpi/cabrioletred_large.png
new file mode 100644
index 0000000..691c0c3
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/cabrioletred_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_all_blue.png b/libSafeMobile/src/main/res/drawable-hdpi/call_all_blue.png
new file mode 100644
index 0000000..9ad6911
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_all_blue.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_all_blue_small.png b/libSafeMobile/src/main/res/drawable-hdpi/call_all_blue_small.png
new file mode 100644
index 0000000..7b2983f
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_all_blue_small.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_all_green.png b/libSafeMobile/src/main/res/drawable-hdpi/call_all_green.png
new file mode 100644
index 0000000..bb7a5f0
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_all_green.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_all_green_small.png b/libSafeMobile/src/main/res/drawable-hdpi/call_all_green_small.png
new file mode 100644
index 0000000..503bcb3
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_all_green_small.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_group_blue.png b/libSafeMobile/src/main/res/drawable-hdpi/call_group_blue.png
new file mode 100644
index 0000000..9a81a7f
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_group_blue.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_group_blue_small.png b/libSafeMobile/src/main/res/drawable-hdpi/call_group_blue_small.png
new file mode 100644
index 0000000..36b9b44
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_group_blue_small.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_group_green.png b/libSafeMobile/src/main/res/drawable-hdpi/call_group_green.png
new file mode 100644
index 0000000..f921928
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_group_green.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_group_green_small.png b/libSafeMobile/src/main/res/drawable-hdpi/call_group_green_small.png
new file mode 100644
index 0000000..a1be7bb
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_group_green_small.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_made.png b/libSafeMobile/src/main/res/drawable-hdpi/call_made.png
new file mode 100644
index 0000000..e332cf4
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_made.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_made_all.png b/libSafeMobile/src/main/res/drawable-hdpi/call_made_all.png
new file mode 100644
index 0000000..15a18d9
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_made_all.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_made_group.png b/libSafeMobile/src/main/res/drawable-hdpi/call_made_group.png
new file mode 100644
index 0000000..7cff314
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_made_group.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_private_blue.png b/libSafeMobile/src/main/res/drawable-hdpi/call_private_blue.png
new file mode 100644
index 0000000..3e93018
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_private_blue.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_private_blue_small.png b/libSafeMobile/src/main/res/drawable-hdpi/call_private_blue_small.png
new file mode 100644
index 0000000..428fa87
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_private_blue_small.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_private_green.png b/libSafeMobile/src/main/res/drawable-hdpi/call_private_green.png
new file mode 100644
index 0000000..5c9bc3b
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_private_green.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_private_green_sm.png b/libSafeMobile/src/main/res/drawable-hdpi/call_private_green_sm.png
new file mode 100644
index 0000000..6d3c65d
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_private_green_sm.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_private_green_small.png b/libSafeMobile/src/main/res/drawable-hdpi/call_private_green_small.png
new file mode 100644
index 0000000..239f7b0
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_private_green_small.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_received.png b/libSafeMobile/src/main/res/drawable-hdpi/call_received.png
new file mode 100644
index 0000000..360a820
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_received.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_received_all.png b/libSafeMobile/src/main/res/drawable-hdpi/call_received_all.png
new file mode 100644
index 0000000..636a5ef
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_received_all.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/call_received_group.png b/libSafeMobile/src/main/res/drawable-hdpi/call_received_group.png
new file mode 100644
index 0000000..810e6ad
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/call_received_group.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/car0.png b/libSafeMobile/src/main/res/drawable-hdpi/car0.png
new file mode 100644
index 0000000..cba0da4
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/car0.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/car0_large.png b/libSafeMobile/src/main/res/drawable-hdpi/car0_large.png
new file mode 100644
index 0000000..dc9d3bb
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/car0_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/car1.png b/libSafeMobile/src/main/res/drawable-hdpi/car1.png
new file mode 100644
index 0000000..c6d8783
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/car1.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/car1_large.png b/libSafeMobile/src/main/res/drawable-hdpi/car1_large.png
new file mode 100644
index 0000000..7d3e07c
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/car1_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/car2.png b/libSafeMobile/src/main/res/drawable-hdpi/car2.png
new file mode 100644
index 0000000..3624478
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/car2.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/car2_large.png b/libSafeMobile/src/main/res/drawable-hdpi/car2_large.png
new file mode 100644
index 0000000..98025e6
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/car2_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/car3.png b/libSafeMobile/src/main/res/drawable-hdpi/car3.png
new file mode 100644
index 0000000..36ad6c1
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/car3.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/car3_large.png b/libSafeMobile/src/main/res/drawable-hdpi/car3_large.png
new file mode 100644
index 0000000..1cb2728
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/car3_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/cargrey.png b/libSafeMobile/src/main/res/drawable-hdpi/cargrey.png
new file mode 100644
index 0000000..7f30aa9
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/cargrey.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/cargrey_large.png b/libSafeMobile/src/main/res/drawable-hdpi/cargrey_large.png
new file mode 100644
index 0000000..ccb63e5
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/cargrey_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/channel.png b/libSafeMobile/src/main/res/drawable-hdpi/channel.png
new file mode 100644
index 0000000..ac3ac5b
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/channel.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/channel_small.png b/libSafeMobile/src/main/res/drawable-hdpi/channel_small.png
new file mode 100644
index 0000000..92c7eb3
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/channel_small.png differ
diff --git a/res/drawable-hdpi/checked.png b/libSafeMobile/src/main/res/drawable-hdpi/checked.png
similarity index 100%
rename from res/drawable-hdpi/checked.png
rename to libSafeMobile/src/main/res/drawable-hdpi/checked.png
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/classiccar.png b/libSafeMobile/src/main/res/drawable-hdpi/classiccar.png
new file mode 100644
index 0000000..2ea8585
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/classiccar.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/classiccar_large.png b/libSafeMobile/src/main/res/drawable-hdpi/classiccar_large.png
new file mode 100644
index 0000000..848c92d
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/classiccar_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/classycar.png b/libSafeMobile/src/main/res/drawable-hdpi/classycar.png
new file mode 100644
index 0000000..675d4c7
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/classycar.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/classycar_large.png b/libSafeMobile/src/main/res/drawable-hdpi/classycar_large.png
new file mode 100644
index 0000000..5166e48
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/classycar_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/combobox.9.png b/libSafeMobile/src/main/res/drawable-hdpi/combobox.9.png
new file mode 100644
index 0000000..cfa427a
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/combobox.9.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/combobox_bg_selector.xml b/libSafeMobile/src/main/res/drawable-hdpi/combobox_bg_selector.xml
new file mode 100644
index 0000000..81bb14a
--- /dev/null
+++ b/libSafeMobile/src/main/res/drawable-hdpi/combobox_bg_selector.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/combobox_over.9.png b/libSafeMobile/src/main/res/drawable-hdpi/combobox_over.9.png
new file mode 100644
index 0000000..e73ce1a
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/combobox_over.9.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/de.png b/libSafeMobile/src/main/res/drawable-hdpi/de.png
new file mode 100644
index 0000000..7814e65
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/de.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/dial.png b/libSafeMobile/src/main/res/drawable-hdpi/dial.png
new file mode 100644
index 0000000..1dbc29e
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/dial.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/dodge.png b/libSafeMobile/src/main/res/drawable-hdpi/dodge.png
new file mode 100644
index 0000000..d3435e6
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/dodge.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/dodge_large.png b/libSafeMobile/src/main/res/drawable-hdpi/dodge_large.png
new file mode 100644
index 0000000..4385221
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/dodge_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/en.png b/libSafeMobile/src/main/res/drawable-hdpi/en.png
new file mode 100644
index 0000000..5ca8eab
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/en.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/error.png b/libSafeMobile/src/main/res/drawable-hdpi/error.png
new file mode 100644
index 0000000..6988c97
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/error.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/es.png b/libSafeMobile/src/main/res/drawable-hdpi/es.png
new file mode 100644
index 0000000..f90ea5d
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/es.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/exclamation_small.png b/libSafeMobile/src/main/res/drawable-hdpi/exclamation_small.png
new file mode 100644
index 0000000..0b064c3
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/exclamation_small.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/fireescape.png b/libSafeMobile/src/main/res/drawable-hdpi/fireescape.png
new file mode 100644
index 0000000..f1eaca7
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/fireescape.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/fireescape_large.png b/libSafeMobile/src/main/res/drawable-hdpi/fireescape_large.png
new file mode 100644
index 0000000..16a0754
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/fireescape_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/firefighters2.png b/libSafeMobile/src/main/res/drawable-hdpi/firefighters2.png
new file mode 100644
index 0000000..6a0d394
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/firefighters2.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/firefighters2_large.png b/libSafeMobile/src/main/res/drawable-hdpi/firefighters2_large.png
new file mode 100644
index 0000000..d6e001b
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/firefighters2_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/firetruck1.png b/libSafeMobile/src/main/res/drawable-hdpi/firetruck1.png
new file mode 100644
index 0000000..de3db4d
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/firetruck1.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/firetruck1_large.png b/libSafeMobile/src/main/res/drawable-hdpi/firetruck1_large.png
new file mode 100644
index 0000000..2217eab
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/firetruck1_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/firetruck2.png b/libSafeMobile/src/main/res/drawable-hdpi/firetruck2.png
new file mode 100644
index 0000000..9af94b3
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/firetruck2.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/firetruck2_large.png b/libSafeMobile/src/main/res/drawable-hdpi/firetruck2_large.png
new file mode 100644
index 0000000..9c27e1f
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/firetruck2_large.png differ
diff --git a/res/drawable-hdpi/icon.png b/libSafeMobile/src/main/res/drawable-hdpi/icon.png
similarity index 100%
rename from res/drawable-hdpi/icon.png
rename to libSafeMobile/src/main/res/drawable-hdpi/icon.png
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/jeep.png b/libSafeMobile/src/main/res/drawable-hdpi/jeep.png
new file mode 100644
index 0000000..82daa75
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/jeep.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/jeep_large.png b/libSafeMobile/src/main/res/drawable-hdpi/jeep_large.png
new file mode 100644
index 0000000..407e7ff
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/jeep_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/longhaul.png b/libSafeMobile/src/main/res/drawable-hdpi/longhaul.png
new file mode 100644
index 0000000..3c1d5a8
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/longhaul.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/longhaul_large.png b/libSafeMobile/src/main/res/drawable-hdpi/longhaul_large.png
new file mode 100644
index 0000000..a69e032
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/longhaul_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/lorrygreen.png b/libSafeMobile/src/main/res/drawable-hdpi/lorrygreen.png
new file mode 100644
index 0000000..101c4b1
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/lorrygreen.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/lorrygreen_large.png b/libSafeMobile/src/main/res/drawable-hdpi/lorrygreen_large.png
new file mode 100644
index 0000000..3cfe9de
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/lorrygreen_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/m_message.png b/libSafeMobile/src/main/res/drawable-hdpi/m_message.png
new file mode 100644
index 0000000..6511ea4
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/m_message.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/m_settings.png b/libSafeMobile/src/main/res/drawable-hdpi/m_settings.png
new file mode 100644
index 0000000..85be590
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/m_settings.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/minibus.png b/libSafeMobile/src/main/res/drawable-hdpi/minibus.png
new file mode 100644
index 0000000..c1ef14a
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/minibus.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/minibus_large.png b/libSafeMobile/src/main/res/drawable-hdpi/minibus_large.png
new file mode 100644
index 0000000..8f8cf5a
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/minibus_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/minicar.png b/libSafeMobile/src/main/res/drawable-hdpi/minicar.png
new file mode 100644
index 0000000..7daf2d5
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/minicar.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/minicar2.png b/libSafeMobile/src/main/res/drawable-hdpi/minicar2.png
new file mode 100644
index 0000000..ecc1416
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/minicar2.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/minicar2_large.png b/libSafeMobile/src/main/res/drawable-hdpi/minicar2_large.png
new file mode 100644
index 0000000..b9dec7d
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/minicar2_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/minicar_large.png b/libSafeMobile/src/main/res/drawable-hdpi/minicar_large.png
new file mode 100644
index 0000000..a68e4f5
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/minicar_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/peopleblue.png b/libSafeMobile/src/main/res/drawable-hdpi/peopleblue.png
new file mode 100644
index 0000000..effaf97
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/peopleblue.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/peopleblue_large.png b/libSafeMobile/src/main/res/drawable-hdpi/peopleblue_large.png
new file mode 100644
index 0000000..6d9135e
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/peopleblue_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/peoplegreen.png b/libSafeMobile/src/main/res/drawable-hdpi/peoplegreen.png
new file mode 100644
index 0000000..5c928df
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/peoplegreen.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/peoplegreen_large.png b/libSafeMobile/src/main/res/drawable-hdpi/peoplegreen_large.png
new file mode 100644
index 0000000..561e1ed
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/peoplegreen_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/peoplegrey.png b/libSafeMobile/src/main/res/drawable-hdpi/peoplegrey.png
new file mode 100644
index 0000000..0871a04
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/peoplegrey.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/peoplegrey_large.png b/libSafeMobile/src/main/res/drawable-hdpi/peoplegrey_large.png
new file mode 100644
index 0000000..5a5f8a1
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/peoplegrey_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/peoplepink.png b/libSafeMobile/src/main/res/drawable-hdpi/peoplepink.png
new file mode 100644
index 0000000..d43eaa1
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/peoplepink.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/peoplepink_large.png b/libSafeMobile/src/main/res/drawable-hdpi/peoplepink_large.png
new file mode 100644
index 0000000..e9799dc
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/peoplepink_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/peoplepurple.png b/libSafeMobile/src/main/res/drawable-hdpi/peoplepurple.png
new file mode 100644
index 0000000..8d5c861
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/peoplepurple.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/peoplepurple_large.png b/libSafeMobile/src/main/res/drawable-hdpi/peoplepurple_large.png
new file mode 100644
index 0000000..7beea1e
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/peoplepurple_large.png differ
diff --git a/res/drawable-hdpi/play.png b/libSafeMobile/src/main/res/drawable-hdpi/play.png
similarity index 100%
rename from res/drawable-hdpi/play.png
rename to libSafeMobile/src/main/res/drawable-hdpi/play.png
diff --git a/res/drawable-hdpi/play_over.png b/libSafeMobile/src/main/res/drawable-hdpi/play_over.png
similarity index 100%
rename from res/drawable-hdpi/play_over.png
rename to libSafeMobile/src/main/res/drawable-hdpi/play_over.png
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/police.png b/libSafeMobile/src/main/res/drawable-hdpi/police.png
new file mode 100644
index 0000000..b516945
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/police.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/police1.png b/libSafeMobile/src/main/res/drawable-hdpi/police1.png
new file mode 100644
index 0000000..b2869a9
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/police1.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/police1_large.png b/libSafeMobile/src/main/res/drawable-hdpi/police1_large.png
new file mode 100644
index 0000000..ca88ab3
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/police1_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/police_large.png b/libSafeMobile/src/main/res/drawable-hdpi/police_large.png
new file mode 100644
index 0000000..744fb30
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/police_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/poll.png b/libSafeMobile/src/main/res/drawable-hdpi/poll.png
new file mode 100644
index 0000000..d135401
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/poll.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/recordings.png b/libSafeMobile/src/main/res/drawable-hdpi/recordings.png
new file mode 100644
index 0000000..a13dd66
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/recordings.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/recycle.png b/libSafeMobile/src/main/res/drawable-hdpi/recycle.png
new file mode 100644
index 0000000..c059664
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/recycle.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/ro.png b/libSafeMobile/src/main/res/drawable-hdpi/ro.png
new file mode 100644
index 0000000..4bbd6f0
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/ro.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/ru.png b/libSafeMobile/src/main/res/drawable-hdpi/ru.png
new file mode 100644
index 0000000..4d72c77
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/ru.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/schoolbus.png b/libSafeMobile/src/main/res/drawable-hdpi/schoolbus.png
new file mode 100644
index 0000000..ae236d4
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/schoolbus.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/schoolbus2.png b/libSafeMobile/src/main/res/drawable-hdpi/schoolbus2.png
new file mode 100644
index 0000000..ab5b97f
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/schoolbus2.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/schoolbus2_large.png b/libSafeMobile/src/main/res/drawable-hdpi/schoolbus2_large.png
new file mode 100644
index 0000000..233a018
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/schoolbus2_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/schoolbus_large.png b/libSafeMobile/src/main/res/drawable-hdpi/schoolbus_large.png
new file mode 100644
index 0000000..f5109cb
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/schoolbus_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/separator.png b/libSafeMobile/src/main/res/drawable-hdpi/separator.png
new file mode 100644
index 0000000..16114f9
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/separator.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/separator_white.png b/libSafeMobile/src/main/res/drawable-hdpi/separator_white.png
new file mode 100644
index 0000000..25a918b
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/separator_white.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/spinner_arrows.9.png b/libSafeMobile/src/main/res/drawable-hdpi/spinner_arrows.9.png
new file mode 100644
index 0000000..892e7f7
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/spinner_arrows.9.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/taxi.png b/libSafeMobile/src/main/res/drawable-hdpi/taxi.png
new file mode 100644
index 0000000..1565f74
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/taxi.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/taxi_large.png b/libSafeMobile/src/main/res/drawable-hdpi/taxi_large.png
new file mode 100644
index 0000000..610ef5f
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/taxi_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/towtruckyellow.png b/libSafeMobile/src/main/res/drawable-hdpi/towtruckyellow.png
new file mode 100644
index 0000000..45e640b
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/towtruckyellow.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/towtruckyellow_large.png b/libSafeMobile/src/main/res/drawable-hdpi/towtruckyellow_large.png
new file mode 100644
index 0000000..546430f
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/towtruckyellow_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/tr.png b/libSafeMobile/src/main/res/drawable-hdpi/tr.png
new file mode 100644
index 0000000..5c20607
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/tr.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/tractorunitblack.png b/libSafeMobile/src/main/res/drawable-hdpi/tractorunitblack.png
new file mode 100644
index 0000000..b85adeb
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/tractorunitblack.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/tractorunitblack_large.png b/libSafeMobile/src/main/res/drawable-hdpi/tractorunitblack_large.png
new file mode 100644
index 0000000..68c9646
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/tractorunitblack_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck0.png b/libSafeMobile/src/main/res/drawable-hdpi/truck0.png
new file mode 100644
index 0000000..5ea2eea
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck0.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck0_large.png b/libSafeMobile/src/main/res/drawable-hdpi/truck0_large.png
new file mode 100644
index 0000000..5518329
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck0_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck1.png b/libSafeMobile/src/main/res/drawable-hdpi/truck1.png
new file mode 100644
index 0000000..235fd82
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck1.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck1_large.png b/libSafeMobile/src/main/res/drawable-hdpi/truck1_large.png
new file mode 100644
index 0000000..96873ba
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck1_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck2.png b/libSafeMobile/src/main/res/drawable-hdpi/truck2.png
new file mode 100644
index 0000000..1fe9237
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck2.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck2_large.png b/libSafeMobile/src/main/res/drawable-hdpi/truck2_large.png
new file mode 100644
index 0000000..e8ccd75
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck2_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck3.png b/libSafeMobile/src/main/res/drawable-hdpi/truck3.png
new file mode 100644
index 0000000..0ca1259
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck3.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck3_large.png b/libSafeMobile/src/main/res/drawable-hdpi/truck3_large.png
new file mode 100644
index 0000000..eb64ae0
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck3_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck4.png b/libSafeMobile/src/main/res/drawable-hdpi/truck4.png
new file mode 100644
index 0000000..95e82d7
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck4.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck4_large.png b/libSafeMobile/src/main/res/drawable-hdpi/truck4_large.png
new file mode 100644
index 0000000..7f7794b
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck4_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck5.png b/libSafeMobile/src/main/res/drawable-hdpi/truck5.png
new file mode 100644
index 0000000..bd33eed
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck5.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck5_large.png b/libSafeMobile/src/main/res/drawable-hdpi/truck5_large.png
new file mode 100644
index 0000000..9f0ebca
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck5_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck6.png b/libSafeMobile/src/main/res/drawable-hdpi/truck6.png
new file mode 100644
index 0000000..5daecf1
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck6.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truck6_large.png b/libSafeMobile/src/main/res/drawable-hdpi/truck6_large.png
new file mode 100644
index 0000000..56b1d6d
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truck6_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truckyellow.png b/libSafeMobile/src/main/res/drawable-hdpi/truckyellow.png
new file mode 100644
index 0000000..55a1db2
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truckyellow.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/truckyellow_large.png b/libSafeMobile/src/main/res/drawable-hdpi/truckyellow_large.png
new file mode 100644
index 0000000..b07fcf6
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/truckyellow_large.png differ
diff --git a/res/drawable-hdpi/unchecked.png b/libSafeMobile/src/main/res/drawable-hdpi/unchecked.png
similarity index 100%
rename from res/drawable-hdpi/unchecked.png
rename to libSafeMobile/src/main/res/drawable-hdpi/unchecked.png
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/wagon.png b/libSafeMobile/src/main/res/drawable-hdpi/wagon.png
new file mode 100644
index 0000000..64d630f
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/wagon.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/wagon_large.png b/libSafeMobile/src/main/res/drawable-hdpi/wagon_large.png
new file mode 100644
index 0000000..dd3f917
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/wagon_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/zone.png b/libSafeMobile/src/main/res/drawable-hdpi/zone.png
new file mode 100644
index 0000000..964697c
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/zone.png differ
diff --git a/libSafeMobile/src/main/res/drawable-hdpi/zone_small.png b/libSafeMobile/src/main/res/drawable-hdpi/zone_small.png
new file mode 100644
index 0000000..df76381
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-hdpi/zone_small.png differ
diff --git a/libSafeMobile/src/main/res/drawable-ldpi/m_settings.png b/libSafeMobile/src/main/res/drawable-ldpi/m_settings.png
new file mode 100644
index 0000000..a42ea52
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-ldpi/m_settings.png differ
diff --git a/libSafeMobile/src/main/res/drawable-ldpi/message.png b/libSafeMobile/src/main/res/drawable-ldpi/message.png
new file mode 100644
index 0000000..806da60
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-ldpi/message.png differ
diff --git a/libSafeMobile/src/main/res/drawable-ldpi/recordings.png b/libSafeMobile/src/main/res/drawable-ldpi/recordings.png
new file mode 100644
index 0000000..11f3e57
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-ldpi/recordings.png differ
diff --git a/libSafeMobile/src/main/res/drawable-ldpi/textmessage.png b/libSafeMobile/src/main/res/drawable-ldpi/textmessage.png
new file mode 100644
index 0000000..806da60
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-ldpi/textmessage.png differ
diff --git a/libSafeMobile/src/main/res/drawable-mdpi/bg_combobox.9.png b/libSafeMobile/src/main/res/drawable-mdpi/bg_combobox.9.png
new file mode 100644
index 0000000..dc20e03
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-mdpi/bg_combobox.9.png differ
diff --git a/libSafeMobile/src/main/res/drawable-mdpi/bg_combobox_disabled.9.png b/libSafeMobile/src/main/res/drawable-mdpi/bg_combobox_disabled.9.png
new file mode 100644
index 0000000..478eaa0
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-mdpi/bg_combobox_disabled.9.png differ
diff --git a/libSafeMobile/src/main/res/drawable-mdpi/bg_combobox_pressed.9.png b/libSafeMobile/src/main/res/drawable-mdpi/bg_combobox_pressed.9.png
new file mode 100644
index 0000000..21e52d1
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-mdpi/bg_combobox_pressed.9.png differ
diff --git a/libSafeMobile/src/main/res/drawable-mdpi/bg_selector_combobox.xml b/libSafeMobile/src/main/res/drawable-mdpi/bg_selector_combobox.xml
new file mode 100644
index 0000000..f06ea01
--- /dev/null
+++ b/libSafeMobile/src/main/res/drawable-mdpi/bg_selector_combobox.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/drawable-mdpi/btn_shay.9.png b/libSafeMobile/src/main/res/drawable-mdpi/btn_shay.9.png
new file mode 100644
index 0000000..6181574
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-mdpi/btn_shay.9.png differ
diff --git a/libSafeMobile/src/main/res/drawable-mdpi/m_settings.png b/libSafeMobile/src/main/res/drawable-mdpi/m_settings.png
new file mode 100644
index 0000000..a42ea52
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-mdpi/m_settings.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/bg_motopad.jpg b/libSafeMobile/src/main/res/drawable-xhdpi/bg_motopad.jpg
new file mode 100644
index 0000000..78bbf31
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/bg_motopad.jpg differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/footer.9.png b/libSafeMobile/src/main/res/drawable-xhdpi/footer.9.png
new file mode 100644
index 0000000..5543e94
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/footer.9.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/footer_blue.9.png b/libSafeMobile/src/main/res/drawable-xhdpi/footer_blue.9.png
new file mode 100644
index 0000000..a77b933
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/footer_blue.9.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/footer_normal.png b/libSafeMobile/src/main/res/drawable-xhdpi/footer_normal.png
new file mode 100644
index 0000000..4db63b5
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/footer_normal.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/m_message.png b/libSafeMobile/src/main/res/drawable-xhdpi/m_message.png
new file mode 100644
index 0000000..806da60
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/m_message.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/m_message_large.png b/libSafeMobile/src/main/res/drawable-xhdpi/m_message_large.png
new file mode 100644
index 0000000..d04e9d3
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/m_message_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/m_settings.png b/libSafeMobile/src/main/res/drawable-xhdpi/m_settings.png
new file mode 100644
index 0000000..a42ea52
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/m_settings.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/message.png b/libSafeMobile/src/main/res/drawable-xhdpi/message.png
new file mode 100644
index 0000000..806da60
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/message.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/recording.png b/libSafeMobile/src/main/res/drawable-xhdpi/recording.png
new file mode 100644
index 0000000..11f3e57
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/recording.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/recording_large.png b/libSafeMobile/src/main/res/drawable-xhdpi/recording_large.png
new file mode 100644
index 0000000..5eec55d
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/recording_large.png differ
diff --git a/libSafeMobile/src/main/res/drawable-xhdpi/waves.png b/libSafeMobile/src/main/res/drawable-xhdpi/waves.png
new file mode 100644
index 0000000..e641991
Binary files /dev/null and b/libSafeMobile/src/main/res/drawable-xhdpi/waves.png differ
diff --git a/res/drawable-hdpi/icon_original.png b/libSafeMobile/src/main/res/drawable/ic_launcher.png
similarity index 100%
rename from res/drawable-hdpi/icon_original.png
rename to libSafeMobile/src/main/res/drawable/ic_launcher.png
diff --git a/libSafeMobile/src/main/res/layout-large/titled_combobox.xml b/libSafeMobile/src/main/res/layout-large/titled_combobox.xml
new file mode 100644
index 0000000..8e05b96
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout-large/titled_combobox.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/layout-small/titled_combobox.xml b/libSafeMobile/src/main/res/layout-small/titled_combobox.xml
new file mode 100644
index 0000000..3fcd3af
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout-small/titled_combobox.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/layout-w650dp/titled_combobox.xml b/libSafeMobile/src/main/res/layout-w650dp/titled_combobox.xml
new file mode 100644
index 0000000..ad1b234
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout-w650dp/titled_combobox.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/layout/activity_main.xml b/libSafeMobile/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..98704be
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout/activity_main.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/layout/combobox_bg_selector.xml b/libSafeMobile/src/main/res/layout/combobox_bg_selector.xml
new file mode 100644
index 0000000..6ba4f53
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout/combobox_bg_selector.xml
@@ -0,0 +1,31 @@
+
+
+-
+
+
+
+
+
+-
+
+
+
+
+
+-
+
+
+
+
+
diff --git a/libSafeMobile/src/main/res/layout/combobox_row.xml b/libSafeMobile/src/main/res/layout/combobox_row.xml
new file mode 100644
index 0000000..11fed2f
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout/combobox_row.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/layout/combobox_section_header.xml b/libSafeMobile/src/main/res/layout/combobox_section_header.xml
new file mode 100644
index 0000000..af55fbd
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout/combobox_section_header.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/layout/row_alert.xml b/libSafeMobile/src/main/res/layout/row_alert.xml
new file mode 100644
index 0000000..a95893d
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout/row_alert.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/layout/row_conversation.xml b/libSafeMobile/src/main/res/layout/row_conversation.xml
new file mode 100644
index 0000000..4273df7
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout/row_conversation.xml
@@ -0,0 +1,165 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/style_received.xml b/libSafeMobile/src/main/res/layout/row_conversation_style_rec.xml
similarity index 100%
rename from res/layout/style_received.xml
rename to libSafeMobile/src/main/res/layout/row_conversation_style_rec.xml
diff --git a/res/layout/style_send.xml b/libSafeMobile/src/main/res/layout/row_conversation_style_send.xml
similarity index 100%
rename from res/layout/style_send.xml
rename to libSafeMobile/src/main/res/layout/row_conversation_style_send.xml
diff --git a/libSafeMobile/src/main/res/layout/row_message.xml b/libSafeMobile/src/main/res/layout/row_message.xml
new file mode 100644
index 0000000..ba00aae
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout/row_message.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/layout/row_recordings.xml b/libSafeMobile/src/main/res/layout/row_recordings.xml
new file mode 100644
index 0000000..1d49e6a
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout/row_recordings.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/layout/row_vehicle.xml b/libSafeMobile/src/main/res/layout/row_vehicle.xml
new file mode 100644
index 0000000..ad70d8e
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout/row_vehicle.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/style_grid.xml b/libSafeMobile/src/main/res/layout/row_vehicle_style.xml
similarity index 100%
rename from res/layout/style_grid.xml
rename to libSafeMobile/src/main/res/layout/row_vehicle_style.xml
diff --git a/res/layout/spinner.xml b/libSafeMobile/src/main/res/layout/spinner.xml
similarity index 100%
rename from res/layout/spinner.xml
rename to libSafeMobile/src/main/res/layout/spinner.xml
diff --git a/libSafeMobile/src/main/res/layout/titled_combobox.xml b/libSafeMobile/src/main/res/layout/titled_combobox.xml
new file mode 100644
index 0000000..30ac3da
--- /dev/null
+++ b/libSafeMobile/src/main/res/layout/titled_combobox.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values-ar/strings.xml b/libSafeMobile/src/main/res/values-ar/strings.xml
new file mode 100644
index 0000000..e868138
--- /dev/null
+++ b/libSafeMobile/src/main/res/values-ar/strings.xml
@@ -0,0 +1,312 @@
+
+
+
+ SafeDispatch Mobile
+ RadioPod
+ RadioPad
+ RadioPod TETRA
+ RadioPad TETRA
+ RadioPod SEPURA
+ RadioPad SEPURA
+ RadioPod
+ RadioPad
+ RadioPod Demo
+ RadioPad Demo
+ RadioPod TETRA Demo
+ RadioPad TETRA Demo
+ RadioPod SEPURA Demo
+ RadioPad SEPURA Demo
+ MotoPOD TETRA
+ MotoPAD TETRA
+ MotoPOD TETRA Demo
+ MotoPAD TETRA Demo
+ MotoPOD TRBO
+ MotoPAD TRBO
+ MotoPOD TRBO Demo
+ MotoPAD TRBO Demo
+ اللغة
+ اختيار لغة
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiyqDpsOhADJPi+ADVTBDOLY9105U3Z0vtRiZV46J9/0no2V+BcPmfwM5Gf/At+bNwX6P3GSkYmsBxFlaFxis723sR2B18nSQIoUaZrEldS02wUtO/M/Ilh8WyQ7FQYlugAxdXPl8N70Nf29opZ3okQlwM3NRJ7S+VGgE8SztRkCA7DE4cYLDBV01moGvyLZxe0vxGXVHWh2Pso623Gw/gghuONxqYUgt1ThNtLkQDcKG8UdG8N2f0Oc9tW4/624Eat5J+/DoPmzPSwUkohl8lukxzVISGUGaP3C5L1xQX2mdVIjIK3SrKInyDiRW3h7zDdjHtMZ+2OUj7rIDz9WlrQIDAQAB
+
+
+ هل متأكد من الخروج
+ نعم
+ لا
+ الإصدار
+ إيميل
+ رسالة جديدة
+ من
+ نوع
+ خروج
+ تسجيل الخروج
+
+
+ فقد الاتصال بالشبكة
+ اسم المستخدم
+ الرقم السري
+ دخول
+ الإعدادات
+ حفظ كإفتراضي
+ إلغاء
+ موافق
+ مدخل الإتصال
+ Welcome to SafeDispatch Mobile!\nYou have to set the IP where the APPServer Mobile is installed.
+ تأكد من اسم المستخدم
+ خطأ الإتصال
+ تحميل المستخدمين
+ خانة المستخدم أو الرقم السري خالية
+ التاكد من اسم المستخدم
+
+
+ رسالة نصية
+ رسالة
+ اختيار سيارة
+ ارسال تقرير الخطأ
+ ارسال
+ غير فعال
+ محتويات شفرة الباراكوود
+ خطأفي قراءة الباراكوود
+
+
+ Dekey
+ اضغط لتتحدث
+ خاصية اضغط لتتحدث مغلقة
+ طوارئ
+ منطقة
+ قناة
+ قائمة الإتصال
+ « قائمة الإتصال
+ IP:
+ 127.0.0.1
+ 192.168.10.40
+ الحالة
+ نوع الإتصال
+ جميع الإتصالات
+ مجموعة الإتصال
+ اتصال خاص
+ اختيار قناة
+ اختيار منطقة
+ اختيار مجموعة
+ غير متصل
+ متصل
+ زمن حجز الاتصال
+
+
+ الاسم
+ توقف
+
+
+ اسم الوحدة
+ نوع الإنذار
+ وصف
+ الوقت و التاريخ
+
+
+ مدخل الخادم
+ عنوان الخادم
+ حفظ
+ اسم ملف الإعدادات
+ تحميل
+ فقد الإعدادات
+
+
+ إعادة الضبط
+ اعادة ضبط الاعدادات
+ ارسال رسالة اعادة الضبط
+
+
+
+
+ ارسال رسالة
+ خطأ في الإرسال
+ ارسال تقرير الخطأ
+ اختيار المتصل
+ رسالة الطوارئ
+ فشل الطوارئ
+ ايقاف الطوارئ
+ فشل ايقاف الطوارئ
+ تم التحميل بنجاح
+ خطأ في التحميل
+ You must restart application for the changes to take effect!
+ تم حفظ الاعدادات بنجاح
+ خطأ في حفظ الاعدادات
+ إعادة تشغيل التطبيق
+ Hint
+ رسالة تلميح
+ عربي
+ الإنجليزية
+ الألمانية
+ التركية
+ الرومانية
+ الروسية
+ الإسبانية
+
+
+ - عربي
+ - الإنجليزية
+ - الألمانية
+ - التركية
+ - الرومانية
+ - الروسية
+ - الإسبانية
+
+
+ اتصال يدوي
+ صوت الاتصال
+ اعادة تشغيل
+ دفق الصوت
+ اختيار دفق الصوت
+ سماعة خارجية
+ إرسل نوع الاتصال
+ اضغط زر الإرسال
+ اتصال ابتدائي
+ خطأ اتصال
+ خطأ في الإرسال
+ مصدر الإرسال
+ رسالة جديدة
+ إلى
+ مصدر الصوت
+ اختيار مصدر الصوت
+ تسجيل
+ مسح التسجيل ؟
+ مسح كامل التسجيلات
+ المجموعات
+ المجموعات »
+ حالة سقوط شخص
+ حالة عدم الحركة
+ حالة سقوط
+ عدم الحركة
+ مرحبا !
+ قائمة الاعدادات
+ إعدادات التفعيل
+ تخزين خارجي
+ تخزين داخلي
+ خدمات TCP
+ تعريف المنطقة و القناة
+ تعريف الاتصالات
+ نسخة البرنامج
+ Your RadioPad version will work properly with SafeBridge Firmware %1$s version. Your current version is %2$s. You should update it!
+ اتصال مجهول
+ محتويات
+ تذكرني
+ تحميل التسجيل
+ خطأ في التشغيل
+
+
+
+
+
+ اسم غير موجود
+ ترقية البرنامج
+ اتصال آمن بالشبكة
+ ادخل عنوان الاتصال الآمن
+ تم الاتصال بالخدمة
+ تم قطع الاتصال
+ مرحبا بكم
+ ادخال اعداد اسم الجهاز
+ اسم الجهاز
+ حفظ التغييرات
+ حفظ الاعدادات؟
+ %1$s - الجهاز متصل
+ %1$s - الجهاز غير متصل
+ Device found
+
+
+ المنطقة والقناة
+ جاري الاتصال
+ يتصل بك
+ قيم عناوين الراديو
+ عنوان المحطة الثابتة
+
+
+ قائمة الرسائل
+ قائمة اأجهزة الراديو
+ قائمة التسجيلات
+ قائمة الإعدادات
+ قائمة حول
+ اتصال بالطابعة ...
+ تم التصال بالطابعة
+ الطابعة غير متصلة
+ اتصال بالمجموعة
+ اتصال خاص
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values-ar/strings_activity_settings.xml b/libSafeMobile/src/main/res/values-ar/strings_activity_settings.xml
new file mode 100644
index 0000000..8b44366
--- /dev/null
+++ b/libSafeMobile/src/main/res/values-ar/strings_activity_settings.xml
@@ -0,0 +1,140 @@
+
+
+ Settings
+
+
+ SafeBridge Wi-Fi IP
+ 192.168.2.100
+ The IP of SafeBridge wireless network
+
+ SafeBridge Gateway Apps Port
+ 13570
+
+ Config file name
+ serial.xml
+ The name received after uploading the codeplug
+
+ Language
+ en
+
+ Audio Source
+ Audio Source
+
+ Audio Stream
+ Audio Stream
+
+ External Microphone
+ Set if an external mic will be used (eg.: for What-a-Pair system)
+
+ Tether Sound
+ Allow the sound to be redirected to a bluetooth device
+
+ Record calls
+ Allow that all calls to be saved
+
+ Recordings location
+ Select if recordings are saved on the internal or external storage
+
+ TRBO station
+ Select whether the station connected to SafeBridge is TRBO (checked) or TETRA (unchecked)
+
+ Text Message Notifications
+ Notifications will be triggered as they normally do
+
+ Man Down
+ Send an alarm signal if the device is dropped
+
+ Motionless
+ The device is tipped on its side for a preset perdiod
+
+ 300
+ Time before motionless event
+ The period after which the motionless alarm is sent (seconds)
+
+ 25
+ ManDown Threshold
+ ManDown threshold after which the alarm is sent[values from 1 to 50]
+
+ Reset SafeBridge
+ Reset the gateway applications that runs on SafeBridge
+
+ Audio settings
+ Radio configuration
+ SafeBridge Connection Parameters
+ Misc
+ Reset SafeBridge
+
+
+ Printer and MSR
+ Allow the Printer and the MSR to be active
+
+
+
+ Radio ID
+ 100
+ The ID of the radio on which the SafeBridge is connected
+
+ Define/Edit Contacts
+
+ Add, edit, remove contacts
+
+
+
+ - UDP
+ - TCP
+
+
+ - UDP
+ - TCP
+
+
+
+ - Internal Storage
+ - External Storage
+
+
+ - Internal Storage
+ - External Storage
+
+
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+
+
+ - عربي
+ - الإنجليزية
+ - الألمانية
+ - التركية
+ - الرومانية
+ - الروسية
+ - الإسبانية
+
+
+ - ar
+ - en
+ - de
+ - tr
+ - ro
+ - ru
+ - es
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values-de/strings.xml b/libSafeMobile/src/main/res/values-de/strings.xml
new file mode 100644
index 0000000..ad7e1d3
--- /dev/null
+++ b/libSafeMobile/src/main/res/values-de/strings.xml
@@ -0,0 +1,208 @@
+
+
+
+ SafeDispatch Mobile
+ RadioPod
+ RadioPad
+ RadioPod TETRA
+ RadioPad TETRA
+ RadioPod
+ RadioPad
+ RadioPod Demo
+ RadioPad Demo
+ RadioPod TETRA Demo
+ RadioPad TETRA Demo
+ MotoPOD TETRA
+ MotoPAD TETRA
+ MotoPOD TETRA Demo
+ MotoPAD TETRA Demo
+ MotoPOD TRBO
+ MotoPAD TRBO
+ MotoPOD TRBO Demo
+ MotoPAD TRBO Demo
+ Sprache:
+ Sprache wählen
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiyqDpsOhADJPi+ADVTBDOLY9105U3Z0vtRiZV46J9/0no2V+BcPmfwM5Gf/At+bNwX6P3GSkYmsBxFlaFxis723sR2B18nSQIoUaZrEldS02wUtO/M/Ilh8WyQ7FQYlugAxdXPl8N70Nf29opZ3okQlwM3NRJ7S+VGgE8SztRkCA7DE4cYLDBV01moGvyLZxe0vxGXVHWh2Pso623Gw/gghuONxqYUgt1ThNtLkQDcKG8UdG8N2f0Oc9tW4/624Eat5J+/DoPmzPSwUkohl8lukxzVISGUGaP3C5L1xQX2mdVIjIK3SrKInyDiRW3h7zDdjHtMZ+2OUj7rIDz9WlrQIDAQAB
+
+
+ Möchten Sie wirklich abschalten?
+ Ja
+ Nein
+ Version
+ E-Mail
+ Neue Nachricht
+ Von
+ Type
+ Ende
+ Logout
+
+
+ TCP Verbindung fehlt!
+ Username
+ Passwort
+ Login
+ Einstellungen
+ Grundeinstellung speichern
+ Löschen
+ OK
+ Der Kommunikatios Port
+ Willkommen zu Safeispatch Mobile! Stellen Sie die IP wie beim APP-Server Mobile ein.
+ Benutzer kann nicht geladen werden! Bitte prüfen Sie die Verbindung mit anschliessendem Neustart.
+ Verbindungsfehler
+ Benutzer von der Datenbank laden…
+ Passwort oder Benutzer fehlen!
+ Identifizierung…
+
+
+ Textnachricht
+ Nachricht:
+ Fahrzeug auswählen
+ Fehler senden
+ senden
+ kein ACK
+ Inhalt vom Barcode
+ Barcode Scanner ist nicht installiert!
+
+
+ Entsperren
+ PTT
+ PTT aus
+ Notruf
+ Zone
+ Kanal
+ Kontakte:
+ « Kontakte
+ IP:
+ 127.0.0.1
+ 192.168.10.40
+ Status:
+ Ruf Typ
+ Sammelruf
+ Gruppenruf
+ Einzelruf
+ Kanal auswählen
+ Zone auswählen
+ Gruppe auswählen
+ Offline!
+ Online
+ Haltezeit
+
+
+ Name
+ Stop
+
+
+ Gerätename
+ Alarm typ
+ Beschreibung
+ Datum und Zeit
+
+
+ Server Port:
+ Server IP:
+ Speichern
+ Config File Name:
+ Laden
+ Die Config File fehlt oder ist unvollständig! Grundeinstellung wird geladen.
+
+
+ Löschen
+ Sind Sie sicher das Sie löschen wollen?
+ Löschen an den Controller gesendet.
+
+
+
+
+ Nachricht wird gesendet…
+ Fehler beim senden aufgetreten, ACK nicht erhalten
+ Fehler wird gesendet
+ Kontakt auswählen
+ !!! Emg !!!
+ Emg fehlgeschlagen
+ Emg angehalten
+ Emg anhalten fehlgeschlagen
+ Download ist vollständig und erfolgreich.
+ Fehler beim download der Config File.
+ Neustart der Applikation!
+ Einstellungen erfolgreich gespeichert.
+ Einstellungen nicht vollständig geladen!
+ Neustart der Applikation
+ Hinweis
+ Geben Sie hier die Serien-Nr. ein (z.B. 038TJQ5277) nachdem Sie die conf.file aus der Motoroal CPS über (Reports- >Detailed Report- > Save as) erhalten haben.
+ Englisch
+ Deutsch
+ Türkisch
+ Rumänisch
+ Russisch
+ Spanisch
+
+
+ - Arabic
+ - English
+ - Deutsch
+ - Turkish
+ - Romanian
+ - Russian
+ - Spanish
+
+
+ Manuelle Wahl…
+ Sound übertragen:
+ Zum wirksam werden der Änderungen wbitte RadioPad neu starten.
+ Audio Stream:
+ Audio Stream wählen
+ Externes Mikrofon
+ Call Type senden
+ Ptt drücken für
+ Ruf auslösen
+ Ruf fehlgeschlagen
+ PTT Fehler
+ PTT wurde von externe Quelle ausgeführt!
+ Neue Nachricht von
+ an
+ Audio Quelle:
+ Audio Quelle wählen
+ Aufnahmen
+ Möchten Sie die Aufnahmen wirklich aus der Datenbank und dem Speicher löschen?
+ Alle Aufnahmen werden von der Datenbank und vom Speicher gelöscht. Weiter?
+ Gruppen:
+ Gruppen »
+ Totmann Vorfall
+ Bewegungsmelder Vorfall
+ Totmann Vorfall ausgelöst, Sind Sie ok?
+ Bewegungsmelder Vorfall ausgelöst, sind Sie ok?
+ Hello world!
+ Einstellungen
+ Aktivität einstellen
+ Externer Speicher
+ Interner Speicher
+ TCP Service
+ Zone und Kanäle festlegen
+ Kontakte festlegen
+ Firmware Version
+ Ihre RadioPad Version läuft sicher mit der SafeBridge FirmwareVersion %1$s. Ihre aktuelle Version ist %2$s. Sie sollten Ihre Version aktualisieren.!
+ Unbekannter Ruf
+ Image Inhalt
+ Erinnern
+ Aufnahme laden…
+ Fehler bei Wiedergabe der Aufnahme
+
+
+
+
+ Username oder Passwort ungültig!
+ Sie verwenden eine alte Version der Bridge Firmware. Bitte ein update für die neueste Version starten!
+ SafeBridge\'s IP
+ Geben Sie die IP von SafeBridge ein.
+ Service ist verbunden
+ Service is disconnected
+ Willkommen zu
+ Zur einwandfreien Funktion der Sprache geben Sie die Funkgeräte ID des Hauptgerätes ein
+ Radio ID
+ Änderungen sichern?
+ Möchten Sie die durchgeführten Änderungen abspeichern?
+ Gerät %1$s ist jetzt verbunden. Sprache wird übertragen…
+ Gerät %1$s ist jetzt getrennt. Übertragung wir gestoppt…
+ Gerät gefunden
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values-de/strings_activity_settings.xml b/libSafeMobile/src/main/res/values-de/strings_activity_settings.xml
new file mode 100644
index 0000000..0c91b1f
--- /dev/null
+++ b/libSafeMobile/src/main/res/values-de/strings_activity_settings.xml
@@ -0,0 +1,138 @@
+
+
+ Einstellungen
+
+
+ SafeBridge Wi-Fi IP
+ 192.168.2.100
+ Die IP für das Safebridge Wireless Netzwerk
+
+ SafeBridge Gateway Apps Port
+ 13570
+
+ Name Config File
+ Seriell.xml
+ Der Name nach dem upload des Codeplugs
+
+ Sprache
+ en
+
+ Audio Quelle
+ Audio Quelle
+
+ Audio Stream
+ Audio Stream
+
+ Externes Mikrofon
+ Einstellen wenn ein externes Mikrofon verwendet wird (z.B.: für What-a-pair System)
+
+ Klang übertragen
+ Freigabe um den Klang über ein Bluetooth Gerät zu übertragen
+
+ Rufe wiederholen
+ Freigabe das alle Rufe gespeichert werden
+
+ Aufnahme Medium
+ Auswählen ob Aufnahmen auf ein internes oder externes Medium gespeichert werden sollen
+
+ TRBO Station
+ Auswählen, ob das Funkgerät für die SafeBridge ein MotoTrbo oder Tetra Gerät ist
+
+ Textnachricht erhalten
+ Anzeige erscheint wie festgelegt
+
+
+ Totmann
+ Einen Alarm senden wenn die Verbindung unterbrochen ist
+
+ Bewegungslos
+ Das Gerät liegt auf der Seite für einen eingestellten Zeitraum
+
+ 300
+ Zeit vor dem Bewegungsmelder Vorfall
+ Zeitraum nachdem der Bewegungsmelderalarm gesendet wurde (Sekunden)
+
+ 25
+ Totmann Schwelle
+ Totmann Schwelle nacgdem der Alarm gesendet wird (Wert von1 bis 50)
+
+ Reset SafeBridge
+ Reset der Gateway Applikationauf der SafeBridge läuft
+
+ Audio Einstellungen
+ Konfiguration des Radios
+ SafeBridge Verbindungsparameter
+ weitere
+ Reset SafeBridge
+
+
+
+
+ Funkgeräte ID
+ 100
+ Die Funkgeräte ID mit der SafeBridge verbunden ist
+
+ Bestimmen /Einstellen der Kontakte
+
+ Hinzufügen, Einstellen, Entfernen von kontakten
+
+
+
+ - UDP
+ - TCP
+
+
+ - UDP
+ - TCP
+
+
+
+ - Internal Storage
+ - External Storage
+
+
+ - Internal Storage
+ - External Storage
+
+
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+
+
+ - Arabic
+ - English
+ - Deutsch
+ - Turkish
+ - Romanian
+ - Russian
+ - Spanish
+
+
+ - ar
+ - en
+ - de
+ - tr
+ - ro
+ - ru
+ - es
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values-es/strings.xml b/libSafeMobile/src/main/res/values-es/strings.xml
new file mode 100644
index 0000000..55ee7f6
--- /dev/null
+++ b/libSafeMobile/src/main/res/values-es/strings.xml
@@ -0,0 +1,169 @@
+
+
+
+ SafeDispatch Mobile
+ RadioPod
+ RadioPad
+ RadioPod
+ RadioPad
+ RadioPod Demo
+ RadioPad Demo
+ MotoPOD TETRA
+ MotoPAD TETRA
+ MotoPOD TETRA Demo
+ MotoPAD TETRA Demo
+ MotoPOD TRBO
+ MotoPAD TRBO
+ MotoPOD TRBO Demo
+ MotoPAD TRBO Demo
+ Idioma:
+ Seleccione Idioma
+
+
+ ¿Esta seguro que desea salir?
+ Si
+ No
+ Versión
+ e-mail
+ Nuevo Mensaje
+ De
+ Tipo
+
+
+ La conexión TCP no funciona!
+ Nombre de Usuario
+ Clave
+ Entrar
+ Configuración
+ Guardar como Default
+ Cancelar
+ OK
+ Y el puerto de comunicación
+ Bienvenidos a SafeDispatch Mobile!/nDebe configurar la IP en donde el AppServer sea instalado.
+ No puede cargar los usuarios! Por favor verifique su conexión y re empiece.
+ Error de Conexión
+ Obteniendo usuarios de la base de datos…
+
+
+ Mensajería de Texto
+ Mensaje:
+ Seleccione Vehículo
+ Enviando Error
+ Enviar
+ no reconocimiento
+ Barcode content
+ Barcode Scanner nor installed!
+
+
+ Dekey
+ PTT
+ PTT Apagado
+ Emergencia
+ Zone
+ Canal
+ Contactos:
+ IP:
+ 127.0.0.1
+ 192.168.10.40
+ Estado:
+ Tipo de Llamada
+ Llamada a Todos
+ Llamada a Grupo
+ Llamada Privada
+ Seleccione Canal
+ Seleccione Zona
+ Seleccione Grupo
+ ¡Fuera de Línea!
+ En Línea
+ Tiempo de Espera
+
+
+ Nombre
+ Parar
+
+
+ Nombre de Unidad
+ Tipo de Alarma
+ Descripción
+ Fecha y Hora
+
+
+ Puerto de Servidor:
+ Servidor de IP:
+ Guardar
+ Configurar Nombre de Archivo:
+ Cargar
+ Su archivo de configuración no esta o es invalido! Cargando.
+
+
+ Reset
+ Are you sure you want to reset?
+ Reset sent to the controller.
+
+
+
+
+ Mensaje esta siendo enviado…
+ Error al enviar mensaje. ACK (reconocimiento) no recibido
+ Enviando Error
+ Seleccionar Contacto
+ ¡¡¡Emergencia!!!
+ FALLO Emergencia
+ PARO Emergencia
+ FALLO Parada de Emergencia
+ Completada exitosamente la descarga.
+ No pudo cargar el archivo de configuración. Verifique URL e inténtelo nuevamente.
+ ¡Debe reiniciar la aplicación para que los cambios tomen efecto!
+ Las configuraciones guardadas exitosamente.
+ ¡Las configuraciones no pudieron terminarse!
+ Re empezar Aplicación
+ Idea
+ Aquí usted introduce la serie (por ejemplo 037TMA2845) generada después de subir su archivo que fue exportado del CPS de Motorola [Reports->Detailed Reports->Save As]. Usted subirá el archivo a la dirección: www.safemobile.com/uploadCodeplug.
+ Ingles
+ Alemán
+ Turco
+ Rumano
+ Russian
+ Spanish
+
+
+ - Arabic
+ - English
+ - German
+ - Turkish
+ - Romanian
+ - Spanish
+ - Russian
+
+
+ Manual dial...
+ Tether Sound:
+ In order for the changes to take effect please restart RadioPad.
+ Audio Stream:
+ Select Audio Stream
+ External Mic
+ Send Call Type
+ Press PTT for
+ Initiating Call
+ Call Failed
+ PTT Error
+ Ptt was made from external source!
+ New Message from
+ To
+ Audio Source:
+ Select Audio Source
+ Recordings
+ Are you sure you want to delete this recording from database and memory?
+ All recordings will be deleted from database and memory. Continue?
+ Groups:
+ Man Down Event
+ Motionless Event
+ Man Down event has been detected. Are you OK?
+ Motionless event has been detected. Are you OK?
+ Hello world!
+ Settings
+ SetupActivity
+ External Storage
+ Internal Storage
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values-es/strings_activity_settings.xml b/libSafeMobile/src/main/res/values-es/strings_activity_settings.xml
new file mode 100644
index 0000000..bbd1239
--- /dev/null
+++ b/libSafeMobile/src/main/res/values-es/strings_activity_settings.xml
@@ -0,0 +1,103 @@
+
+
+ Settings
+
+
+ SafeBridge Wi-Fi IP
+ 192.168.2.100
+ The IP of SafeBridge wireless network
+
+ SafeBridge Gateway Apps Port
+ 13570
+
+ Config file name
+ serial.xml
+ The name received after uploading the codeplug
+
+ Language
+ en
+
+ Audio Source
+ Audio Source
+
+ Audio Stream
+ Audio Stream
+
+ Tether Sound
+ Allow the sound to be redirected to a bluetooth device
+
+ TRBO station
+ Select whether the station connected to SafeBridge is TRBO (checked) or TETRA (unchecked)
+
+ Text Message Notifications
+ Notifications will be triggered as they normally do
+
+
+ Man Down
+ Send an alarm signal if the device is dropped
+
+ Motionless
+ The device is tipped on its side for a preset perdiod
+
+ 300
+ Time before motionless event
+ The period after which the motionless alarm is sent
+
+ Reset SafeBridge
+ Reset the gateway applications that runs on SafeBridge
+
+ Audio settings
+ SafeBridge Connection Parameters
+ Misc
+ Reset SafeBridge
+
+
+ - UDP
+ - TCP
+
+
+ - UDP
+ - TCP
+
+
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+
+
+ - Arabic
+ - English
+ - Deutsch
+ - Turkish
+ - Romanian
+ - Russian
+ - Spanish
+
+
+ - ar
+ - en
+ - de
+ - tr
+ - ro
+ - ru
+ - es
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values-ro/strings.xml b/libSafeMobile/src/main/res/values-ro/strings.xml
new file mode 100644
index 0000000..ab9df84
--- /dev/null
+++ b/libSafeMobile/src/main/res/values-ro/strings.xml
@@ -0,0 +1,209 @@
+
+
+
+ SafeDispatch Mobile
+ RadioPod
+ RadioPad
+ RadioPod TETRA
+ RadioPad TETRA
+ RadioPod
+ RadioPad
+ RadioPod Demo
+ RadioPad Demo
+ RadioPod TETRA Demo
+ RadioPad TETRA Demo
+ MotoPOD TETRA
+ MotoPAD TETRA
+ MotoPOD TETRA Demo
+ MotoPAD TETRA Demo
+ MotoPOD TRBO
+ MotoPAD TRBO
+ MotoPOD TRBO Demo
+ MotoPAD TRBO Demo
+ Limba:
+ Selectați limba
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiyqDpsOhADJPi+ADVTBDOLY9105U3Z0vtRiZV46J9/0no2V+BcPmfwM5Gf/At+bNwX6P3GSkYmsBxFlaFxis723sR2B18nSQIoUaZrEldS02wUtO/M/Ilh8WyQ7FQYlugAxdXPl8N70Nf29opZ3okQlwM3NRJ7S+VGgE8SztRkCA7DE4cYLDBV01moGvyLZxe0vxGXVHWh2Pso623Gw/gghuONxqYUgt1ThNtLkQDcKG8UdG8N2f0Oc9tW4/624Eat5J+/DoPmzPSwUkohl8lukxzVISGUGaP3C5L1xQX2mdVIjIK3SrKInyDiRW3h7zDdjHtMZ+2OUj7rIDz9WlrQIDAQAB
+
+
+ Sunteți sigur că doriți să ieșiți din program?
+ Da
+ Nu
+ Versiune
+ E-mail
+ Mesaj nou
+ De la
+ Tip
+ Ieșire
+ Delogare
+
+
+ Conexiunea TCP nu functionează!
+ Utilizator
+ Parola
+ Logare
+ Setări
+ Salvați ca implicit
+ Anulați
+ OK
+ și portul pentru comunicație
+ Bun venit! Trebuie să setați IP-ul server-ului unde AppServer Mobile este instalat.
+ Nu se pot încărca utilizatorii! Va rugăm verificați conexiunea și reporniți.
+ Eroare de conexiune
+ Aducerea utilizatorilor din baza de date…
+ Utilizatorul sau Parola sunt necompletate!
+ Autentificare…
+
+
+ Mesaje text
+ Mesaj:
+ Selectati vehiculul
+ Eroare la trimitere
+ Trimitere
+ neconfirmat
+ Codul de bare:
+ Barcode Scanner nu este instalat!
+
+
+ Dekey
+ PTT
+ PTT OFF
+ Urgență
+ Zona
+ Canal
+ Contacte:
+ « Contacte
+ IP:
+ 127.0.0.1
+ 192.168.10.40
+ Stare:
+ Tipul apelului
+ Apel general
+ Apel de grup
+ Apel privat
+ Selectați canalul
+ Selectați zona
+ Selectați grupul
+ Deconectat!
+ Conectat
+ Perioadă de așteptare
+
+
+ Nume
+ Stop
+
+
+ Numele unității
+ Tipul alarmei
+ Descriere
+ Data și ora
+
+
+ Port server:
+ IP server:
+ Salvare
+ Nume fișier configurare:
+ Încarcă
+ Fișierul de configurare lipsește sau este invalid! Se încarca fișierul implicit.
+
+
+ Resetare
+ Sunteți sigur că vreți să resetați Bridge-ul?
+ Comanda de reset a fost trimisă.
+
+
+
+
+ Mesajul se trimite…
+ Eroare la trimitere mesajului. Confirmare neprimită
+ Eroare la trimitere
+ Selectare contact
+ !!! Urgență !!!
+ Nu s-a putut trimite Urgența
+ Urgență oprită
+ Oprire Urgență eșuată
+ Descărcare completă încheiată cu succes.
+ Descarcarea fișierului de configurare a eșuat. Verificați numele și încercați încă o dată.
+ Trebuie să reporniți aplicația pentru ca modificările să aibă efect!
+ Setările au fost salvate cu succes.
+ Setările au eșuat să fie salvate!
+ Repornire aplicație
+ Indiciu
+ Aici veți introduce serialul (ex. 037TMA2845) generat dupa încarcarea fișierului de configurare exportat din Motorola CPS [Reports -> Detailed Reports-> Save As].\nYou will upload the file to the address: www.safemobile.com/uploadCodeplug.
+ Engleză
+ Germană
+ Turcă
+ Română
+ Russian
+ Spanish
+
+
+ - Arabic
+ - Engleză
+ - Germană
+ - Turcă
+ - Română
+ - Rusă
+ - Spaniolă
+
+
+ Formare număr…
+ Tether Sound:
+ Pentru ca modificările să devină active trebuie ca RadioPad-ul să fie restartat.
+ Stream-ul audio:
+ Selectați stream-ul audio
+ Microfon extern
+ Trimite tipul apelului
+ Apasă PTT pentru
+ Inițializare apel
+ Apel eșuat
+ Eroare PTT
+ Apelul a fost efectuat de pe o sursă externă!
+ Mesaj nou de la
+ Către
+ Sursa audio:
+ Selectați sursa audio
+ Înregistrări
+ Are you sure you want to delete this recording from database and memory?
+ All recordings will be deleted from database and memory. Continue?
+ Grupuri:
+ Grupuri »
+ Eveniment \'Om jos\'
+ Eventiment \'Nemișcat\'
+ Eveniment \'om jos\' detectat. Sunteți în regulă?
+ Eveniment \'nemișcat\' detectat. Sunteți în regulă?
+ Hello world!
+ Setări
+ Activitate Setări
+ Memoria Externa
+ Memoria Interna
+ Serviciu TCP
+ Definere Zone și Canale
+ Definere Contacte
+ Versiune Firmware
+ Versiunea dumneavoastră de RadioPad funcționează corect cu versiunea %1$s de Firmware a bridge-ului. Versiunea dumneavoastră curentă este %2$s. Ar trebui să updatați!
+ Apel nedefinit
+ imageContent
+ reține-mă
+ Încărcare înregistrare…
+ Redarea înregistrării a eșuat
+
+
+
+
+
+ Utilizator și/sau parolă greșite!
+ Sunteți conectat pe un bridge cu o versiune veche de firmware. Vă rugăm updatați la ultima versiune!
+ IP SafeBridge
+ Introduceți IP-ul SafeBridge-ului.
+ Serviciul este conectat
+ Serviciul este deconectat
+ Hello
+ Pentru ca sunetul să funcționeze corect trebuie să setați id-ul stației la care este conectat bridge-ul.
+ Radio ID
+ Salvați modificările?
+ Doriți să salvați modificările efectuate?
+ Dispozitivul %1$s este conectat. Redirecționare sunet…
+ Dispozitivul %1$s este deconectat. Oprire direcționare sunet…
+ Dispozitiv găsit
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values-ro/strings_activity_settings.xml b/libSafeMobile/src/main/res/values-ro/strings_activity_settings.xml
new file mode 100644
index 0000000..6a8d597
--- /dev/null
+++ b/libSafeMobile/src/main/res/values-ro/strings_activity_settings.xml
@@ -0,0 +1,121 @@
+
+
+ Settings
+
+
+ SafeBridge Wi-Fi IP
+ 192.168.2.100
+ IP-ul retelei wireless a SafeBridge-ului
+
+ Portul SafeBridge-ului
+ 13570
+
+ Numele fisierului de configurare
+ serial.xml
+ Numele generat dupa uploadarea codeplug-ului
+
+ Limba
+ en
+
+ Sursa audio
+ Sursa audio
+
+ Stream-ul audio
+ Stream-ul audio
+
+ Redirectioneaza sunetul
+ Sunetul va fi redirectionat catre un dispozitiv bluetooth
+
+ Inregistreaza apelurile
+ Permite salvarea apelurile
+
+ Locatia inregistrarilor
+ Selecteaza daca salvarile sunt stocate in memoria telefonului sau pe cardul extern
+
+ Statie TRBO
+ Selecteaza daca statia conectata la SafeBridge este is TRBO (bifat) sau TETRA (debifat)
+
+ Notificari Mesage Text
+ Notificarile vor fi generate in mod normal
+
+
+ Om jos
+ Trimite o alarma daca dispozitivul este scapat
+
+ Inactiv
+ Dispozitivul este lasat nemiscat pentru o perioada prestabilita
+
+ 300
+ Perioada de inactivitate
+ Perioada dupa scurgerea careia se trimite alarma
+
+ 25
+ Nivel pentru Om jos
+ Nivelul minim pentru care se trimite alarma pentru om jos [valori intre 1 si 50]
+
+ Reseteaza SafeBridge
+ Reseteaza aplicatia gateway ce ruleaza pe SafeBridge
+
+ Setari audio
+ Parametrii de conectare la SafeBridge
+ Altele
+ Reseteaza SafeBridge-ul
+
+
+ - UDP
+ - TCP
+
+
+ - UDP
+ - TCP
+
+
+
+ - Memoria interna
+ - Memoria externa
+
+
+ - Internal Storage
+ - External Storage
+
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+
+
+ - Arabic
+ - Engleza
+ - Germana
+ - Turca
+ - Romana
+ - Rusa
+ - Spaniola
+
+
+ - ar
+ - en
+ - de
+ - tr
+ - ro
+ - ru
+ - es
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values-ru/strings.xml b/libSafeMobile/src/main/res/values-ru/strings.xml
new file mode 100644
index 0000000..10bacac
--- /dev/null
+++ b/libSafeMobile/src/main/res/values-ru/strings.xml
@@ -0,0 +1,169 @@
+
+
+
+ SafeDispatch Mobile
+ RadioPod
+ RadioPad
+ RadioPod
+ RadioPad
+ RadioPod Demo
+ RadioPad Demo
+ MotoPOD TETRA
+ MotoPAD TETRA
+ MotoPOD TETRA Demo
+ MotoPAD TETRA Demo
+ MotoPOD TRBO
+ MotoPAD TRBO
+ MotoPOD TRBO Demo
+ MotoPAD TRBO Demo
+ Язык:
+ Select Language
+
+
+ Are you sure you want to exit?
+ Yes
+ No
+ Version
+ e-mail
+ New Message
+ From
+ Type
+
+
+ TCP connection is down!
+ Username
+ Password
+ Login
+ Settings
+ Save as Default
+ Cancel
+ OK
+ And the communication port
+ Welcome to SafeDispatch Mobile!\nYou have to set the IP where the APPServer Mobile is installed.
+ Could not load users! Please check the connection and restart.
+ Connection Error
+ Getting users from database…
+
+
+ Text Messaging
+ Message:
+ Select Vehicle
+ Sending Error
+ Send
+ not ACK
+ Barcode content
+ Barcode Scanner nor installed!
+
+
+ Dekey
+ PTT
+ PTT OFF
+ Emergency
+ Zone
+ Channel
+ Contacts:
+ IP:
+ 127.0.0.1
+ 192.168.10.40
+ Status:
+ Call Type
+ All Call
+ Group Call
+ Private Call
+ Select Channel
+ Select Zone
+ Select Group
+ Offline!
+ Online
+ Hang Time
+
+
+ Name
+ Stop
+
+
+ Unit Name
+ Alarm Type
+ Description
+ Date and Time
+
+
+ Server Port:
+ Server IP:
+ Save
+ Config File Name:
+ Load
+ Your config file is missing or is invalid! Loading default config file.
+
+
+ Reset
+ Are you sure you want to reset?
+ Reset sent to the controller.
+
+
+
+
+ Message is being send…
+ Error on sending message. ACK not received
+ Sending Error
+ Select Contact
+ !!! Emergency !!!
+ Emergency FAILED
+ Emergency STOPED
+ Emergency Stop FAILED
+ Download completed successfully.
+ Failed to download config file. Verify URL and try again.
+ You must restart application for the changes to take effect!
+ Settings saved successfully.
+ Settings failed to complete!
+ Restart Application
+ Hint
+ Here you enter the serial (eg. 037TMA2845) generated after uploading your config file exported from Motorola CPS [Reports->Detailed Reports->Save As]. You will upload the file to the address: www.safemobile.com/uploadCodeplug.
+ English
+ Deutsch
+ Turkish
+ Romanian
+ Russian
+ Spanish
+
+
+ - Arabic
+ - English
+ - German
+ - Turkish
+ - Romanian
+ - Spanish
+ - Russian
+
+
+ Manual dial...
+ Tether Sound:
+ In order for the changes to take effect please restart RadioPad.
+ Audio Stream:
+ Select Audio Stream
+ External Mic
+ Send Call Type
+ Press PTT for
+ Initiating Call
+ Call Failed
+ PTT Error
+ Ptt was made from external source!
+ New Message from
+ To
+ Audio Source:
+ Select Audio Source
+ Recordings
+ Are you sure you want to delete this recording from database and memory?
+ All recordings will be deleted from database and memory. Continue?
+ Groups:
+ Man Down Event
+ Motionless Event
+ Man Down event has been detected. Are you OK?
+ Motionless event has been detected. Are you OK?
+ Hello world!
+ Settings
+ SetupActivity
+ External Storage
+ Internal Storage
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values-ru/strings_activity_settings.xml b/libSafeMobile/src/main/res/values-ru/strings_activity_settings.xml
new file mode 100644
index 0000000..eaf3846
--- /dev/null
+++ b/libSafeMobile/src/main/res/values-ru/strings_activity_settings.xml
@@ -0,0 +1,122 @@
+
+
+ Settings
+
+
+ SafeBridge Wi-Fi IP
+ 192.168.2.100
+ The IP of SafeBridge wireless network
+
+ SafeBridge Gateway Apps Port
+ 13570
+
+ Config file name
+ serial.xml
+ The name received after uploading the codeplug
+
+ Language
+ en
+
+ Audio Source
+ Audio Source
+
+ Audio Stream
+ Audio Stream
+
+ Tether Sound
+ Allow the sound to be redirected to a bluetooth device
+
+ Record calls
+ Allow that all calls to be saved
+
+ Recordings location
+ Select if recordings are saved on the internal or external storage
+
+ TRBO station
+ Select whether the station connected to SafeBridge is TRBO (checked) or TETRA (unchecked)
+
+ Text Message Notifications
+ Notifications will be triggered as they normally do
+
+
+ Man Down
+ Send an alarm signal if the device is dropped
+
+ Motionless
+ The device is tipped on its side for a preset perdiod
+
+ 300
+ Time before motionless event
+ The period after which the motionless alarm is sent (seconds)
+
+ 25
+ ManDown Threshold
+ ManDown threshold after which the alarm is sent[values from 1 to 50]
+
+ Reset SafeBridge
+ Reset the gateway applications that runs on SafeBridge
+
+ Audio settings
+ SafeBridge Connection Parameters
+ Misc
+ Reset SafeBridge
+
+
+ - UDP
+ - TCP
+
+
+ - UDP
+ - TCP
+
+
+
+ - Internal Storage
+ - External Storage
+
+
+ - Internal Storage
+ - External Storage
+
+
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+
+
+ - Arabic
+ - English
+ - Deutsch
+ - Turkish
+ - Romanian
+ - Russian
+ - Spanish
+
+
+ - ar
+ - en
+ - de
+ - tr
+ - ro
+ - ru
+ - es
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values-tr/strings.xml b/libSafeMobile/src/main/res/values-tr/strings.xml
new file mode 100644
index 0000000..aac4449
--- /dev/null
+++ b/libSafeMobile/src/main/res/values-tr/strings.xml
@@ -0,0 +1,169 @@
+
+
+
+ SafeDispatch Mobile
+ RadioPod
+ RadioPad
+ RadioPod
+ RadioPad
+ RadioPod Demo
+ RadioPad Demo
+ MotoPOD TETRA
+ MotoPAD TETRA
+ MotoPOD TETRA Demo
+ MotoPAD TETRA Demo
+ MotoPOD TRBO
+ MotoPAD TRBO
+ MotoPOD TRBO Demo
+ MotoPAD TRBO Demo
+ Dil
+ Dil seçiniz
+
+
+ Çıkmak istediğinize emin misiniz?
+ Evet
+ Hayır
+ Versiyon
+ e-mail
+ Yeni mesaj
+ Kimden
+ Tip
+
+
+ Tcp bağlantısı yok!
+ Kullanıcı adı
+ Şifre
+ Giriş yap
+ Ayarlar
+ Varsayılan olarak kaydet
+ İptal
+ Tamam
+ ve iletişim portu
+ SafeDispatch Mobile\'e hoşgeldiniz!\nAPPServer Mobile\'in kurulmuş olduğu cihazın IP adresini ayarlamanız gerekiyor.
+ Hepsini göster
+ Bağlantı hatası
+ Veri tabanından kullanıcıları yüklüyor…
+
+
+ Metin mesajlaşması
+ Mesaj:
+ Araç seç
+ Gönderme hatası
+ Gönder
+ ACK yok
+ Barcode content
+ Barcode Scanner nor installed!
+
+
+ Dekey
+ PTT
+ PTT kapalı
+ Acil
+ Bölge
+ Kanal
+ İrtibatlar:
+ IP:
+ 127.0.0.1
+ 192.168.10.40
+ Durum:
+ Arama tipi
+ Bütün aramalar
+ Grup aramaları
+ Özel aramalar
+ Kanal seçimi
+ Bölge seçimi
+ Grup seçimi
+ Çevrimdışı!
+ Çevrimiçi
+ Askıda kalma zamanı
+
+
+ ad
+ dur
+
+
+ Unite adı
+ alarm tipi
+ tanımlama
+ gün ve zaman
+
+
+ Sunucu portu:
+ Sunucu IP\'si:
+ Kaydet
+ Yapılandırma dosya adı:
+ Yük
+ Config dosyanız kayıp veya geçersiz! Varolan Config dosyası yükleniyor.
+
+
+ Reset
+ Are you sure you want to reset?
+ Reset sent to the controller.
+
+
+
+
+ Mesaj gönderildi…
+ Mesaj göndermede hata. Onay alınmadı
+ Gönderme hatası
+ İrtibat seçiniz
+ !!! Acil Durum !!!
+ Acil durum hatası
+ Acil durum bitti
+ Acil durum bitme hatası
+ İndirme başarı ile tamamlandı.
+ Config dosyası indirmede hata. URL adresini onaylayın ve tekrar deneyin.
+ Değişikliklerin uygulanabilmesi için uygulamayı yeniden başlatınız!
+ Ayarlar başarı ile kaydedilmiştir.
+ Ayarların kaydedilmesinde hata oluştu!
+ Uygulamayı yeniden başlatın
+ İpucu
+ Config dosyasını yükledikten sonra üretilen Motorola CPS\'den aldığınız [ Raporlar-> Detaylı raporlar-> Farklı Kaydet ] seri numarasını giriniz (ör. 037TMA2845). Dosyayı www.safemobile.com/uploadCodeplug adresine yükleyebilirsiniz.
+ İngilizce
+ Almanca
+ Türkçe
+ Romence
+ Russian
+ Spanish
+
+
+ - Arabic
+ - English
+ - German
+ - Turkish
+ - Romanian
+ - Spanish
+ - Russian
+
+
+ Manual dial...
+ Tether Sound:
+ In order for the changes to take effect please restart RadioPad.
+ Audio Stream:
+ Select Audio Stream
+ External Mic
+ Send Call Type
+ Press PTT for
+ Initiating Call
+ Call Failed
+ PTT Error
+ Ptt was made from external source!
+ New Message from
+ To
+ Audio Source:
+ Select Audio Source
+ Recordings
+ Are you sure you want to delete this recording from database and memory?
+ All recordings will be deleted from database and memory. Continue?
+ Groups:
+ Man Down Event
+ Motionless Event
+ Man Down event has been detected. Are you OK?
+ Motionless event has been detected. Are you OK?
+ Hello world!
+ Settings
+ SetupActivity
+ External Storage
+ Internal Storage
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values-tr/strings_activity_settings.xml b/libSafeMobile/src/main/res/values-tr/strings_activity_settings.xml
new file mode 100644
index 0000000..eaf3846
--- /dev/null
+++ b/libSafeMobile/src/main/res/values-tr/strings_activity_settings.xml
@@ -0,0 +1,122 @@
+
+
+ Settings
+
+
+ SafeBridge Wi-Fi IP
+ 192.168.2.100
+ The IP of SafeBridge wireless network
+
+ SafeBridge Gateway Apps Port
+ 13570
+
+ Config file name
+ serial.xml
+ The name received after uploading the codeplug
+
+ Language
+ en
+
+ Audio Source
+ Audio Source
+
+ Audio Stream
+ Audio Stream
+
+ Tether Sound
+ Allow the sound to be redirected to a bluetooth device
+
+ Record calls
+ Allow that all calls to be saved
+
+ Recordings location
+ Select if recordings are saved on the internal or external storage
+
+ TRBO station
+ Select whether the station connected to SafeBridge is TRBO (checked) or TETRA (unchecked)
+
+ Text Message Notifications
+ Notifications will be triggered as they normally do
+
+
+ Man Down
+ Send an alarm signal if the device is dropped
+
+ Motionless
+ The device is tipped on its side for a preset perdiod
+
+ 300
+ Time before motionless event
+ The period after which the motionless alarm is sent (seconds)
+
+ 25
+ ManDown Threshold
+ ManDown threshold after which the alarm is sent[values from 1 to 50]
+
+ Reset SafeBridge
+ Reset the gateway applications that runs on SafeBridge
+
+ Audio settings
+ SafeBridge Connection Parameters
+ Misc
+ Reset SafeBridge
+
+
+ - UDP
+ - TCP
+
+
+ - UDP
+ - TCP
+
+
+
+ - Internal Storage
+ - External Storage
+
+
+ - Internal Storage
+ - External Storage
+
+
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+
+
+ - Arabic
+ - English
+ - Deutsch
+ - Turkish
+ - Romanian
+ - Russian
+ - Spanish
+
+
+ - ar
+ - en
+ - de
+ - tr
+ - ro
+ - ru
+ - es
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values/attrs.xml b/libSafeMobile/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..6e92ab8
--- /dev/null
+++ b/libSafeMobile/src/main/res/values/attrs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values/strings.xml b/libSafeMobile/src/main/res/values/strings.xml
new file mode 100644
index 0000000..b693959
--- /dev/null
+++ b/libSafeMobile/src/main/res/values/strings.xml
@@ -0,0 +1,321 @@
+
+
+
+ SafeDispatch Mobile
+ RadioPod
+ RadioPad
+ RadioPod TETRA
+ RadioPad TETRA
+ RadioPod SEPURA
+ RadioPad SEPURA
+ RadioPod
+ RadioPad
+ RadioPod Demo
+ RadioPad Demo
+ RadioPod TETRA Demo
+ RadioPad TETRA Demo
+ RadioPod SEPURA Demo
+ RadioPad SEPURA Demo
+ MotoPOD TETRA
+ MotoPAD TETRA
+ MotoPOD TETRA Demo
+ MotoPAD TETRA Demo
+ MotoPOD TRBO
+ MotoPAD TRBO
+ MotoPOD TRBO Demo
+ MotoPAD TRBO Demo
+ Language:
+ Select Language
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiyqDpsOhADJPi+ADVTBDOLY9105U3Z0vtRiZV46J9/0no2V+BcPmfwM5Gf/At+bNwX6P3GSkYmsBxFlaFxis723sR2B18nSQIoUaZrEldS02wUtO/M/Ilh8WyQ7FQYlugAxdXPl8N70Nf29opZ3okQlwM3NRJ7S+VGgE8SztRkCA7DE4cYLDBV01moGvyLZxe0vxGXVHWh2Pso623Gw/gghuONxqYUgt1ThNtLkQDcKG8UdG8N2f0Oc9tW4/624Eat5J+/DoPmzPSwUkohl8lukxzVISGUGaP3C5L1xQX2mdVIjIK3SrKInyDiRW3h7zDdjHtMZ+2OUj7rIDz9WlrQIDAQAB
+
+
+ Are you sure you want to exit?
+ Yes
+ No
+ Version
+ e-mail
+ New Message
+ From
+ Type
+ Exit
+ Logout
+
+
+ TCP connection is down!
+ Username
+ Password
+ Login
+ Settings
+ Save as Default
+ Cancel
+ OK
+ And the communication port
+ Welcome to SafeDispatch Mobile!\nYou have to set the IP where the APPServer Mobile is installed.
+ Could not load users! Please check the connection and restart.
+ Connection Error
+ Getting users from database…
+ Password or Username are empty!
+ Authenticating…
+
+
+ Text Messaging
+ Message:
+ Select Vehicle
+ Sending Error
+ Send
+ not ACK
+ Barcode content
+ Barcode Scanner nor installed!
+
+
+ DeKey
+ PTT
+ PTT OFF
+ Emergency
+ Zone
+ Channel
+ Contacts
+ « Contacts
+ IP:
+ 127.0.0.1
+ 192.168.10.40
+ Status:
+ Call Type
+ All Call
+ Group Call
+ Private Call
+ Select Channel
+ Select Zone
+ Select Group
+ Offline!
+ Online
+ Hang Time
+
+
+ Name
+ Stop
+
+
+ Unit Name
+ Alarm Type
+ Description
+ Date and Time
+
+
+ Server Port:
+ Server IP:
+ Save
+ Config File Name:
+ Load
+ Your config file is missing or is invalid! Loading default config file.
+
+
+ Reset
+ Are you sure you want to reset?
+ Reset sent to the controller.
+
+
+
+
+ Message is being send…
+ Error on sending message. ACK not received
+ Sending Error
+ Select Contact
+ !!! Emg !!!
+ Emg FAILED
+ Emg STOPED
+ Emg Stop FAILED
+ Download completed successfully.
+ Failed to download config file. Verify URL and try again.
+ You must restart application for the changes to take effect!
+ Settings saved successfully.
+ Settings failed to complete!
+ Restart Application
+ Hint
+ Here you enter the serial (eg. 038TJQ5277.xml) generated after uploading your config file exported from Motorola CPS [Reports->Detailed Reports->Save As]. You will upload the file to the address: www.safemobile.com/uploadCodeplug.
+ Arabic
+ English
+ Deutsch
+ Turkish
+ Romanian
+ Russian
+ Spanish
+
+
+ - Arabic
+ - English
+ - Deutsch
+ - Turkish
+ - Romanian
+ - Russian
+ - Spanish
+
+
+ Manual dial...
+ Tether Sound:
+ In order for the changes to take effect please restart RadioPad.
+ Audio Stream:
+ Select Audio Stream
+ External Mic
+ Send Call Type
+ Press PTT for
+ Initiating Call
+ Call Failed
+ PTT Error
+ Ptt was made from external source!
+ New Message from
+ To
+ Audio Source:
+ Select Audio Source
+ Recordings
+ Are you sure you want to delete this recording from database and memory?
+ All recordings will be deleted from database and memory. Continue?
+ Groups:
+ Groups »
+ Man Down Event
+ Motionless Event
+ Man Down event has been detected. Are you OK?
+ Motionless event has been detected. Are you OK?
+ Hello world!
+ Settings
+ SetupActivity
+ External Storage
+ Internal Storage
+ TCP Service
+ Define Zone and Channels
+ Define Contacts
+ Firmware Version
+ Your RadioPad version will work properly with SafeBridge Firmware %1$s version. Your current version is %2$s. You should update it!
+ Undefined Call
+ imageContent
+ remember me
+ Loading Recording…
+ Failed Playing Recording
+
+
+
+
+
+ Invalid username or password!
+ You are on an old bridge firmware version. Please update to the last release!
+ SafeBridge\'s IP
+ Enter the IP of the SafeBridge.
+ Service is connected
+ Service is disconnected
+ Welcome to
+ In order for the sound to function properly you have to set the radio ID of the Main Station
+ Radio ID
+ Save changes?
+ Do you want to save the changes that you have made?
+ Device is now connected: %1$s. Tethering sound…
+ Device is now disconnected: %1$s. Stopping tethering…
+ Device found
+
+
+ Zone and Channel
+ Call In Progress
+ Incomming Call
+ Radio ID values must be between 1 and 16777215!
+ Base Station ID
+
+
+ Message
+ Radio
+ Record…
+ Settings
+ About
+ Connecting to printer…
+ Printer connected
+ Could not connect to the Printer. Check if printer is connected!
+ Dial Group…
+ Dial Private…
+
+
+ Loading more recordings…
+ Loading more text messages…
+ PTT Info
+ Loading recordings…
+ User already logged in!
+ Port must be between 1 and 65535!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AbstractMapsActivity
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values/strings_activity_settings.xml b/libSafeMobile/src/main/res/values/strings_activity_settings.xml
new file mode 100644
index 0000000..ad302fd
--- /dev/null
+++ b/libSafeMobile/src/main/res/values/strings_activity_settings.xml
@@ -0,0 +1,166 @@
+
+
+ Settings
+
+
+ SafeBridge Wi-Fi IP
+ 192.168.2.100
+ The IP of SafeBridge wireless network
+
+ SafeBridge Gateway Apps Port
+ 13570
+
+ Config file name
+ serial.xml
+ The name received after uploading the codeplug
+
+ Language
+ en
+
+ Audio Source
+ Audio Source
+
+ Audio Stream
+ Audio Stream
+
+ External Microphone
+ Set if an external mic will be used (eg.: for What-a-Pair system)
+
+ Tether Sound
+ Allow the sound to be redirected to a bluetooth device
+
+ Record calls
+ Allow that all calls to be saved
+
+ Recordings location
+ Select if recordings are saved on the internal or external storage
+
+ TRBO station
+ Select whether the station connected to SafeBridge is TRBO (checked) or TETRA (unchecked)
+
+ Text Message Notifications
+ Notifications will be triggered as they normally do
+
+ Man Down
+ Send an alarm signal if the device is dropped
+
+ Motionless
+ The device is tipped on its side for a preset perdiod
+
+ 300
+ Time before motionless event
+ The period after which the motionless alarm is sent (seconds)
+
+ 25
+ ManDown Threshold
+ ManDown threshold after which the alarm is sent[values from 1 to 50]
+
+ Reset SafeBridge
+ Reset the gateway applications that runs on SafeBridge
+
+ Audio settings
+ Radio configuration
+ SafeBridge Connection Parameters
+ Misc
+ Reset SafeBridge
+
+
+ Printer and MSR
+ Allow the Printer and the MSR to be active
+
+
+
+ Radio ID
+ 100
+ The ID of the radio on which the SafeBridge is connected
+
+ Define/Edit Contacts
+
+ Add, edit, remove contacts
+
+
+
+ Text and Recordings Update Size
+ Set the size of text messages and recordings which will be loaded when scrolling to the beegining of the list
+
+
+
+
+ - UDP
+ - TCP
+
+
+ - UDP
+ - TCP
+
+
+
+ - Internal Storage
+ - External Storage
+
+
+ - Internal Storage
+ - External Storage
+
+
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+ - ALARM
+ - DTMF
+ - MUSIC
+ - NOTIFICATION
+ - RING
+ - SYSTEM
+ - VOICE CALL
+
+
+
+
+ - Arabic
+ - English
+ - Deutsch
+ - Turkish
+ - Romanian
+ - Russian
+ - Spanish
+
+
+ - ar
+ - en
+ - de
+ - tr
+ - ro
+ - ru
+ - es
+
+
+
+
+ - 10
+ - 20
+ - 30
+ - 40
+ - 50
+ - 100
+ - 200
+
+
+ - 10
+ - 20
+ - 30
+ - 40
+ - 50
+ - 100
+ - 200
+
+
+
\ No newline at end of file
diff --git a/libSafeMobile/src/main/res/values/styles.xml b/libSafeMobile/src/main/res/values/styles.xml
new file mode 100644
index 0000000..4a10ca4
--- /dev/null
+++ b/libSafeMobile/src/main/res/values/styles.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libs/android-support-v4.jar b/libs/android-support-v4.jar
deleted file mode 100644
index 187bdf4..0000000
Binary files a/libs/android-support-v4.jar and /dev/null differ
diff --git a/proguard.cfg b/proguard.cfg
deleted file mode 100644
index 4f8e2c3..0000000
--- a/proguard.cfg
+++ /dev/null
@@ -1,57 +0,0 @@
--optimizationpasses 5
--dontusemixedcaseclassnames
--dontskipnonpubliclibraryclasses
--dontpreverify
--verbose
--optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-
--keep public class * extends android.app.Activity
--keep public class * extends android.app.Application
--keep public class * extends android.app.Service
--keep public class * extends android.content.BroadcastReceiver
--keep public class * extends android.content.ContentProvider
--keep public class * extends android.app.backup.BackupAgentHelper
--keep public class * extends android.preference.Preference
--keep public class com.android.vending.licensing.ILicensingService
-
--keepclasseswithmembernames class * {
- native ;
-}
-
--keepclasseswithmembers class * {
- public (android.content.Context, android.util.AttributeSet);
-}
-
--keepclasseswithmembers class * {
- public (android.content.Context, android.util.AttributeSet, int);
-}
-
--keepclassmembers class * extends android.app.Activity {
- public void *(android.view.View);
-}
-
--keepclassmembers enum * {
- public static **[] values();
- public static ** valueOf(java.lang.String);
-}
-
--keep class * implements android.os.Parcelable {
- public static final android.os.Parcelable$Creator *;
-}
-
--keep class * extends java.util.ListResourceBundle {
- protected Object[][] getContents();
-}
-
--keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
- public static final *** NULL;
-}
-
--keepnames @com.google.android.gms.common.annotation.KeepName class *
--keepclassmembernames class * {
- @ccom.google.android.gms.common.annotation.KeepName *;
-}
-
--keepnames class * implements android.os.Parcelable {
- public static final ** CREATOR;
-}
diff --git a/project.properties b/project.properties
deleted file mode 100644
index 7c092e4..0000000
--- a/project.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=Google Inc.:Google APIs:18
-
-android.library.reference.1=..\\LibSafeMobile
-android.library.reference.2=../LibGooglePlayServices
diff --git a/res/drawable-hdpi/ic_launcher.png b/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index 8074c4c..0000000
Binary files a/res/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/res/drawable-hdpi/textbox.9.png b/res/drawable-hdpi/textbox.9.png
deleted file mode 100644
index 32f0f20..0000000
Binary files a/res/drawable-hdpi/textbox.9.png and /dev/null differ
diff --git a/res/layout-large/tablive.xml b/res/layout-large/tablive.xml
deleted file mode 100644
index e4270ff..0000000
--- a/res/layout-large/tablive.xml
+++ /dev/null
@@ -1,246 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/layout/tablive.xml b/res/layout/tablive.xml
deleted file mode 100644
index 23f9746..0000000
--- a/res/layout/tablive.xml
+++ /dev/null
@@ -1,243 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
deleted file mode 100644
index d0304b2..0000000
--- a/res/values/strings.xml
+++ /dev/null
@@ -1,245 +0,0 @@
-
-
-
- SafeMobile Dispatch
- SafeMobile Dispatch Demo
- RadioPod
- RadioPad
- RadioPod
- RadioPad
- RadioPod Demo
- RadioPad Demo
-
-
- AIzaSyANbpEqXiYL6aKawYO0gjkkAHWpZT4Gb8s
- AIzaSyBJx0dvuoAnWD0dpwjtFljRltU5c85ih20
-
-
- 0LoK1PwpD1-ZVnfSkXoirZJ5eYRYss3tM9b2Abw
- 0rur5ag6QXrW51ii-CwqK5G-XSwdAe1wPTZDCeg
- 0LoK1PwpD1-ZVnfSkXoirZJ5eYRYss3tM9b2Abw
- 0LoK1PwpD1-YhGHazIDazDll3hkm-ReytXVny6A
- Select Username
- Language:
- Select Language
-
- - Channel1
- - Channel2
- - Ch3
-
-
- - Zone1
- - Zone2
-
-
-
- Are you sure you want to exit?
- Yes
- Exit
- Logout
- No
- Version
- e-mail
- New Message
- New Alarm
- Poll Reply
- From
- Type
-
-
- TCP connection is down!
- Username
- Password
- Login
- Settings
- Save as Default
- Cancel
- OK
- And the communication port
- Welcome to SafeDispatch Mobile!\nYou have to set the IP where the APPServer Mobile is installed.
- Could not load users! Please check the connection and restart.
- Connection Error
- Getting users from database…
- AppServer IP:PORT
- Enter the IP:PORT combination for the AppServer Mobile.
-
-
-
- Live
- Display All
- Hide All
- Enable
- Disable
- Poll
- Speed
- Time
- Options
- Getting vehicles from database…
-
-
- History
- Vehicle
- Start Date
- End Date
- Display
- Positions
- Results for
- start
- end
- Data Error
- Address
- Unable to display more the 2000 points, please select smaller interval
- Info data
- End date has to be greater than start date
- You don\'t have data for [x] on interval
- You have [x] points please wait until all points will be on the map
- Loading history from database…
-
-
- Text Messaging
- Message:
- Select Vehicle
- Sending Error
- Send
- not ACK
- Barcode content
- Barcode Scanner nor installed!
-
-
- Dekey
- PTT
- PTT OFF
- Emergency
- Zone
- Channel
- Contacts:
- IP:
- port
- ip
- 127.0.0.1
- 192.168.10.40
- Status:
- Call Type
- All Call
- Group Call
- Private Call
- Select Channel
- Select Zone
- Select Group
- Offline!
- Online
- Hang Time
-
-
- Name
- Stop
-
-
- Alarms
- Unit Name
- Alarm Type
- Description
- Date and Time
-
-
- Server Port:
- Server IP:
- Save
- Config File Name:
- Load
- Your config file is missing or is invalid! Loading default config file.
-
-
-
-
- Message is being send…
- Error on sending message. ACK not received
- Sending Error
- Select Contact
- !!! Emergency !!!
- Emergency FAILED
- Emergency STOPED
- Emergency Stop FAILED
-
-
- Download completed successfully.
- Failed to download config file. Verify URL and try again.
- You must restart application for the changes to take effect!
- Settings saved successfully.
- Settings failed to complete!
- Restart Application
- Hint
- Here you enter the serial (eg. 037TMA2845) generated after uploading your config file exported from Motorola CPS [Reports->Detailed Reports->Save As]. You will upload the file to the address: www.safemobile.com/uploadCodeplug.
-
- English
- Deutsch
- Turkish
- Romanian
- Russian
- Spanish
-
-
-
-
-
-
-
-
- - English
- - German
- - Romanian
-
-
\ No newline at end of file
diff --git a/safeDispatch/build.gradle b/safeDispatch/build.gradle
new file mode 100644
index 0000000..216ff1d
--- /dev/null
+++ b/safeDispatch/build.gradle
@@ -0,0 +1,54 @@
+apply plugin: 'com.android.application'
+apply plugin: 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
+
+android {
+ compileSdkVersion 31
+ buildToolsVersion "31.0.0"
+
+ defaultConfig {
+ applicationId "com.safemobile.dispatch"
+ minSdkVersion 21
+ targetSdkVersion 31
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
+ }
+ }
+ buildFeatures {
+ viewBinding false
+ }
+}
+dependencies {
+ implementation project(':libSafeMobile')
+
+ // support libraries
+ implementation 'androidx.appcompat:appcompat:1.4.1'
+ implementation 'com.google.android.material:material:1.5.0'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'androidx.appcompat:appcompat:1.4.1'
+ implementation 'androidx.recyclerview:recyclerview:1.2.1'
+ implementation 'androidx.media:media:1.5.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
+ implementation 'com.google.android.gms:play-services-auth:20.1.0'
+
+ // Fused location provider with and without google services
+ implementation 'com.google.android.gms:play-services-location:19.0.1'
+
+ // Google maps library
+ implementation 'com.google.android.gms:play-services-maps:18.0.2'
+
+ // define a BOM and its version
+ implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.3"))
+
+ // define any required OkHttp artifacts without version
+ implementation("com.squareup.okhttp3:okhttp")
+ implementation("com.squareup.okhttp3:logging-interceptor")
+
+ // add Gson
+ implementation 'com.google.code.gson:gson:2.8.6'
+
+ //retrofit
+}
diff --git a/lint.xml b/safeDispatch/lint.xml
similarity index 99%
rename from lint.xml
rename to safeDispatch/lint.xml
index 2c3a301..40f7ae7 100644
--- a/lint.xml
+++ b/safeDispatch/lint.xml
@@ -1,4 +1,4 @@
-
+
diff --git a/safeDispatch/src/main/AndroidManifest.xml b/safeDispatch/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..6489df7
--- /dev/null
+++ b/safeDispatch/src/main/AndroidManifest.xml
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/Sketch_Block.ttf b/safeDispatch/src/main/assets/Sketch_Block.ttf
similarity index 100%
rename from assets/Sketch_Block.ttf
rename to safeDispatch/src/main/assets/Sketch_Block.ttf
diff --git a/assets/demo_positions.txt b/safeDispatch/src/main/assets/demo_positions.txt
similarity index 100%
rename from assets/demo_positions.txt
rename to safeDispatch/src/main/assets/demo_positions.txt
diff --git a/assets/exitwindows.mp3 b/safeDispatch/src/main/assets/exitwindows.mp3
similarity index 100%
rename from assets/exitwindows.mp3
rename to safeDispatch/src/main/assets/exitwindows.mp3
diff --git a/assets/grenade.mp3 b/safeDispatch/src/main/assets/grenade.mp3
similarity index 100%
rename from assets/grenade.mp3
rename to safeDispatch/src/main/assets/grenade.mp3
diff --git a/assets/mike.mp3 b/safeDispatch/src/main/assets/mike.mp3
similarity index 100%
rename from assets/mike.mp3
rename to safeDispatch/src/main/assets/mike.mp3
diff --git a/assets/mikee.mp3 b/safeDispatch/src/main/assets/mikee.mp3
similarity index 100%
rename from assets/mikee.mp3
rename to safeDispatch/src/main/assets/mikee.mp3
diff --git a/assets/startwindows.mp3 b/safeDispatch/src/main/assets/startwindows.mp3
similarity index 100%
rename from assets/startwindows.mp3
rename to safeDispatch/src/main/assets/startwindows.mp3
diff --git a/assets/xmldmr.xml b/safeDispatch/src/main/assets/xmldmr.xml
similarity index 100%
rename from assets/xmldmr.xml
rename to safeDispatch/src/main/assets/xmldmr.xml
diff --git a/src/com/safemobile/dispatch_demo/AlarmActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/AlarmActivity.java
similarity index 98%
rename from src/com/safemobile/dispatch_demo/AlarmActivity.java
rename to safeDispatch/src/main/java/com/safemobile/dispatch/AlarmActivity.java
index ed2b764..d33dc87 100644
--- a/src/com/safemobile/dispatch_demo/AlarmActivity.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/AlarmActivity.java
@@ -1,13 +1,9 @@
-package com.safemobile.dispatch_demo;
+package com.safemobile.dispatch;
import java.util.ArrayList;
import java.util.Locale;
/** fix import*/
-import com.safemobile.dispatch.*;
-import com.safemobile.dispatch_demo.*;
-
-
import com.safemobile.adapters.AlertGridViewAdapter;
import com.safemobile.adapters.AlertGridViewAdapter.ViewHolder;
@@ -61,7 +57,7 @@ public class AlarmActivity extends Activity {
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
- getBaseContext().getResources().updateConfiguration(config,
+ getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
diff --git a/safeDispatch/src/main/java/com/safemobile/dispatch/HistoryActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/HistoryActivity.java
new file mode 100644
index 0000000..87de241
--- /dev/null
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/HistoryActivity.java
@@ -0,0 +1,35 @@
+package com.safemobile.dispatch;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import android.os.Bundle;
+
+import com.safemobile.lib.SM;
+
+public class HistoryActivity extends AppCompatActivity {
+
+ public Bundle savedInstanceState;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ this.savedInstanceState = savedInstanceState;
+ setContentView(R.layout.tabhistory);
+ }
+
+ public void UpdateMap() {
+ SM.Debug("Do the updateMAP post");
+ }
+
+ public void UpdateUnableDisp() {
+ SM.Debug("Do Cancelwindow");
+ }
+
+ public void UpdateCancel() {
+ SM.Debug("Do Cancelwindow");
+ }
+
+ public void UpdateNrPos(int size) {
+ SM.Debug("Do Cancelwindow");
+ }
+}
\ No newline at end of file
diff --git a/src/com/safemobile/dispatch_demo/IconContextMenu.java b/safeDispatch/src/main/java/com/safemobile/dispatch/IconContextMenu.java
similarity index 99%
rename from src/com/safemobile/dispatch_demo/IconContextMenu.java
rename to safeDispatch/src/main/java/com/safemobile/dispatch/IconContextMenu.java
index 3c1ec09..22fb898 100644
--- a/src/com/safemobile/dispatch_demo/IconContextMenu.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/IconContextMenu.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.safemobile.dispatch_demo;
+package com.safemobile.dispatch;
import java.util.ArrayList;
diff --git a/safeDispatch/src/main/java/com/safemobile/dispatch/LiveActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/LiveActivity.java
new file mode 100644
index 0000000..ebbfdc1
--- /dev/null
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/LiveActivity.java
@@ -0,0 +1,726 @@
+package com.safemobile.dispatch;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.View;
+import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.GridView;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+
+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.MarkerOptions;
+import com.safemobile.activities.AbstractLiveActivity;
+import com.safemobile.activities.AbstractSDParentActivity;
+import com.safemobile.adapters.VehiclesGridViewAdapter;
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.OperationCodes;
+import com.safemobile.lib.SM;
+import com.safemobile.lib.SuperVehicle;
+import com.safemobile.lib.Vehicle;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Objects;
+
+public class LiveActivity extends AbstractLiveActivity implements OnMapReadyCallback {
+
+ private GoogleMap googleMap;
+
+ /* Context Menu */
+ private static final int MENU_ENABLE = 150;
+ private static final int MENU_DISABLE = 151;
+ private static final int MENU_REMOTE = 161;
+ private static final int MENU_POLL = 154;
+ private static final double LAT_OUTLIMIT = 91;
+ private static final double LNG_OUTLIMIT = 181;
+ private IconContextMenu iconContextMenu = null;
+
+ /* Dialog */
+ private Dialog loadingDialog;
+
+ // Need handler for callbacks to the UI thread
+ private final Handler myHandler = new Handler(Looper.getMainLooper());
+ private Thread threadUI;
+
+ /* Misc */
+ private Context context;
+ private Resources res;
+ private Activity activity;
+
+ /* Visual Elements */
+ private ImageButton imageViewCheckAll;
+ private Button displayButton;
+ private boolean isFirstRun = true;
+ private boolean isFirstMap = true;
+ private boolean isAck = false;
+ private boolean showVehicle = true;
+ private int contextMenuPosition;
+ private int vehStatus;
+ private int position; // vehStatus = vehicle status received from apps
+
+ /* Live Vehicle GridView */
+ private GridView gridVehicle;
+ private ArrayList liveVehicle = new ArrayList<>();
+ private ArrayList displayedVehicles = new ArrayList<>();
+ private ArrayList disabledVehicles = new ArrayList<>();
+ private VehiclesGridViewAdapter adapter;
+ private final HashMap> tableHashOverlay = new HashMap<>();
+
+ //value poll
+ private double latPoll = 0;
+ private double lngPoll = 0;
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ this.setSavedInstanceState(savedInstanceState);
+ // get parentTab
+ setParentTab((AbstractSDParentActivity) getParent());
+ try {
+ ((TabLayoutActivity) getParentTab()).liveActivity = this;
+ } catch (Exception ignored) {
+ // ignored
+ }
+ context = this;
+ activity = this;
+ res = getResources();
+
+ Locale locale = new Locale(AppParams.LANGUAGETMP);
+ Locale.setDefault(locale);
+ Configuration config = new Configuration();
+ config.locale = locale;
+ getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
+
+ // get mapView only when creating first time
+ if (isFirstMap) {
+ setContentView(R.layout.tablive);
+ isFirstMap = false;
+ }
+
+ // Obtain the SupportMapFragment and get notified when the map is ready to be used.
+ SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
+ .findFragmentById(R.id.map);
+ if (mapFragment != null) {
+ mapFragment.getMapAsync(this);
+ }
+
+
+ // create on vehicle long click menu
+ createIconContextMenu();
+
+ // image View for changing map type satellite or map
+ ImageView changeMapTypeImageView = (ImageView) findViewById(R.id.changeMapType);
+ changeMapTypeImageView.setOnClickListener(v -> {
+ if (googleMap.getMapType() == GoogleMap.MAP_TYPE_SATELLITE) {
+ changeMapTypeImageView.setImageResource(R.drawable.satellite);
+ googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
+ } else {
+ changeMapTypeImageView.setImageResource(R.drawable.map);
+ googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
+ }
+ });
+
+ ImageView changeTrafficImageView = (ImageView) findViewById(R.id.changeTraffic);
+ changeTrafficImageView.setOnClickListener(v -> {
+ if (googleMap.isTrafficEnabled()) {
+ changeTrafficImageView.setImageResource(R.drawable.traffic_off);
+ googleMap.setTrafficEnabled(false);
+ } else {
+ changeTrafficImageView.setImageResource(R.drawable.traffic);
+ googleMap.setTrafficEnabled(true);
+ }
+ });
+
+ // change tab header font
+ TextView textView1 = (TextView) findViewById(R.id.textView1);
+ textView1.setTypeface(Typeface.createFromAsset(getAssets(), "Sketch_Block.ttf"));
+ textView1.setTextSize(24);
+
+ // get grid view and set empty data adapter
+ gridVehicle = (GridView) findViewById(R.id.gridVehicle);
+
+ if (AppParams.DEMO) {
+ disabledVehicles = new ArrayList<>();
+ for (Vehicle veh : getParentTab().allVehicle)
+ disabledVehicles.add(!veh.status);
+ }
+
+
+ adapter = new VehiclesGridViewAdapter(activity, context, getParentTab().allVehicle, disabledVehicles);
+ adapter.notifyDataSetChanged();
+ gridVehicle.setAdapter(adapter);
+
+ // get vehicle display click
+ gridVehicle.setOnItemClickListener((parent, view, position, id) -> {
+ threadUI = new Thread(() -> {
+ myHandler.post(() -> itemClick(position, view));
+ threadUI.interrupt();
+ });
+ threadUI.start();
+ });
+
+
+ // get vehicle menu creation
+ gridVehicle.setOnItemLongClickListener(itemLongClickHandler);
+
+
+ LinearLayout slideLayout = (LinearLayout) findViewById(R.id.slidelayout);
+ ImageView slideLayoutImageView = (ImageView) findViewById(R.id.slideLayoutImage);
+ LinearLayout linearLayoutVehicles = (LinearLayout) findViewById(R.id.layoutBig);
+ slideLayout.setOnClickListener(v -> {
+ if (showVehicle) {
+ linearLayoutVehicles.setVisibility(View.GONE);
+ slideLayoutImageView.setImageResource(R.drawable.arrow_right);
+ showVehicle = false;
+ } else {
+ linearLayoutVehicles.setVisibility(View.VISIBLE);
+ slideLayoutImageView.setImageResource(R.drawable.arrow_left);
+ showVehicle = true;
+ }
+ });
+
+ imageViewCheckAll = (ImageButton) findViewById(R.id.imageCheckAll);
+ imageViewCheckAll.setSelected(false);
+ imageViewCheckAll.setOnClickListener(arg0 -> {
+ for (int i = 0; i < displayedVehicles.size(); i++)
+ displayedVehicles.set(i, true);
+
+ adapter.changeDisplayAll(!imageViewCheckAll.isSelected());
+
+
+ VehiclesGridViewAdapter.ViewHolder viewLive = (VehiclesGridViewAdapter.ViewHolder) gridVehicle.getChildAt(0).getTag();
+
+ if (!imageViewCheckAll.isSelected())
+ viewLive.imgViewChecked.setImageResource(R.drawable.checked);
+ else
+ viewLive.imgViewChecked.setImageResource(R.drawable.unchecked);
+
+ Enumeration keyList = getParentTab().SuperVehHash.keys();
+ while (keyList.hasMoreElements()) {
+ (Objects.requireNonNull(getParentTab().SuperVehHash.get((long) keyList.nextElement()))).needUpdate = true;
+ }
+
+ // change button title
+ if (!imageViewCheckAll.isSelected()) {
+ imageViewCheckAll.setSelected(true);
+ imageViewCheckAll.setBackgroundResource(R.drawable.check_all);
+ displayButton.setText(getString(R.string.hideAll));
+ // set all vehicles to be displayed
+ for (int i = 0; i < displayedVehicles.size(); i++)
+ displayedVehicles.set(i, true);
+ } else {
+ imageViewCheckAll.setSelected(false);
+ imageViewCheckAll.setBackgroundResource(R.drawable.uncheck_all);
+ displayButton.setText(getString(R.string.displayAll));
+ // set all vehicles to not be displayed
+ for (int i = 0; i < displayedVehicles.size(); i++)
+ displayedVehicles.set(i, false);
+ }
+
+ // refresh UI
+ displayVehicle(true, LAT_OUTLIMIT, LNG_OUTLIMIT);
+ });
+
+ displayButton = (Button) findViewById(R.id.buttonDisplay);
+ displayButton.setText(getString(R.string.displayAll));
+
+
+ displayButton.setOnClickListener(v -> {
+ // set all displayed vehicles to true
+
+ for (int i = 0; i < displayedVehicles.size(); i++)
+ displayedVehicles.set(i, true);
+
+ Enumeration keyList = getParentTab().SuperVehHash.keys();
+ while (keyList.hasMoreElements())
+ (Objects.requireNonNull(getParentTab().SuperVehHash.get((long) keyList.nextElement()))).needUpdate = true;
+
+ // change button title
+ if (displayButton.getText().toString().equals(getString(R.string.displayAll))) {
+ displayButton.setText(getString(R.string.hideAll));
+ // set all vehicles to be displayed
+ for (int i = 0; i < displayedVehicles.size(); i++)
+ displayedVehicles.set(i, true);
+ } else {
+ displayButton.setText(getString(R.string.displayAll));
+ // set all vehicles to not be displayed
+ for (int i = 0; i < displayedVehicles.size(); i++)
+ displayedVehicles.set(i, false);
+ }
+
+ // refresh UI
+ displayVehicle(true, LAT_OUTLIMIT, LNG_OUTLIMIT);
+ });
+
+ // display Vehicles
+ displayVehicle(true, LAT_OUTLIMIT, LNG_OUTLIMIT);
+
+ // register to receive broadcasts
+ registerBroadcastIntents();
+ }
+
+ /**
+ * Manipulates the map once available.
+ * This callback is triggered when the map is ready to be used.
+ * This is where we can add markers or lines, add listeners or move the camera. In this case,
+ * we just add a marker near Sydney, Australia.
+ * If Google Play services is not installed on the device, the user will be prompted to install
+ * it inside the SupportMapFragment. This method will only be triggered once the user has
+ * installed Google Play services and returned to the app.
+ */
+ @Override
+ public void onMapReady(@NonNull GoogleMap googleMap) {
+ this.googleMap = googleMap;
+
+ // Add a marker in Sydney and move the camera
+ LatLng sydney = new LatLng(-34, 151);
+ this.googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
+ this.googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
+ }
+
+
+ @Override
+ public void onBackPressed() {
+ // cancel loading dialog if showing
+ if (loadingDialog.isShowing()) {
+ cancelLoadingDialog();
+ } else {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setMessage(getString(R.string.exit))
+ .setCancelable(false)
+ .setNeutralButton(getString(R.string.logout), (dialog, id) -> getParentTab().whenBackPressed(AppParams.ActivityResult.logout))
+ .setPositiveButton(getString(R.string.ext), (dialog, id) -> getParentTab().whenBackPressed(AppParams.ActivityResult.exit))
+ .setNegativeButton(getString(R.string.cancel), (dialog, id) -> dialog.cancel());
+ AlertDialog alert = builder.create();
+ alert.show();
+ }
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ if (isFirstRun) {
+ // show loading dialog
+ showLoadingDialog("Getting vehicles from database...");
+ // send liveActivity
+ getParentTab().setLiveActivity((AbstractLiveActivity) activity);
+ // get all vehicles
+ isAck = false;
+ // start a thread to wait 3 seconds for ack
+ new Thread(() -> {
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ SM.Exception(e.toString());
+ // Restore interrupted state
+ Thread.currentThread().interrupt();
+ }
+ // if not getVehicle not isAck
+ if (!isAck)
+ myHandler.post(cancelLoadingDialogRUN);
+ }).start();
+
+ SM.Debug("GetVehs");
+ isFirstRun = false;
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ SM.Debug("onPause");
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ // clear previous vehicles
+ SM.Debug("onResume");
+ displayVehicle(true, LAT_OUTLIMIT, LNG_OUTLIMIT);
+ }
+
+ final Runnable cancelLoadingDialogRUN = LiveActivity.this::cancelLoadingDialog;
+
+ // cancel loading dialog and show sending error message
+ private void cancelLoadingDialog() {
+ // cancel loading dialog
+ try {
+ loadingDialog.cancel();
+ } catch (Exception ex) {
+ SM.Exception(ex.toString());
+ }
+ if (!isAck) {
+ // show connection error
+ Toast.makeText(context, "Could not get Vehicles... ", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ public void createIconContextMenu() {
+ iconContextMenu = new IconContextMenu(this, 1);
+ iconContextMenu.addItem(res, R.string.enable, R.drawable.enable, MENU_ENABLE);
+ iconContextMenu.addItem(res, R.string.disable, R.drawable.disable, MENU_DISABLE);
+ iconContextMenu.addItem(res, R.string.poll, R.drawable.poll, MENU_POLL);
+
+ //set onclick listener for context menu
+ iconContextMenu.setOnClickListener(menuId -> {
+ int radioCode = 30;
+ switch (menuId) {
+ case MENU_ENABLE: {
+ // send change to AppServer
+ optionForUnit(radioCode, MENU_ENABLE, liveVehicle.get(contextMenuPosition).id + "");
+ if (AppParams.DEMO)
+ vehicleStatusReceived(liveVehicle.get(contextMenuPosition).id, 101, 1);
+ SM.Debug("MENU: Enable for " + liveVehicle.get(contextMenuPosition).id);
+ break;
+ }
+ case MENU_DISABLE: {
+ // send change to AppServer
+ optionForUnit(radioCode, MENU_DISABLE, liveVehicle.get(contextMenuPosition).id + "");
+ if (AppParams.DEMO)
+ vehicleStatusReceived(liveVehicle.get(contextMenuPosition).id, 101, 0);
+ SM.Debug("MENU: Disable for " + liveVehicle.get(contextMenuPosition).id);
+ break;
+ }
+ case MENU_REMOTE: {
+ // send change to AppServer
+ optionForUnit(radioCode, MENU_REMOTE, liveVehicle.get(contextMenuPosition).id + "");
+ SM.Debug("MENU: Remote for " + liveVehicle.get(contextMenuPosition).id);
+ break;
+ }
+ case MENU_POLL: {
+ // send change to AppServer
+ optionForUnit(radioCode, MENU_POLL, liveVehicle.get(contextMenuPosition).id + "");
+ if (AppParams.DEMO) {
+ getParentTab().imei = liveVehicle.get(contextMenuPosition).sc_id + "";
+ getParentTab().updateDemoPosition();
+ getParentTab().updateResultsPollInUi("realpha");
+ }
+
+ SM.Debug("MENU: P for " + liveVehicle.get(contextMenuPosition).id);
+ break;
+ }
+ default:
+ throw new IllegalStateException("Unexpected value: " + menuId);
+ }
+ });
+ }
+
+ /**
+ * create context menu
+ */
+ @Override
+ public Dialog onCreateDialog(int id) {
+ if (id == 1) {
+ return iconContextMenu.createMenu(getString(R.string.options));
+ }
+ return super.onCreateDialog(id);
+ }
+
+
+ /* list item long click handler
+ * used to show the context menu
+ */
+ private final AdapterView.OnItemLongClickListener itemLongClickHandler = ((parent, view, position, id) -> {
+ // save position
+ contextMenuPosition = position;
+ showDialog(1);
+ return true;
+ });
+
+ public void displayVehicle(boolean withZoom, double latZoom, double lngZoom) {
+ //TODO: add makers for vehicles
+ }
+
+ public void showOpenedBalloon(boolean demo) {
+ //TODO: add show balloon
+ }
+
+ public void showLoadingDialog(String message) {
+ loadingDialog = new Dialog(context);
+ loadingDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ loadingDialog.setContentView(R.layout.dialogloading);
+ loadingDialog.setCancelable(true);
+ loadingDialog.setCanceledOnTouchOutside(false);
+
+ Button cancel = (Button) loadingDialog.findViewById(R.id.buttonCancel);
+ cancel.setVisibility(View.GONE);
+ TextView textView1 = (TextView) loadingDialog.findViewById(R.id.textView1);
+ textView1.setText(message);
+
+ loadingDialog.show();
+ }
+
+ // save Vehicles
+ @Override
+ public void vehiclesReceived(ArrayList list) {
+
+ SM.Debug("vehiclesReceived");
+ isAck = true;
+ liveVehicle = list;
+ disabledVehicles = new ArrayList<>();
+ displayedVehicles = new ArrayList<>();
+ // set displayed to false and add icons to hashTable
+ int i = 0;
+ SM.Debug("DISPLAY LIVE VEHICLE");
+ for (Vehicle veh : list) {
+
+ SM.Debug(veh.toString());
+ liveVehicle.get(i).id = veh.sc_id;
+ i++;
+ // set vehicle to false
+ displayedVehicles.add(AppParams.DEMO && (veh.sc_id == 101 || veh.sc_id == 102));
+ // set disable to false
+ disabledVehicles.add(!veh.status);
+
+ // add vehicle to hash Table according to driver_id
+ if (tableHashOverlay.get((int) veh.driver_id) == null) // if doesn't exist
+ {
+ ArrayList array = new ArrayList<>();
+ SuperVehicle superVehicle = new SuperVehicle(veh.sc_id, veh.imei, veh.lp, veh.name, veh.driver_id, veh.time_route, veh.GPS_reporting_interval, veh.is_stolen);
+ array.add(superVehicle);
+ tableHashOverlay.put((int) veh.driver_id, array);
+ } else {
+ // another vehicle with same driver_id exists
+ ArrayList array = tableHashOverlay.get((int) veh.driver_id);
+ SuperVehicle superVehicle = new SuperVehicle(veh.sc_id, veh.imei, veh.lp, veh.name, veh.driver_id, veh.time_route, veh.GPS_reporting_interval, veh.is_stolen);
+ // add vehicle to array
+ if (array != null) {
+ array.add(superVehicle);
+ }
+ }
+ }
+
+ // set adapter
+
+ adapter = new VehiclesGridViewAdapter(activity, context, list, disabledVehicles);
+ adapter.notifyDataSetChanged();
+
+ // Update UI
+ myHandler.post(updateResultsRUN);
+
+ // hide loading dialog
+ loadingDialog.cancel();
+ if (!AppParams.DEMO)
+ getLastPos();
+ }
+
+ // Create runnable for posting
+ final Runnable updateResultsRUN = this::updateResultsUI;
+
+ // show vehicles in gridView
+ private void updateResultsUI() {
+ gridVehicle.setAdapter(adapter);
+
+ try {
+ // hide loading dialog
+ loadingDialog.cancel();
+ } catch (Exception e) {
+ SM.Exception(e.toString());
+ }
+ }
+
+ @Override
+ public void refreshMap() {
+ // Update UI
+ myHandler.post(updateMapResults);
+ }
+
+ @Override
+ public void pollReceived(int position, double lat, double lng) {
+ // Update UI
+ latPoll = lat;
+ lngPoll = lng;
+ this.position = position;
+ myHandler.post(updatePollResults);
+ }
+
+ @Override
+ public void vehicleStatusReceived(long imei, int opCode, int status) {
+ vehStatus = status;
+ SM.Debug("UpdateOptions from APP with-> imei: " + imei + " | opCode: " + opCode + " | status: " + vehStatus);
+ contextMenuPosition = getPositionFromImei(imei);
+ // Update UI
+ myHandler.post(updateOptionsRUN);
+ }
+
+ @Override
+ public void emergencyAlarmReceived(int position, double lat, double lng) {
+ pollReceived(position,lat,lng);
+ }
+
+
+ public void updatePosition(int pos) {
+ contextMenuPosition = pos;
+ }
+
+ // Create runnable for posting
+ final Runnable updateMapResults = () -> displayVehicle(false, LAT_OUTLIMIT, LNG_OUTLIMIT);
+
+ // Create runnable for posting
+ final Runnable updatePollResults = () -> {
+ if (position != -1) {
+ SM.Debug("updatePosition :" + position + " last value:" + displayedVehicles.get(position));
+ // change in adapter
+ adapter.changeDisplayed(position, true);
+ }
+
+ displayVehicle(true, latPoll, lngPoll); };
+
+ // Create runnable for posting
+ final Runnable updateOptionsRUN = this::updateOptionsUI;
+
+ private void updateOptionsUI() {
+
+ SM.Debug("REFRESHDisableEnable" + (Boolean.TRUE.equals(disabledVehicles.get(contextMenuPosition)) ? "true" : "false"));
+ // change Enable/Disable in adapter
+ adapter.changeDisabled(contextMenuPosition, disabledVehicles.get(contextMenuPosition));
+
+ }
+
+ /**
+ * visual modifications when a vehicle is clicked
+ *
+ * @param position position in grid that was clicked
+ * @param view View in which will do the modifications
+ */
+ private void itemClick(int position, View view) {
+ // change displayed state
+ displayedVehicles.set(position, !Boolean.TRUE.equals(displayedVehicles.get(position)));
+
+ // change in the adapter
+ adapter.changeDisplayed(position, displayedVehicles.get(position));
+
+ // change check image for selected value
+ VehiclesGridViewAdapter.ViewHolder viewLive = (VehiclesGridViewAdapter.ViewHolder) view.getTag();
+
+ if (Boolean.TRUE.equals(displayedVehicles.get(position)))
+ viewLive.imgViewChecked.setImageResource(R.drawable.checked);
+ else
+ viewLive.imgViewChecked.setImageResource(R.drawable.unchecked);
+
+ // check if all values are identical
+ boolean identical = true;
+ for (Boolean displ : displayedVehicles)
+ if (!Objects.equals(displ, displayedVehicles.get(0))) {
+ identical = false;
+ break;
+ }
+
+ // change image when all values are identical
+ if (identical && Boolean.TRUE.equals(displayedVehicles.get(0))) {
+ imageViewCheckAll.setSelected(true);
+ imageViewCheckAll.setBackgroundResource(R.drawable.check_all);
+ } else if (identical && Boolean.TRUE.equals(!displayedVehicles.get(0))) {
+ imageViewCheckAll.setSelected(false);
+ imageViewCheckAll.setBackgroundResource(R.drawable.uncheck_all);
+ }
+
+ // display vehicle
+ displayVehicle(true, LAT_OUTLIMIT, LNG_OUTLIMIT);
+ }
+
+ /**
+ * get last position for all vehicles
+ */
+ private void getLastPos() {
+ getParentTab().executeNetworkStuff(new String[]{OperationCodes.GetLastPositions + "", AppParams.USERID + ""});
+ }
+
+ /**
+ * send a command that enable/disable a vehicle or request a poll
+ *
+ * @param radioCode is a hardcoded values set to 30
+ * @param opCode the operation code. It can be :
+ * MENU_ENABLE = 150,
+ * MENU_DISABLE = 151,
+ * MENU_REMOTE = 161,
+ * MENU_POLL = 154;
+ * @param scId vehicle imei for which we do the operation
+ */
+ public void optionForUnit(int radioCode, int opCode, String scId) {
+ // last values is set to 0 for disable and 1 for others
+ getParentTab().executeNetworkStuff(new String[]{OperationCodes.Option4Unit + "", radioCode + "", (opCode == MENU_DISABLE ? MENU_ENABLE : opCode) + "", scId,
+ (opCode == MENU_DISABLE ? 0 : 1) + ""});
+ }
+
+ /**
+ * return the position in the grid for a Vehicle specified by imei
+ *
+ * @param imei vehicle's imei
+ */
+ private int getPositionFromImei(long imei) {
+ int positionFromImei = -1;
+ for (int i = 0; i < liveVehicle.size(); i++)
+ if (liveVehicle.get(i).imei.equalsIgnoreCase(imei + ""))
+ positionFromImei = i;
+ SM.Debug("Position: " + positionFromImei);
+ return positionFromImei;
+ }
+
+ /**
+ * Register for broadcasts
+ */
+ private void registerBroadcastIntents() {
+ // zone and channel change intent
+ IntentFilter intentFilter = new IntentFilter(OperationCodes.UNIT_STATUS_UPDATE + "");
+ this.registerReceiver(mReceiver, intentFilter);
+
+ }
+
+ //The BroadcastReceiver that listens for Notification broadcasts
+ public final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ final String action = intent.getAction();
+
+ if (action.equals(OperationCodes.UNIT_STATUS_UPDATE + "")) {
+ try {
+ final String[] extra = intent.getStringExtra("unitStatus").split("#");
+
+ SM.Debug("extra has " + extra.length + " objects");
+ Toast.makeText(context, "Unit was " + (Integer.parseInt(extra[1]) == 0 ? "DISABLED" : "ENABLED"), Toast.LENGTH_LONG).show();
+
+ myHandler.post(() -> {
+ vehStatus = Integer.parseInt(extra[1]);
+ contextMenuPosition = getPositionFromImei(Integer.parseInt(extra[0]));
+ disabledVehicles.remove(contextMenuPosition);
+ // invert logic is used
+ disabledVehicles.add(contextMenuPosition, vehStatus != 1);
+ adapter.changeDisabled(contextMenuPosition, disabledVehicles.get(contextMenuPosition));
+ });
+ } catch (Exception ex) {
+ SM.Exception("Exception in live BroadCastReceived" + ex.toString());
+ }
+ }
+ }
+ };
+}
\ No newline at end of file
diff --git a/src/com/safemobile/dispatch_demo/MapDemo.java b/safeDispatch/src/main/java/com/safemobile/dispatch/MapDemo.java
similarity index 53%
rename from src/com/safemobile/dispatch_demo/MapDemo.java
rename to safeDispatch/src/main/java/com/safemobile/dispatch/MapDemo.java
index 311b22e..cee9e0c 100644
--- a/src/com/safemobile/dispatch_demo/MapDemo.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/MapDemo.java
@@ -1,11 +1,7 @@
-package com.safemobile.dispatch_demo;
+package com.safemobile.dispatch;
-import android.app.Fragment;
import android.os.Bundle;
-import android.support.v4.app.FragmentActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
+import androidx.fragment.app.FragmentActivity;
public class MapDemo extends FragmentActivity {
diff --git a/src/com/safemobile/dispatch_demo/MessagesActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/MessagesActivity.java
similarity index 99%
rename from src/com/safemobile/dispatch_demo/MessagesActivity.java
rename to safeDispatch/src/main/java/com/safemobile/dispatch/MessagesActivity.java
index 90a5288..23dd2b1 100644
--- a/src/com/safemobile/dispatch_demo/MessagesActivity.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/MessagesActivity.java
@@ -2,26 +2,7 @@
* Author : ErVaLt / techwavedev.com
* Description : TabLayout Andorid App
*/
-package com.safemobile.dispatch_demo;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Hashtable;
-import java.util.Locale;
-
-/** fix import */
-import com.safemobile.dispatch.*;
-import com.safemobile.dispatch_demo.*;
-
-import com.safemobile.adapters.ConversationGridViewAdapter;
-import com.safemobile.adapters.MessagesGridViewAdapter;
-import com.safemobile.lib.AppParams;
-import com.safemobile.lib.Msg;
-import com.safemobile.lib.OperationCodes;
-import com.safemobile.lib.SM;
-import com.safemobile.lib.SMS;
-import com.safemobile.lib.Vehicle;
+package com.safemobile.dispatch;
import android.app.Activity;
import android.app.AlertDialog;
@@ -36,17 +17,36 @@ import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
+import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.GridView;
import android.widget.Toast;
+import com.safemobile.adapters.ConversationGridViewAdapter;
+import com.safemobile.adapters.MessagesGridViewAdapter;
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.Msg;
+import com.safemobile.lib.OperationCodes;
+import com.safemobile.lib.SM;
+import com.safemobile.lib.SMS;
+import com.safemobile.lib.Vehicle;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Locale;
+
+/**
+ * fix import
+ */
+
public class MessagesActivity extends Activity {
/** Called when the activity is first created. */
@@ -113,7 +113,7 @@ public class MessagesActivity extends Activity {
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
- getBaseContext().getResources().updateConfiguration(config,
+ getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
setContentView(R.layout.tabtext);
diff --git a/src/com/safemobile/dispatch_demo/NotificationActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/NotificationActivity.java
similarity index 94%
rename from src/com/safemobile/dispatch_demo/NotificationActivity.java
rename to safeDispatch/src/main/java/com/safemobile/dispatch/NotificationActivity.java
index d150ed5..c775a3b 100644
--- a/src/com/safemobile/dispatch_demo/NotificationActivity.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/NotificationActivity.java
@@ -1,12 +1,11 @@
-package com.safemobile.dispatch_demo;
-
-import com.safemobile.lib.AppParams;
-import com.safemobile.lib.SM;
+package com.safemobile.dispatch;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
+import com.safemobile.lib.AppParams;
+
public class NotificationActivity extends Activity{
public static final String NOTIFICATION_MESSAGE_INTENT = "notification_message_clicked_intent";
diff --git a/src/com/safemobile/dispatch_demo/RadioActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/RadioActivity.java
similarity index 99%
rename from src/com/safemobile/dispatch_demo/RadioActivity.java
rename to safeDispatch/src/main/java/com/safemobile/dispatch/RadioActivity.java
index cbaa4e3..f0821a1 100644
--- a/src/com/safemobile/dispatch_demo/RadioActivity.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/RadioActivity.java
@@ -1,24 +1,4 @@
-package com.safemobile.dispatch_demo;
-
-import java.util.ArrayList;
-import java.util.Locale;
-
-
-
-
-
-/** fix import */
-import com.safemobile.dispatch.*;
-import com.safemobile.dispatch_demo.*;
-import com.safemobile.lib.AppParams;
-import com.safemobile.lib.OperationCodes;
-import com.safemobile.lib.SM;
-import com.safemobile.lib.Vehicle;
-import com.safemobile.lib.radio.Channel;
-import com.safemobile.lib.radio.RadioGW;
-import com.safemobile.lib.radio.Zone;
-import com.safemobile.lib.radio.Zone_and_channel;
-import com.safemobile.lib.sound.AudioHandle;
+package com.safemobile.dispatch;
import android.app.Activity;
import android.app.AlertDialog;
@@ -43,6 +23,23 @@ import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.TextView;
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.OperationCodes;
+import com.safemobile.lib.SM;
+import com.safemobile.lib.Vehicle;
+import com.safemobile.lib.radio.Channel;
+import com.safemobile.lib.radio.RadioGW;
+import com.safemobile.lib.radio.Zone;
+import com.safemobile.lib.radio.Zone_and_channel;
+import com.safemobile.lib.sound.AudioHandle;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+/**
+ * fix import
+ */
+
public class RadioActivity extends Activity {
/* Visual Elements */
@@ -103,9 +100,9 @@ public class RadioActivity extends Activity {
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
- getBaseContext().getResources().updateConfiguration(config,
+ getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
-
+
setContentView(R.layout.tabradio);
// get context
context = this;
@@ -327,7 +324,7 @@ public class RadioActivity extends Activity {
audioH.soundNeeded = true;
buttonPTT.setText(getString(R.string.PTToff));
- buttonPTT.setBackgroundResource(R.layout.style_buttonptt_green);
+ buttonPTT.setBackgroundResource(R.drawable.style_buttonptt_green);
// change text in Screen according to callType
switch(selectedCallType)
{
@@ -389,7 +386,7 @@ public class RadioActivity extends Activity {
if(audioH!=null)
audioH.soundNeeded = false;
buttonPTT.setText(getString(R.string.PTT));
- buttonPTT.setBackgroundResource(R.layout.style_buttonptt);
+ buttonPTT.setBackgroundResource(R.drawable.style_buttonptt);
// change text in Screen
/*
if(rStatus == 1)
@@ -679,7 +676,7 @@ public class RadioActivity extends Activity {
TextView text = (TextView) dialog.findViewById(R.id.text);
ImageView image = (ImageView) dialog.findViewById(R.id.image);
- image.setImageResource(R.drawable.icon);
+ image.setImageResource(R.drawable.ic_launcher);
text.setText(errorMsg);
dialog.show();
}
@@ -985,7 +982,7 @@ public class RadioActivity extends Activity {
if(audioH!=null)
audioH.soundNeeded = false;
buttonPTT.setText(getString(R.string.PTT));
- buttonPTT.setBackgroundResource(R.layout.style_buttonptt);
+ buttonPTT.setBackgroundResource(R.drawable.style_buttonptt);
}
parentTab.enableMenuButtons(true);
diff --git a/src/com/safemobile/dispatch_demo/RecordingsActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/RecordingsActivity.java
similarity index 98%
rename from src/com/safemobile/dispatch_demo/RecordingsActivity.java
rename to safeDispatch/src/main/java/com/safemobile/dispatch/RecordingsActivity.java
index 83f3b3d..c22f103 100644
--- a/src/com/safemobile/dispatch_demo/RecordingsActivity.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/RecordingsActivity.java
@@ -1,24 +1,4 @@
-package com.safemobile.dispatch_demo;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Locale;
-
-
-
-
-
-
-/** fix import */
-import com.safemobile.dispatch.*;
-import com.safemobile.dispatch_demo.*;
-import com.safemobile.adapters.RecordingsGridViewAdapter;
-import com.safemobile.lib.AppParams;
-import com.safemobile.lib.OperationCodes;
-import com.safemobile.lib.Recording;
-import com.safemobile.lib.SM;
-import com.safemobile.lib.radio.RadioGW;
-import com.safemobile.lib.sound.RecordingHandle;
+package com.safemobile.dispatch;
import android.app.Activity;
import android.app.AlertDialog;
@@ -37,13 +17,29 @@ import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
-import android.widget.AdapterView.OnItemClickListener;
import android.widget.Toast;
+import com.safemobile.adapters.RecordingsGridViewAdapter;
+import com.safemobile.lib.AppParams;
+import com.safemobile.lib.OperationCodes;
+import com.safemobile.lib.Recording;
+import com.safemobile.lib.SM;
+import com.safemobile.lib.radio.RadioGW;
+import com.safemobile.lib.sound.RecordingHandle;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Locale;
+
+/**
+ * fix import
+ */
+
public class RecordingsActivity extends Activity {
private Context context;
private Activity activity;
@@ -79,7 +75,7 @@ public class RecordingsActivity extends Activity {
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
- getBaseContext().getResources().updateConfiguration(config,
+ getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
setContentView(R.layout.tabrecordings);
@@ -191,7 +187,7 @@ public class RecordingsActivity extends Activity {
TextView text = (TextView) dialog.findViewById(R.id.text);
ImageView image = (ImageView) dialog.findViewById(R.id.image);
- image.setImageResource(R.drawable.icon);
+ image.setImageResource(R.drawable.ic_launcher);
text.setText(errorMsg);
dialog.show();
}
diff --git a/src/com/safemobile/dispatch_demo/SDMobileActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/SDMobileActivity.java
similarity index 98%
rename from src/com/safemobile/dispatch_demo/SDMobileActivity.java
rename to safeDispatch/src/main/java/com/safemobile/dispatch/SDMobileActivity.java
index f8e268c..dc0f5ea 100644
--- a/src/com/safemobile/dispatch_demo/SDMobileActivity.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/SDMobileActivity.java
@@ -1,32 +1,12 @@
-package com.safemobile.dispatch_demo;
+package com.safemobile.dispatch;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Calendar;
import java.util.Locale;
-import java.util.TimeZone;
import java.util.Timer;
import java.util.TimerTask;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
//to fix R import
-import com.safemobile.dispatch.*;
-import com.safemobile.dispatch_demo.*;
import com.safemobile.adapters.LanguageSpinnerAdapter;
import com.safemobile.interfaces.ITCPListener;
import com.safemobile.interfaces.TCPEvent;
@@ -60,10 +40,6 @@ import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Color;
-import android.graphics.LinearGradient;
-import android.graphics.Shader;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.RectShape;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
@@ -81,7 +57,6 @@ import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.LinearLayout.LayoutParams;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
@@ -151,7 +126,7 @@ public class SDMobileActivity extends Activity {
else if(AppParams.theme == AppParams.Theme.HYTERA)
this.setTheme(R.style.Theme_Hytera);
else
- this.setTheme(R.style.Theme_Safedispatch);
+ this.setTheme(R.style.AppTheme);
// get Context
@@ -162,7 +137,7 @@ public class SDMobileActivity extends Activity {
loadSettings();
// if package is demo set DEMO to true
- AppParams.DEMO = (context.getPackageName().contains("demo")? true: false);
+ AppParams.DEMO = (context.getPackageName().contains("demo"));
if(savedInstanceState != null && savedInstanceState.getString("language") != null)
@@ -175,7 +150,7 @@ public class SDMobileActivity extends Activity {
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
- getBaseContext().getResources().updateConfiguration(config,
+ getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
Languages = new String[] {getString(R.string.en), getString(R.string.de), getString(R.string.tr), getString(R.string.ro), getString(R.string.ru), getString(R.string.es)};
@@ -349,8 +324,8 @@ public class SDMobileActivity extends Activity {
llPassword.setBackgroundResource(R.drawable.textboxx);
}
else {
- llUsername.setBackgroundResource(R.drawable.textbox);
- llPassword.setBackgroundResource(R.drawable.textbox);
+ llUsername.setBackgroundResource(R.drawable.textboxx);
+ llPassword.setBackgroundResource(R.drawable.textboxx);
}
}
@@ -733,16 +708,17 @@ public class SDMobileActivity extends Activity {
saved.putString("username", etUsername.getText().toString());
saved.putString("password", etPassword.getText().toString());
saved.putBoolean("checked", checkBoxSaveDefault.isChecked());
-
+
+
switch(which)
{
case 0: imageLanguage.setImageResource(R.drawable.en);
saved.putString("language", "en");
- AppParams.LANGUAGETMP = "en"; AppParams.LANGUAGE = "en";
+ AppParams.LANGUAGETMP = "en"; AppParams.LANGUAGE = "en";
break;
case 1: imageLanguage.setImageResource(R.drawable.de);
saved.putString("language", "de");
- AppParams.LANGUAGETMP = "de"; AppParams.LANGUAGE = "de";
+ AppParams.LANGUAGETMP = "de"; AppParams.LANGUAGE = "de";
break;
case 2: imageLanguage.setImageResource(R.drawable.tr);
saved.putString("language", "tr");
@@ -761,9 +737,9 @@ public class SDMobileActivity extends Activity {
AppParams.LANGUAGETMP = "es"; AppParams.LANGUAGE = "es";
break;
}
-
+
// recreate the activity
- onCreate(saved);
+ onCreate(saved);
}
});
diff --git a/src/com/safemobile/dispatch_demo/SDMobileActivity_beforeMod.java b/safeDispatch/src/main/java/com/safemobile/dispatch/SDMobileActivity_beforeMod.java
similarity index 99%
rename from src/com/safemobile/dispatch_demo/SDMobileActivity_beforeMod.java
rename to safeDispatch/src/main/java/com/safemobile/dispatch/SDMobileActivity_beforeMod.java
index 84042d7..630f4d9 100644
--- a/src/com/safemobile/dispatch_demo/SDMobileActivity_beforeMod.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/SDMobileActivity_beforeMod.java
@@ -1,4 +1,4 @@
-package com.safemobile.dispatch_demo;
+package com.safemobile.dispatch;
import java.util.ArrayList;
import java.util.List;
@@ -6,15 +6,7 @@ import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
-
-
-
-
-
-import com.google.android.gms.internal.cb;
/** fix import */
-import com.safemobile.dispatch.*;
-import com.safemobile.dispatch_demo.*;
import com.safemobile.adapters.LanguageSpinnerAdapter;
import com.safemobile.interfaces.ITCPListener;
import com.safemobile.interfaces.TCPEvent;
@@ -72,7 +64,6 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
-import android.widget.Toast;
public class SDMobileActivity_beforeMod extends Activity {
@@ -131,7 +122,7 @@ public class SDMobileActivity_beforeMod extends Activity {
if(AppParams.theme == AppParams.Theme.SAFENET)
this.setTheme(R.style.Theme_Safenet);
else
- this.setTheme(R.style.Theme_Safedispatch);
+ this.setTheme(R.style.AppTheme);
// get settings
loadSettings();
@@ -148,7 +139,7 @@ public class SDMobileActivity_beforeMod extends Activity {
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
- getBaseContext().getResources().updateConfiguration(config,
+ getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
Languages = new String[] {getString(R.string.en), getString(R.string.de), getString(R.string.tr), getString(R.string.ro), getString(R.string.ru), getString(R.string.es)};
diff --git a/src/com/safemobile/dispatch_demo/SetupActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/SetupActivity.java
similarity index 97%
rename from src/com/safemobile/dispatch_demo/SetupActivity.java
rename to safeDispatch/src/main/java/com/safemobile/dispatch/SetupActivity.java
index 0694860..37a2450 100644
--- a/src/com/safemobile/dispatch_demo/SetupActivity.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/SetupActivity.java
@@ -1,11 +1,8 @@
-package com.safemobile.dispatch_demo;
+package com.safemobile.dispatch;
import java.util.Locale;
/** fix import */
-import com.safemobile.dispatch.*;
-import com.safemobile.dispatch_demo.*;
-
import com.safemobile.adapters.LanguageSpinnerAdapter;
import com.safemobile.lib.AppParams;
import com.safemobile.lib.SM;
@@ -68,7 +65,7 @@ public class SetupActivity extends Activity {
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
- getBaseContext().getResources().updateConfiguration(config,
+ getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
Languages = new String[] {getString(R.string.en), getString(R.string.de), getString(R.string.tr), getString(R.string.ro), getString(R.string.ru), getString(R.string.es)};
@@ -224,9 +221,9 @@ public class SetupActivity extends Activity {
Boolean result = editor.commit();
// saved completed
if(result)
- Toast.makeText(context, "Settings saved successfully.", 2000).show();
+ Toast.makeText(context, "Settings saved successfully.", Toast.LENGTH_LONG).show();
else
- Toast.makeText(context, "Settings failed to complete!", 2000).show();
+ Toast.makeText(context, "Settings failed to complete!", Toast.LENGTH_LONG).show();
// if port or IP changed
if((!appServerIP.getText().toString().equalsIgnoreCase(AppParams.IP) ||
!appServerPort.getText().toString().equalsIgnoreCase(AppParams.PORT)) && !AppParams.DEMO)
diff --git a/src/com/safemobile/dispatch_demo/TabLayoutActivity.java b/safeDispatch/src/main/java/com/safemobile/dispatch/TabLayoutActivity.java
similarity index 96%
rename from src/com/safemobile/dispatch_demo/TabLayoutActivity.java
rename to safeDispatch/src/main/java/com/safemobile/dispatch/TabLayoutActivity.java
index 3bd6c04..fe01c66 100644
--- a/src/com/safemobile/dispatch_demo/TabLayoutActivity.java
+++ b/safeDispatch/src/main/java/com/safemobile/dispatch/TabLayoutActivity.java
@@ -1,4 +1,4 @@
-package com.safemobile.dispatch_demo;
+package com.safemobile.dispatch;
import java.io.BufferedReader;
import java.io.IOException;
@@ -8,24 +8,14 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
-import java.util.Hashtable;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
-
-
-
-
-
-
/** fix import */
-import com.safemobile.dispatch.*;
-import com.safemobile.dispatch_demo.*;
import com.safemobile.activities.AbstractEmptyActivity;
import com.safemobile.activities.AbstractLiveActivity;
import com.safemobile.activities.AbstractMessagesActivity;
-import com.safemobile.activities.AbstractParentActivity;
import com.safemobile.activities.AbstractRadioActivity;
import com.safemobile.activities.AbstractSDParentActivity;
import com.safemobile.interfaces.ITCPListener;
@@ -52,25 +42,20 @@ import com.safemobile.lib.TCPmsg;
import com.safemobile.lib.VehMSG;
import com.safemobile.lib.Vehicle;
import com.safemobile.lib.radio.RadioGW;
-import com.safemobile.lib.radio.SUstatus;
import com.safemobile.services.TCPService;
import com.safemobile.services.TCPhandler;
import com.safemobile.services.TCPService.TCPBinder;
-import com.safemobile.services.TCPmsgParser;
-import android.app.Activity;
import android.app.Dialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.app.TabActivity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
-import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -79,12 +64,10 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
-import android.os.StrictMode;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
-import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.animation.Animation;
@@ -184,7 +167,7 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
else if(AppParams.theme == AppParams.Theme.HYTERA)
this.setTheme(R.style.Theme_Hytera);
else
- this.setTheme(R.style.Theme_Safedispatch);
+ this.setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
SM.Debug("######### ON CREATE TAB");
@@ -200,7 +183,7 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
- getBaseContext().getResources().updateConfiguration(config,
+ getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
setContentView(R.layout.tabpanel);
@@ -287,8 +270,8 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
tabWidget = (TabWidget) findViewById(android.R.id.tabs);
tabWidget.setVisibility(View.GONE);
- intent = new Intent[8];
- tabspecs = new TabSpec[8];
+ intent = new Intent[7];
+ tabspecs = new TabSpec[7];
// add live tab
try
@@ -310,60 +293,62 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
// add history tab
try
{
- intent[1] = new Intent(context, HistoryActivity.class);
- tabspecs[1] = tabHost.newTabSpec("History")
- .setIndicator("History", res.getDrawable(R.drawable.ic_tab_history_selected))
- .setContent(intent[1]);
+ //intent[1] = new Intent(context, HistoryActivity.class);
+ //tabspecs[1] = tabHost.newTabSpec("History")
+ // .setIndicator("History", res.getDrawable(R.drawable.ic_tab_history_selected))
+ // .setContent(intent[1]);
}
catch(NoClassDefFoundError e)
{
// exception when GoogleApi not exists
- intent[1] = new Intent(context, AbstractEmptyActivity.class);
- tabspecs[1] = tabHost.newTabSpec("History")
- .setIndicator("History", res.getDrawable(R.drawable.ic_tab_history_selected))
- .setContent(intent[1]);
+ //intent[1] = new Intent(context, AbstractEmptyActivity.class);
+ //tabspecs[1] = tabHost.newTabSpec("History")
+ // .setIndicator("History", res.getDrawable(R.drawable.ic_tab_history_selected))
+ // .setContent(intent[1]);
}
// add text tab
- intent[2] = new Intent(context, MessagesActivity.class);
- tabspecs[2] = tabHost.newTabSpec("Text")
+ intent[1] = new Intent(context, MessagesActivity.class);
+ tabspecs[1] = tabHost.newTabSpec("Text")
.setIndicator("Text", res.getDrawable(R.drawable.ic_tab_text_selected))
+ .setContent(intent[1]);
+
+ // add radio tab
+ intent[2] = new Intent(context, RadioActivity.class);
+ tabspecs[2] = tabHost.newTabSpec("Radio")
+ .setIndicator("Radio", res.getDrawable(R.drawable.ic_tab_radio_selected))
.setContent(intent[2]);
- // add radio tab
- intent[3] = new Intent(context, RadioActivity.class);
- tabspecs[3] = tabHost.newTabSpec("Radio")
- .setIndicator("Radio", res.getDrawable(R.drawable.ic_tab_radio_selected))
+ // add recordings tab
+ intent[3] = new Intent(context, RecordingsActivity.class);
+ tabspecs[3] = tabHost.newTabSpec("Recordings")
+ .setIndicator("Recordings", res.getDrawable(R.drawable.ic_tab_recording_selected))
.setContent(intent[3]);
- // add recordings tab
- intent[4] = new Intent(context, RecordingsActivity.class);
- tabspecs[4] = tabHost.newTabSpec("Recordings")
- .setIndicator("Recordings", res.getDrawable(R.drawable.ic_tab_recording_selected))
+ // add alarms tab
+ intent[4] = new Intent(context, AlarmActivity.class);
+ tabspecs[4] = tabHost.newTabSpec("Alarms")
+ .setIndicator("Alarms", res.getDrawable(R.drawable.ic_tab_alarms_selected))
.setContent(intent[4]);
- // add alarms tab
- intent[5] = new Intent(context, AlarmActivity.class);
- tabspecs[5] = tabHost.newTabSpec("Alarms")
- .setIndicator("Alarms", res.getDrawable(R.drawable.ic_tab_alarms_selected))
+ // add setup tab
+ intent[5] = new Intent(context, SetupActivity.class);
+ tabspecs[5] = tabHost.newTabSpec("Setup")
+ .setIndicator("Setup", res.getDrawable(R.drawable.ic_tab_settings_selected))
.setContent(intent[5]);
- // add setup tab
- intent[6] = new Intent(context, SetupActivity.class);
- tabspecs[6] = tabHost.newTabSpec("Setup")
- .setIndicator("Setup", res.getDrawable(R.drawable.ic_tab_settings_selected))
+ // add radio tab
+ intent[6] = new Intent(context, AbstractEmptyActivity.class);
+ tabspecs[6] = tabHost.newTabSpec("SafeMobile")
+ .setIndicator("SafeMobile", res.getDrawable(AppParams.DEMO ? R.drawable.icon_demo : R.drawable.ic_launcher))
.setContent(intent[6]);
- // add radio tab
- intent[7] = new Intent(context, AbstractEmptyActivity.class);
- tabspecs[7] = tabHost.newTabSpec("SafeMobile")
- .setIndicator("SafeMobile", res.getDrawable(AppParams.DEMO ? R.drawable.icon_demo : R.drawable.icon))
- .setContent(intent[7]);
-
// add tab in tabHost
- for(int i=0;i<7;i++)
- tabHost.addTab(tabspecs[i]);
-
+// for(int i=0;i<7;i++
+ for (TabSpec tab: tabspecs) {
+ if(tabHost != null)
+ tabHost.addTab(tab);
+ }
layoutMenu = (LinearLayout) findViewById(R.id.layoutMenu);
// get slide Menu layout image
@@ -635,7 +620,7 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
dialog.setTitle(AppParams.DEMO ? getString(R.string.app_name_demo) : getString(R.string.app_name));
dialog.setContentView(R.layout.dialog);
ImageView image = (ImageView) dialog.findViewById(R.id.image);
- image.setImageResource(AppParams.DEMO ? R.drawable.icon_demo : R.drawable.icon);
+ image.setImageResource(AppParams.DEMO ? R.drawable.icon_demo : R.drawable.ic_launcher);
TextView text = (TextView) dialog.findViewById(R.id.text);
TextView text2 = (TextView) dialog.findViewById(R.id.text2);
text.setText(getString(R.string.version) + "1.0.8");
@@ -764,7 +749,7 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
}
- if(AppParams.DEMO)
+ if(AppParams.DEMO && liveActivity != null)
{
liveActivity.vehiclesReceived(allVehicle);
demoPositionsList();
@@ -1027,14 +1012,14 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
Locale.setDefault(locale);
android.content.res.Configuration configuration = new android.content.res.Configuration();
configuration.locale = locale;
- getBaseContext().getResources().updateConfiguration(configuration,
+ getBaseContext().getResources().updateConfiguration(configuration,
getBaseContext().getResources().getDisplayMetrics());
// change UI in Live Activity
// if(liveActivity != null)
//liveActivity.onCreate(liveActivity.savedInstanceState);
if(historyActivity!=null)
- historyActivity.onCreate(historyActivity.savedInstanceState);
+ //historyActivity.onCreate(historyActivity.savedInstanceState);
// change UI for RadioActivity and MessageActivity
if(radioActivity!=null)
radioActivity.onCreate(radioActivity.savedInstanceState);
@@ -1671,7 +1656,7 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
historyActivity.UpdateMap();
}
- else
+ else
historyActivity.UpdateUnableDisp(); // update with more than 200 points
}
//((HistoryActivity)currentActivity).UpdateMap(HistPosList.size());
@@ -1949,9 +1934,9 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
if(liveActivity != null)
{
if (x!=allVehicle.size())
- liveActivity.emergAlarmReceived(x ,SuperVehHash.get(Long.parseLong(UnitIMEI)).lat,SuperVehHash.get(Long.parseLong(UnitIMEI)).lng);
+ liveActivity.emergencyAlarmReceived(x ,SuperVehHash.get(Long.parseLong(UnitIMEI)).lat,SuperVehHash.get(Long.parseLong(UnitIMEI)).lng);
else
- liveActivity.emergAlarmReceived(-1, SuperVehHash.get(Long.parseLong(UnitIMEI)).lat,SuperVehHash.get(Long.parseLong(UnitIMEI)).lng);
+ liveActivity.emergencyAlarmReceived(-1, SuperVehHash.get(Long.parseLong(UnitIMEI)).lat,SuperVehHash.get(Long.parseLong(UnitIMEI)).lng);
}
}
catch (Exception ex)
@@ -2237,7 +2222,7 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
mNotificationManager.cancel(icon);
PendingIntent contentIntent = PendingIntent.getActivity(context, NOTIFICATION_ACTIVITY_RESULT, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
- notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
+ //notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
//notification.defaults |= Notification.DEFAULT_SOUND;
// flag that the notification will be closed when clicked
@@ -2355,13 +2340,13 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
}
}
- public void Option4Unit(int radioCode, int opCode, int sc_id, int value)
+ public void optionForUnit(int radioCode, int opCode, int sc_id, int value)
{
boolean res = tcp.Write("0.0", "#"+radioCode+"#"+opCode+"#" + sc_id+"#" +value + "#");
if(res){
- SM.Debug("Message (Option4Unit) sent to app server radioCode:"+radioCode+ " opCode:"+opCode+ " sc_id:"+sc_id+ " value:"+value);
+ SM.Debug("Message (optionForUnit) sent to app server radioCode:"+radioCode+ " opCode:"+opCode+ " sc_id:"+sc_id+ " value:"+value);
}else{
- SM.Debug("Could not send message(Option4Unit)!!");
+ SM.Debug("Could not send message(optionForUnit)!!");
}
}
@@ -2630,12 +2615,7 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
@Override
public void displayToast(final String msg)
{
- myHandler.post(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(context, msg, 500).show();
- }
- });
+ myHandler.post(() -> Toast.makeText(context, msg, Toast.LENGTH_SHORT).show());
}
@@ -2689,14 +2669,6 @@ public class TabLayoutActivity extends AbstractSDParentActivity{
{
if(!AppParams.DEMO)
{
- /*
- if(tcp!=null)
- {
- tcp.Stop();
- tcp = null;
- }
- */
-
if(tcpParser!=null)
tcpParser.clearMsgList();
diff --git a/src/com/safemobile/lib/Configuration.java b/safeDispatch/src/main/java/com/safemobile/lib/Configuration.java
similarity index 100%
rename from src/com/safemobile/lib/Configuration.java
rename to safeDispatch/src/main/java/com/safemobile/lib/Configuration.java
diff --git a/src/com/safemobile/lib/TCPclient.java b/safeDispatch/src/main/java/com/safemobile/lib/TCPclient.java
similarity index 100%
rename from src/com/safemobile/lib/TCPclient.java
rename to safeDispatch/src/main/java/com/safemobile/lib/TCPclient.java
diff --git a/src/com/safemobile/lib/sound/AudioHandle.java b/safeDispatch/src/main/java/com/safemobile/lib/sound/AudioHandle.java
similarity index 98%
rename from src/com/safemobile/lib/sound/AudioHandle.java
rename to safeDispatch/src/main/java/com/safemobile/lib/sound/AudioHandle.java
index 7450d82..12bbd55 100644
--- a/src/com/safemobile/lib/sound/AudioHandle.java
+++ b/safeDispatch/src/main/java/com/safemobile/lib/sound/AudioHandle.java
@@ -1,16 +1,14 @@
package com.safemobile.lib.sound;
-import java.io.DataOutputStream;
-
-import com.safemobile.lib.SM;
-
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
-import android.renderscript.Sampler;
-import android.widget.Toast;
+
+import com.safemobile.lib.SM;
+
+import java.io.DataOutputStream;
public class AudioHandle implements Runnable{
diff --git a/src/com/safemobile/lib/sound/ITCPaudioLis.java b/safeDispatch/src/main/java/com/safemobile/lib/sound/ITCPaudioLis.java
similarity index 100%
rename from src/com/safemobile/lib/sound/ITCPaudioLis.java
rename to safeDispatch/src/main/java/com/safemobile/lib/sound/ITCPaudioLis.java
diff --git a/src/com/safemobile/lib/sound/IUDPListener.java b/safeDispatch/src/main/java/com/safemobile/lib/sound/IUDPListener.java
similarity index 100%
rename from src/com/safemobile/lib/sound/IUDPListener.java
rename to safeDispatch/src/main/java/com/safemobile/lib/sound/IUDPListener.java
diff --git a/src/com/safemobile/lib/sound/RecordingHandle.java b/safeDispatch/src/main/java/com/safemobile/lib/sound/RecordingHandle.java
similarity index 100%
rename from src/com/safemobile/lib/sound/RecordingHandle.java
rename to safeDispatch/src/main/java/com/safemobile/lib/sound/RecordingHandle.java
diff --git a/src/com/safemobile/lib/sound/TCPaudioClient.java b/safeDispatch/src/main/java/com/safemobile/lib/sound/TCPaudioClient.java
similarity index 100%
rename from src/com/safemobile/lib/sound/TCPaudioClient.java
rename to safeDispatch/src/main/java/com/safemobile/lib/sound/TCPaudioClient.java
diff --git a/src/com/safemobile/lib/sound/TCPaudioEvent.java b/safeDispatch/src/main/java/com/safemobile/lib/sound/TCPaudioEvent.java
similarity index 100%
rename from src/com/safemobile/lib/sound/TCPaudioEvent.java
rename to safeDispatch/src/main/java/com/safemobile/lib/sound/TCPaudioEvent.java
diff --git a/src/com/safemobile/lib/sound/UDPclient.java b/safeDispatch/src/main/java/com/safemobile/lib/sound/UDPclient.java
similarity index 100%
rename from src/com/safemobile/lib/sound/UDPclient.java
rename to safeDispatch/src/main/java/com/safemobile/lib/sound/UDPclient.java
diff --git a/src/com/safemobile/lib/sound/UDPevent.java b/safeDispatch/src/main/java/com/safemobile/lib/sound/UDPevent.java
similarity index 100%
rename from src/com/safemobile/lib/sound/UDPevent.java
rename to safeDispatch/src/main/java/com/safemobile/lib/sound/UDPevent.java
diff --git a/res/anim/alpha.xml b/safeDispatch/src/main/res/anim/alpha.xml
similarity index 100%
rename from res/anim/alpha.xml
rename to safeDispatch/src/main/res/anim/alpha.xml
diff --git a/res/anim/realpha.xml b/safeDispatch/src/main/res/anim/realpha.xml
similarity index 100%
rename from res/anim/realpha.xml
rename to safeDispatch/src/main/res/anim/realpha.xml
diff --git a/res/drawable-hdpi/addbutton.png b/safeDispatch/src/main/res/drawable-hdpi/addbutton.png
similarity index 100%
rename from res/drawable-hdpi/addbutton.png
rename to safeDispatch/src/main/res/drawable-hdpi/addbutton.png
diff --git a/res/drawable-hdpi/addbutton_over.png b/safeDispatch/src/main/res/drawable-hdpi/addbutton_over.png
similarity index 100%
rename from res/drawable-hdpi/addbutton_over.png
rename to safeDispatch/src/main/res/drawable-hdpi/addbutton_over.png
diff --git a/res/drawable-hdpi/alert_message.9.png b/safeDispatch/src/main/res/drawable-hdpi/alert_message.9.png
similarity index 100%
rename from res/drawable-hdpi/alert_message.9.png
rename to safeDispatch/src/main/res/drawable-hdpi/alert_message.9.png
diff --git a/res/drawable-hdpi/arrow_down.png b/safeDispatch/src/main/res/drawable-hdpi/arrow_down.png
similarity index 100%
rename from res/drawable-hdpi/arrow_down.png
rename to safeDispatch/src/main/res/drawable-hdpi/arrow_down.png
diff --git a/res/drawable-hdpi/arrow_left.png b/safeDispatch/src/main/res/drawable-hdpi/arrow_left.png
similarity index 100%
rename from res/drawable-hdpi/arrow_left.png
rename to safeDispatch/src/main/res/drawable-hdpi/arrow_left.png
diff --git a/res/drawable-hdpi/arrow_right.png b/safeDispatch/src/main/res/drawable-hdpi/arrow_right.png
similarity index 100%
rename from res/drawable-hdpi/arrow_right.png
rename to safeDispatch/src/main/res/drawable-hdpi/arrow_right.png
diff --git a/res/drawable-hdpi/arrow_up.png b/safeDispatch/src/main/res/drawable-hdpi/arrow_up.png
similarity index 100%
rename from res/drawable-hdpi/arrow_up.png
rename to safeDispatch/src/main/res/drawable-hdpi/arrow_up.png
diff --git a/res/drawable-hdpi/back.png b/safeDispatch/src/main/res/drawable-hdpi/back.png
similarity index 100%
rename from res/drawable-hdpi/back.png
rename to safeDispatch/src/main/res/drawable-hdpi/back.png
diff --git a/res/drawable-hdpi/back_over.png b/safeDispatch/src/main/res/drawable-hdpi/back_over.png
similarity index 100%
rename from res/drawable-hdpi/back_over.png
rename to safeDispatch/src/main/res/drawable-hdpi/back_over.png
diff --git a/res/drawable-hdpi/backgroundgreen.jpg b/safeDispatch/src/main/res/drawable-hdpi/backgroundgreen.jpg
similarity index 100%
rename from res/drawable-hdpi/backgroundgreen.jpg
rename to safeDispatch/src/main/res/drawable-hdpi/backgroundgreen.jpg
diff --git a/res/drawable-hdpi/balloon_close_bg_selector.xml b/safeDispatch/src/main/res/drawable-hdpi/balloon_close_bg_selector.xml
similarity index 100%
rename from res/drawable-hdpi/balloon_close_bg_selector.xml
rename to safeDispatch/src/main/res/drawable-hdpi/balloon_close_bg_selector.xml
diff --git a/res/drawable-hdpi/balloon_overlay_bg_selector.xml b/safeDispatch/src/main/res/drawable-hdpi/balloon_overlay_bg_selector.xml
similarity index 100%
rename from res/drawable-hdpi/balloon_overlay_bg_selector.xml
rename to safeDispatch/src/main/res/drawable-hdpi/balloon_overlay_bg_selector.xml
diff --git a/res/drawable-hdpi/balloon_overlay_close.png b/safeDispatch/src/main/res/drawable-hdpi/balloon_overlay_close.png
similarity index 100%
rename from res/drawable-hdpi/balloon_overlay_close.png
rename to safeDispatch/src/main/res/drawable-hdpi/balloon_overlay_close.png
diff --git a/res/drawable-hdpi/balloon_overlay_close_over.png b/safeDispatch/src/main/res/drawable-hdpi/balloon_overlay_close_over.png
similarity index 100%
rename from res/drawable-hdpi/balloon_overlay_close_over.png
rename to safeDispatch/src/main/res/drawable-hdpi/balloon_overlay_close_over.png
diff --git a/res/drawable-hdpi/balloon_overlay_focused.9.png b/safeDispatch/src/main/res/drawable-hdpi/balloon_overlay_focused.9.png
similarity index 100%
rename from res/drawable-hdpi/balloon_overlay_focused.9.png
rename to safeDispatch/src/main/res/drawable-hdpi/balloon_overlay_focused.9.png
diff --git a/res/drawable-hdpi/balloon_overlay_unfocused.9.png b/safeDispatch/src/main/res/drawable-hdpi/balloon_overlay_unfocused.9.png
similarity index 100%
rename from res/drawable-hdpi/balloon_overlay_unfocused.9.png
rename to safeDispatch/src/main/res/drawable-hdpi/balloon_overlay_unfocused.9.png
diff --git a/res/drawable-hdpi/barcode.png b/safeDispatch/src/main/res/drawable-hdpi/barcode.png
similarity index 100%
rename from res/drawable-hdpi/barcode.png
rename to safeDispatch/src/main/res/drawable-hdpi/barcode.png
diff --git a/res/drawable-hdpi/barcode_over.png b/safeDispatch/src/main/res/drawable-hdpi/barcode_over.png
similarity index 100%
rename from res/drawable-hdpi/barcode_over.png
rename to safeDispatch/src/main/res/drawable-hdpi/barcode_over.png
diff --git a/res/drawable-hdpi/bg_sd.png b/safeDispatch/src/main/res/drawable-hdpi/bg_sd.png
similarity index 100%
rename from res/drawable-hdpi/bg_sd.png
rename to safeDispatch/src/main/res/drawable-hdpi/bg_sd.png
diff --git a/res/drawable-hdpi/bg_sd2.jpg b/safeDispatch/src/main/res/drawable-hdpi/bg_sd2.jpg
similarity index 100%
rename from res/drawable-hdpi/bg_sd2.jpg
rename to safeDispatch/src/main/res/drawable-hdpi/bg_sd2.jpg
diff --git a/res/drawable-hdpi/bg_sn.jpg b/safeDispatch/src/main/res/drawable-hdpi/bg_sn.jpg
similarity index 100%
rename from res/drawable-hdpi/bg_sn.jpg
rename to safeDispatch/src/main/res/drawable-hdpi/bg_sn.jpg
diff --git a/res/drawable-hdpi/bg_snn.png b/safeDispatch/src/main/res/drawable-hdpi/bg_snn.png
similarity index 100%
rename from res/drawable-hdpi/bg_snn.png
rename to safeDispatch/src/main/res/drawable-hdpi/bg_snn.png
diff --git a/res/drawable-hdpi/bluebullet.png b/safeDispatch/src/main/res/drawable-hdpi/bluebullet.png
similarity index 100%
rename from res/drawable-hdpi/bluebullet.png
rename to safeDispatch/src/main/res/drawable-hdpi/bluebullet.png
diff --git a/res/drawable-hdpi/calendar_48.png b/safeDispatch/src/main/res/drawable-hdpi/calendar_48.png
similarity index 100%
rename from res/drawable-hdpi/calendar_48.png
rename to safeDispatch/src/main/res/drawable-hdpi/calendar_48.png
diff --git a/res/drawable-hdpi/calendar_48_red.png b/safeDispatch/src/main/res/drawable-hdpi/calendar_48_red.png
similarity index 100%
rename from res/drawable-hdpi/calendar_48_red.png
rename to safeDispatch/src/main/res/drawable-hdpi/calendar_48_red.png
diff --git a/res/drawable-hdpi/change_ip.png b/safeDispatch/src/main/res/drawable-hdpi/change_ip.png
similarity index 100%
rename from res/drawable-hdpi/change_ip.png
rename to safeDispatch/src/main/res/drawable-hdpi/change_ip.png
diff --git a/res/drawable-hdpi/check_all.png b/safeDispatch/src/main/res/drawable-hdpi/check_all.png
similarity index 100%
rename from res/drawable-hdpi/check_all.png
rename to safeDispatch/src/main/res/drawable-hdpi/check_all.png
diff --git a/safeDispatch/src/main/res/drawable-hdpi/checked.png b/safeDispatch/src/main/res/drawable-hdpi/checked.png
new file mode 100644
index 0000000..141338c
Binary files /dev/null and b/safeDispatch/src/main/res/drawable-hdpi/checked.png differ
diff --git a/res/drawable-hdpi/datepicker.png b/safeDispatch/src/main/res/drawable-hdpi/datepicker.png
similarity index 100%
rename from res/drawable-hdpi/datepicker.png
rename to safeDispatch/src/main/res/drawable-hdpi/datepicker.png
diff --git a/res/drawable-hdpi/disable.PNG b/safeDispatch/src/main/res/drawable-hdpi/disable.png
similarity index 100%
rename from res/drawable-hdpi/disable.PNG
rename to safeDispatch/src/main/res/drawable-hdpi/disable.png
diff --git a/res/drawable-hdpi/enable.png b/safeDispatch/src/main/res/drawable-hdpi/enable.png
similarity index 100%
rename from res/drawable-hdpi/enable.png
rename to safeDispatch/src/main/res/drawable-hdpi/enable.png
diff --git a/res/drawable-hdpi/exclamation.png b/safeDispatch/src/main/res/drawable-hdpi/exclamation.png
similarity index 100%
rename from res/drawable-hdpi/exclamation.png
rename to safeDispatch/src/main/res/drawable-hdpi/exclamation.png
diff --git a/safeDispatch/src/main/res/drawable-hdpi/ic_launcher.png b/safeDispatch/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..63d2d68
Binary files /dev/null and b/safeDispatch/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/res/drawable-hdpi/ic_tab_alarms_selected.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_alarms_selected.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_alarms_selected.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_alarms_selected.png
diff --git a/res/drawable-hdpi/ic_tab_history_selected.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_history_selected.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_history_selected.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_history_selected.png
diff --git a/res/drawable-hdpi/ic_tab_live_selected.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_live_selected.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_live_selected.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_live_selected.png
diff --git a/res/drawable-hdpi/ic_tab_logo_selected.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_logo_selected.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_logo_selected.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_logo_selected.png
diff --git a/res/drawable-hdpi/ic_tab_logo_selected_demo.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_logo_selected_demo.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_logo_selected_demo.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_logo_selected_demo.png
diff --git a/res/drawable-hdpi/ic_tab_logo_selected_original.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_logo_selected_original.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_logo_selected_original.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_logo_selected_original.png
diff --git a/res/drawable-hdpi/ic_tab_radio_selected.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_radio_selected.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_radio_selected.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_radio_selected.png
diff --git a/res/drawable-hdpi/ic_tab_radiopad_selected.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_radiopad_selected.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_radiopad_selected.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_radiopad_selected.png
diff --git a/res/drawable-hdpi/ic_tab_radiopad_selected_red.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_radiopad_selected_red.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_radiopad_selected_red.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_radiopad_selected_red.png
diff --git a/res/drawable-hdpi/ic_tab_radiopod_selected.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_radiopod_selected.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_radiopod_selected.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_radiopod_selected.png
diff --git a/res/drawable-hdpi/ic_tab_radiopod_selected_red.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_radiopod_selected_red.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_radiopod_selected_red.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_radiopod_selected_red.png
diff --git a/res/drawable-hdpi/ic_tab_recording_selected.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_recording_selected.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_recording_selected.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_recording_selected.png
diff --git a/res/drawable-hdpi/ic_tab_settings_selected.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_settings_selected.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_settings_selected.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_settings_selected.png
diff --git a/res/drawable-hdpi/ic_tab_setup_selected.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_setup_selected.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_setup_selected.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_setup_selected.png
diff --git a/res/drawable-hdpi/ic_tab_text_selected.png b/safeDispatch/src/main/res/drawable-hdpi/ic_tab_text_selected.png
similarity index 100%
rename from res/drawable-hdpi/ic_tab_text_selected.png
rename to safeDispatch/src/main/res/drawable-hdpi/ic_tab_text_selected.png
diff --git a/res/drawable-hdpi/icon_demo.png b/safeDispatch/src/main/res/drawable-hdpi/icon_demo.png
similarity index 100%
rename from res/drawable-hdpi/icon_demo.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_demo.png
diff --git a/safeDispatch/src/main/res/drawable-hdpi/icon_original.png b/safeDispatch/src/main/res/drawable-hdpi/icon_original.png
new file mode 100644
index 0000000..63d2d68
Binary files /dev/null and b/safeDispatch/src/main/res/drawable-hdpi/icon_original.png differ
diff --git a/res/drawable-hdpi/icon_radiopad.png b/safeDispatch/src/main/res/drawable-hdpi/icon_radiopad.png
similarity index 100%
rename from res/drawable-hdpi/icon_radiopad.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_radiopad.png
diff --git a/res/drawable-hdpi/icon_radiopad2.png b/safeDispatch/src/main/res/drawable-hdpi/icon_radiopad2.png
similarity index 100%
rename from res/drawable-hdpi/icon_radiopad2.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_radiopad2.png
diff --git a/res/drawable-hdpi/icon_radiopad_blue.png b/safeDispatch/src/main/res/drawable-hdpi/icon_radiopad_blue.png
similarity index 100%
rename from res/drawable-hdpi/icon_radiopad_blue.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_radiopad_blue.png
diff --git a/res/drawable-hdpi/icon_radiopad_red.png b/safeDispatch/src/main/res/drawable-hdpi/icon_radiopad_red.png
similarity index 100%
rename from res/drawable-hdpi/icon_radiopad_red.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_radiopad_red.png
diff --git a/res/drawable-hdpi/icon_radiopad_trim.png b/safeDispatch/src/main/res/drawable-hdpi/icon_radiopad_trim.png
similarity index 100%
rename from res/drawable-hdpi/icon_radiopad_trim.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_radiopad_trim.png
diff --git a/res/drawable-hdpi/icon_radiopad_trim_red.png b/safeDispatch/src/main/res/drawable-hdpi/icon_radiopad_trim_red.png
similarity index 100%
rename from res/drawable-hdpi/icon_radiopad_trim_red.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_radiopad_trim_red.png
diff --git a/res/drawable-hdpi/icon_radiopod.png b/safeDispatch/src/main/res/drawable-hdpi/icon_radiopod.png
similarity index 100%
rename from res/drawable-hdpi/icon_radiopod.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_radiopod.png
diff --git a/res/drawable-hdpi/icon_radiopod_blue.png b/safeDispatch/src/main/res/drawable-hdpi/icon_radiopod_blue.png
similarity index 100%
rename from res/drawable-hdpi/icon_radiopod_blue.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_radiopod_blue.png
diff --git a/res/drawable-hdpi/icon_radiopod_red.png b/safeDispatch/src/main/res/drawable-hdpi/icon_radiopod_red.png
similarity index 100%
rename from res/drawable-hdpi/icon_radiopod_red.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_radiopod_red.png
diff --git a/res/drawable-hdpi/icon_radiopod_trim.png b/safeDispatch/src/main/res/drawable-hdpi/icon_radiopod_trim.png
similarity index 100%
rename from res/drawable-hdpi/icon_radiopod_trim.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_radiopod_trim.png
diff --git a/res/drawable-hdpi/icon_radiopod_trim_red.png b/safeDispatch/src/main/res/drawable-hdpi/icon_radiopod_trim_red.png
similarity index 100%
rename from res/drawable-hdpi/icon_radiopod_trim_red.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_radiopod_trim_red.png
diff --git a/res/drawable-hdpi/icon_radiopoddd.png b/safeDispatch/src/main/res/drawable-hdpi/icon_radiopoddd.png
similarity index 100%
rename from res/drawable-hdpi/icon_radiopoddd.png
rename to safeDispatch/src/main/res/drawable-hdpi/icon_radiopoddd.png
diff --git a/res/drawable-hdpi/img01.png b/safeDispatch/src/main/res/drawable-hdpi/img01.png
similarity index 100%
rename from res/drawable-hdpi/img01.png
rename to safeDispatch/src/main/res/drawable-hdpi/img01.png
diff --git a/res/drawable-hdpi/img02.png b/safeDispatch/src/main/res/drawable-hdpi/img02.png
similarity index 100%
rename from res/drawable-hdpi/img02.png
rename to safeDispatch/src/main/res/drawable-hdpi/img02.png
diff --git a/res/drawable-hdpi/img03.png b/safeDispatch/src/main/res/drawable-hdpi/img03.png
similarity index 100%
rename from res/drawable-hdpi/img03.png
rename to safeDispatch/src/main/res/drawable-hdpi/img03.png
diff --git a/res/drawable-hdpi/img04.png b/safeDispatch/src/main/res/drawable-hdpi/img04.png
similarity index 100%
rename from res/drawable-hdpi/img04.png
rename to safeDispatch/src/main/res/drawable-hdpi/img04.png
diff --git a/res/drawable-hdpi/ip.png b/safeDispatch/src/main/res/drawable-hdpi/ip.png
similarity index 100%
rename from res/drawable-hdpi/ip.png
rename to safeDispatch/src/main/res/drawable-hdpi/ip.png
diff --git a/res/drawable-hdpi/label.png b/safeDispatch/src/main/res/drawable-hdpi/label.png
similarity index 100%
rename from res/drawable-hdpi/label.png
rename to safeDispatch/src/main/res/drawable-hdpi/label.png
diff --git a/res/drawable-hdpi/label_small.png b/safeDispatch/src/main/res/drawable-hdpi/label_small.png
similarity index 100%
rename from res/drawable-hdpi/label_small.png
rename to safeDispatch/src/main/res/drawable-hdpi/label_small.png
diff --git a/res/drawable-hdpi/loading.xml b/safeDispatch/src/main/res/drawable-hdpi/loading.xml
similarity index 100%
rename from res/drawable-hdpi/loading.xml
rename to safeDispatch/src/main/res/drawable-hdpi/loading.xml
diff --git a/res/drawable-hdpi/login.jpg b/safeDispatch/src/main/res/drawable-hdpi/login.jpg
similarity index 100%
rename from res/drawable-hdpi/login.jpg
rename to safeDispatch/src/main/res/drawable-hdpi/login.jpg
diff --git a/res/drawable-hdpi/login_frame_g.png b/safeDispatch/src/main/res/drawable-hdpi/login_frame_g.png
similarity index 100%
rename from res/drawable-hdpi/login_frame_g.png
rename to safeDispatch/src/main/res/drawable-hdpi/login_frame_g.png
diff --git a/res/drawable-hdpi/login_frame_sn.png b/safeDispatch/src/main/res/drawable-hdpi/login_frame_sn.png
similarity index 100%
rename from res/drawable-hdpi/login_frame_sn.png
rename to safeDispatch/src/main/res/drawable-hdpi/login_frame_sn.png
diff --git a/res/drawable-hdpi/login_frame_vi.png b/safeDispatch/src/main/res/drawable-hdpi/login_frame_vi.png
similarity index 100%
rename from res/drawable-hdpi/login_frame_vi.png
rename to safeDispatch/src/main/res/drawable-hdpi/login_frame_vi.png
diff --git a/res/drawable-hdpi/login_key.png b/safeDispatch/src/main/res/drawable-hdpi/login_key.png
similarity index 100%
rename from res/drawable-hdpi/login_key.png
rename to safeDispatch/src/main/res/drawable-hdpi/login_key.png
diff --git a/res/drawable-hdpi/login_user.png b/safeDispatch/src/main/res/drawable-hdpi/login_user.png
similarity index 100%
rename from res/drawable-hdpi/login_user.png
rename to safeDispatch/src/main/res/drawable-hdpi/login_user.png
diff --git a/res/drawable-hdpi/map.png b/safeDispatch/src/main/res/drawable-hdpi/map.png
similarity index 100%
rename from res/drawable-hdpi/map.png
rename to safeDispatch/src/main/res/drawable-hdpi/map.png
diff --git a/safeDispatch/src/main/res/drawable-hdpi/play.png b/safeDispatch/src/main/res/drawable-hdpi/play.png
new file mode 100644
index 0000000..f3c16d6
Binary files /dev/null and b/safeDispatch/src/main/res/drawable-hdpi/play.png differ
diff --git a/safeDispatch/src/main/res/drawable-hdpi/play_over.png b/safeDispatch/src/main/res/drawable-hdpi/play_over.png
new file mode 100644
index 0000000..dd39132
Binary files /dev/null and b/safeDispatch/src/main/res/drawable-hdpi/play_over.png differ
diff --git a/res/drawable-hdpi/play_pressed.png b/safeDispatch/src/main/res/drawable-hdpi/play_pressed.png
similarity index 100%
rename from res/drawable-hdpi/play_pressed.png
rename to safeDispatch/src/main/res/drawable-hdpi/play_pressed.png
diff --git a/res/drawable-hdpi/questionmark.png b/safeDispatch/src/main/res/drawable-hdpi/questionmark.png
similarity index 100%
rename from res/drawable-hdpi/questionmark.png
rename to safeDispatch/src/main/res/drawable-hdpi/questionmark.png
diff --git a/res/drawable-hdpi/questionmark_small.png b/safeDispatch/src/main/res/drawable-hdpi/questionmark_small.png
similarity index 100%
rename from res/drawable-hdpi/questionmark_small.png
rename to safeDispatch/src/main/res/drawable-hdpi/questionmark_small.png
diff --git a/res/drawable-hdpi/record.png b/safeDispatch/src/main/res/drawable-hdpi/record.png
similarity index 100%
rename from res/drawable-hdpi/record.png
rename to safeDispatch/src/main/res/drawable-hdpi/record.png
diff --git a/res/drawable-hdpi/remote.png b/safeDispatch/src/main/res/drawable-hdpi/remote.png
similarity index 100%
rename from res/drawable-hdpi/remote.png
rename to safeDispatch/src/main/res/drawable-hdpi/remote.png
diff --git a/res/drawable-hdpi/safedispatch.jpg b/safeDispatch/src/main/res/drawable-hdpi/safedispatch.jpg
similarity index 100%
rename from res/drawable-hdpi/safedispatch.jpg
rename to safeDispatch/src/main/res/drawable-hdpi/safedispatch.jpg
diff --git a/res/drawable-hdpi/safedispatch3.jpg b/safeDispatch/src/main/res/drawable-hdpi/safedispatch3.jpg
similarity index 100%
rename from res/drawable-hdpi/safedispatch3.jpg
rename to safeDispatch/src/main/res/drawable-hdpi/safedispatch3.jpg
diff --git a/res/drawable-hdpi/safedispatch_logo.jpg b/safeDispatch/src/main/res/drawable-hdpi/safedispatch_logo.jpg
similarity index 100%
rename from res/drawable-hdpi/safedispatch_logo.jpg
rename to safeDispatch/src/main/res/drawable-hdpi/safedispatch_logo.jpg
diff --git a/res/drawable-hdpi/safenet.jpg b/safeDispatch/src/main/res/drawable-hdpi/safenet.jpg
similarity index 100%
rename from res/drawable-hdpi/safenet.jpg
rename to safeDispatch/src/main/res/drawable-hdpi/safenet.jpg
diff --git a/res/drawable-hdpi/safenet_logo.jpg b/safeDispatch/src/main/res/drawable-hdpi/safenet_logo.jpg
similarity index 100%
rename from res/drawable-hdpi/safenet_logo.jpg
rename to safeDispatch/src/main/res/drawable-hdpi/safenet_logo.jpg
diff --git a/res/drawable-hdpi/satellite.png b/safeDispatch/src/main/res/drawable-hdpi/satellite.png
similarity index 100%
rename from res/drawable-hdpi/satellite.png
rename to safeDispatch/src/main/res/drawable-hdpi/satellite.png
diff --git a/res/drawable-hdpi/screen.png b/safeDispatch/src/main/res/drawable-hdpi/screen.png
similarity index 100%
rename from res/drawable-hdpi/screen.png
rename to safeDispatch/src/main/res/drawable-hdpi/screen.png
diff --git a/res/drawable-hdpi/screen2.png b/safeDispatch/src/main/res/drawable-hdpi/screen2.png
similarity index 100%
rename from res/drawable-hdpi/screen2.png
rename to safeDispatch/src/main/res/drawable-hdpi/screen2.png
diff --git a/res/drawable-hdpi/sel_open.png b/safeDispatch/src/main/res/drawable-hdpi/sel_open.png
similarity index 100%
rename from res/drawable-hdpi/sel_open.png
rename to safeDispatch/src/main/res/drawable-hdpi/sel_open.png
diff --git a/res/drawable-hdpi/siren.png b/safeDispatch/src/main/res/drawable-hdpi/siren.png
similarity index 100%
rename from res/drawable-hdpi/siren.png
rename to safeDispatch/src/main/res/drawable-hdpi/siren.png
diff --git a/res/drawable-hdpi/siren_on.png b/safeDispatch/src/main/res/drawable-hdpi/siren_on.png
similarity index 100%
rename from res/drawable-hdpi/siren_on.png
rename to safeDispatch/src/main/res/drawable-hdpi/siren_on.png
diff --git a/res/drawable-hdpi/status_idle.png b/safeDispatch/src/main/res/drawable-hdpi/status_idle.png
similarity index 100%
rename from res/drawable-hdpi/status_idle.png
rename to safeDispatch/src/main/res/drawable-hdpi/status_idle.png
diff --git a/res/drawable-hdpi/status_offline.png b/safeDispatch/src/main/res/drawable-hdpi/status_offline.png
similarity index 100%
rename from res/drawable-hdpi/status_offline.png
rename to safeDispatch/src/main/res/drawable-hdpi/status_offline.png
diff --git a/res/drawable-hdpi/status_online.png b/safeDispatch/src/main/res/drawable-hdpi/status_online.png
similarity index 100%
rename from res/drawable-hdpi/status_online.png
rename to safeDispatch/src/main/res/drawable-hdpi/status_online.png
diff --git a/res/drawable-hdpi/textboxx.9.png b/safeDispatch/src/main/res/drawable-hdpi/textboxx.9.png
similarity index 100%
rename from res/drawable-hdpi/textboxx.9.png
rename to safeDispatch/src/main/res/drawable-hdpi/textboxx.9.png
diff --git a/res/drawable-hdpi/traffic.png b/safeDispatch/src/main/res/drawable-hdpi/traffic.png
similarity index 100%
rename from res/drawable-hdpi/traffic.png
rename to safeDispatch/src/main/res/drawable-hdpi/traffic.png
diff --git a/res/drawable-hdpi/traffic_off.png b/safeDispatch/src/main/res/drawable-hdpi/traffic_off.png
similarity index 100%
rename from res/drawable-hdpi/traffic_off.png
rename to safeDispatch/src/main/res/drawable-hdpi/traffic_off.png
diff --git a/res/drawable-hdpi/uncheck_all.png b/safeDispatch/src/main/res/drawable-hdpi/uncheck_all.png
similarity index 100%
rename from res/drawable-hdpi/uncheck_all.png
rename to safeDispatch/src/main/res/drawable-hdpi/uncheck_all.png
diff --git a/safeDispatch/src/main/res/drawable-hdpi/unchecked.png b/safeDispatch/src/main/res/drawable-hdpi/unchecked.png
new file mode 100644
index 0000000..310b08b
Binary files /dev/null and b/safeDispatch/src/main/res/drawable-hdpi/unchecked.png differ
diff --git a/res/drawable-hdpi/vision_logo.png b/safeDispatch/src/main/res/drawable-hdpi/vision_logo.png
similarity index 100%
rename from res/drawable-hdpi/vision_logo.png
rename to safeDispatch/src/main/res/drawable-hdpi/vision_logo.png
diff --git a/res/drawable-ldpi/map.png b/safeDispatch/src/main/res/drawable-ldpi/map.png
similarity index 100%
rename from res/drawable-ldpi/map.png
rename to safeDispatch/src/main/res/drawable-ldpi/map.png
diff --git a/res/drawable-ldpi/satellite.png b/safeDispatch/src/main/res/drawable-ldpi/satellite.png
similarity index 100%
rename from res/drawable-ldpi/satellite.png
rename to safeDispatch/src/main/res/drawable-ldpi/satellite.png
diff --git a/res/drawable-mdpi/apply.png b/safeDispatch/src/main/res/drawable-mdpi/apply.png
similarity index 100%
rename from res/drawable-mdpi/apply.png
rename to safeDispatch/src/main/res/drawable-mdpi/apply.png
diff --git a/res/drawable-mdpi/apply_over.png b/safeDispatch/src/main/res/drawable-mdpi/apply_over.png
similarity index 100%
rename from res/drawable-mdpi/apply_over.png
rename to safeDispatch/src/main/res/drawable-mdpi/apply_over.png
diff --git a/res/drawable-mdpi/cancel.png b/safeDispatch/src/main/res/drawable-mdpi/cancel.png
similarity index 100%
rename from res/drawable-mdpi/cancel.png
rename to safeDispatch/src/main/res/drawable-mdpi/cancel.png
diff --git a/res/drawable-mdpi/cancel_over.png b/safeDispatch/src/main/res/drawable-mdpi/cancel_over.png
similarity index 100%
rename from res/drawable-mdpi/cancel_over.png
rename to safeDispatch/src/main/res/drawable-mdpi/cancel_over.png
diff --git a/res/drawable-mdpi/map.png b/safeDispatch/src/main/res/drawable-mdpi/map.png
similarity index 100%
rename from res/drawable-mdpi/map.png
rename to safeDispatch/src/main/res/drawable-mdpi/map.png
diff --git a/res/drawable-mdpi/satellite.png b/safeDispatch/src/main/res/drawable-mdpi/satellite.png
similarity index 100%
rename from res/drawable-mdpi/satellite.png
rename to safeDispatch/src/main/res/drawable-mdpi/satellite.png
diff --git a/res/layout/addmessage_selector.xml b/safeDispatch/src/main/res/drawable/addmessage_selector.xml
similarity index 100%
rename from res/layout/addmessage_selector.xml
rename to safeDispatch/src/main/res/drawable/addmessage_selector.xml
diff --git a/res/layout/buttonbarcode.xml b/safeDispatch/src/main/res/drawable/buttonbarcode.xml
similarity index 100%
rename from res/layout/buttonbarcode.xml
rename to safeDispatch/src/main/res/drawable/buttonbarcode.xml
diff --git a/res/layout/gridalarm_selector.xml b/safeDispatch/src/main/res/drawable/gridalarm_selector.xml
similarity index 100%
rename from res/layout/gridalarm_selector.xml
rename to safeDispatch/src/main/res/drawable/gridalarm_selector.xml
diff --git a/res/layout/gridview_selector.xml b/safeDispatch/src/main/res/drawable/gridview_selector.xml
similarity index 100%
rename from res/layout/gridview_selector.xml
rename to safeDispatch/src/main/res/drawable/gridview_selector.xml
diff --git a/res/layout/hytera_style_button.xml b/safeDispatch/src/main/res/drawable/hytera_style_button.xml
similarity index 100%
rename from res/layout/hytera_style_button.xml
rename to safeDispatch/src/main/res/drawable/hytera_style_button.xml
diff --git a/res/layout/hytera_style_header.xml b/safeDispatch/src/main/res/drawable/hytera_style_header.xml
similarity index 100%
rename from res/layout/hytera_style_header.xml
rename to safeDispatch/src/main/res/drawable/hytera_style_header.xml
diff --git a/res/layout/messageback_selector.xml b/safeDispatch/src/main/res/drawable/messageback_selector.xml
similarity index 100%
rename from res/layout/messageback_selector.xml
rename to safeDispatch/src/main/res/drawable/messageback_selector.xml
diff --git a/res/layout/safedispatch_style_button.xml b/safeDispatch/src/main/res/drawable/safedispatch_style_button.xml
similarity index 100%
rename from res/layout/safedispatch_style_button.xml
rename to safeDispatch/src/main/res/drawable/safedispatch_style_button.xml
diff --git a/res/layout/safedispatch_style_header.xml b/safeDispatch/src/main/res/drawable/safedispatch_style_header.xml
similarity index 100%
rename from res/layout/safedispatch_style_header.xml
rename to safeDispatch/src/main/res/drawable/safedispatch_style_header.xml
diff --git a/res/layout/safenet_style_button.xml b/safeDispatch/src/main/res/drawable/safenet_style_button.xml
similarity index 100%
rename from res/layout/safenet_style_button.xml
rename to safeDispatch/src/main/res/drawable/safenet_style_button.xml
diff --git a/res/layout/safenet_style_header.xml b/safeDispatch/src/main/res/drawable/safenet_style_header.xml
similarity index 100%
rename from res/layout/safenet_style_header.xml
rename to safeDispatch/src/main/res/drawable/safenet_style_header.xml
diff --git a/res/layout/style_bluebutton.xml b/safeDispatch/src/main/res/drawable/style_bluebutton.xml
similarity index 100%
rename from res/layout/style_bluebutton.xml
rename to safeDispatch/src/main/res/drawable/style_bluebutton.xml
diff --git a/res/layout/style_blueradiobutton.xml b/safeDispatch/src/main/res/drawable/style_blueradiobutton.xml
similarity index 100%
rename from res/layout/style_blueradiobutton.xml
rename to safeDispatch/src/main/res/drawable/style_blueradiobutton.xml
diff --git a/res/layout/style_brownbutton.xml b/safeDispatch/src/main/res/drawable/style_brownbutton.xml
similarity index 100%
rename from res/layout/style_brownbutton.xml
rename to safeDispatch/src/main/res/drawable/style_brownbutton.xml
diff --git a/res/layout/style_buttonapply.xml b/safeDispatch/src/main/res/drawable/style_buttonapply.xml
similarity index 100%
rename from res/layout/style_buttonapply.xml
rename to safeDispatch/src/main/res/drawable/style_buttonapply.xml
diff --git a/res/layout/style_buttoncancel.xml b/safeDispatch/src/main/res/drawable/style_buttoncancel.xml
similarity index 100%
rename from res/layout/style_buttoncancel.xml
rename to safeDispatch/src/main/res/drawable/style_buttoncancel.xml
diff --git a/res/layout/style_buttonemergency.xml b/safeDispatch/src/main/res/drawable/style_buttonemergency.xml
similarity index 100%
rename from res/layout/style_buttonemergency.xml
rename to safeDispatch/src/main/res/drawable/style_buttonemergency.xml
diff --git a/res/layout/style_buttonplay.xml b/safeDispatch/src/main/res/drawable/style_buttonplay.xml
similarity index 100%
rename from res/layout/style_buttonplay.xml
rename to safeDispatch/src/main/res/drawable/style_buttonplay.xml
diff --git a/res/layout/style_buttonptt.xml b/safeDispatch/src/main/res/drawable/style_buttonptt.xml
similarity index 100%
rename from res/layout/style_buttonptt.xml
rename to safeDispatch/src/main/res/drawable/style_buttonptt.xml
diff --git a/res/layout/style_buttonptt_green.xml b/safeDispatch/src/main/res/drawable/style_buttonptt_green.xml
similarity index 100%
rename from res/layout/style_buttonptt_green.xml
rename to safeDispatch/src/main/res/drawable/style_buttonptt_green.xml
diff --git a/res/layout/style_buttonptt_pttoff.xml b/safeDispatch/src/main/res/drawable/style_buttonptt_pttoff.xml
similarity index 100%
rename from res/layout/style_buttonptt_pttoff.xml
rename to safeDispatch/src/main/res/drawable/style_buttonptt_pttoff.xml
diff --git a/res/layout/style_buttonptt_red.xml b/safeDispatch/src/main/res/drawable/style_buttonptt_red.xml
similarity index 100%
rename from res/layout/style_buttonptt_red.xml
rename to safeDispatch/src/main/res/drawable/style_buttonptt_red.xml
diff --git a/res/layout/style_buttonsend.xml b/safeDispatch/src/main/res/drawable/style_buttonsend.xml
similarity index 100%
rename from res/layout/style_buttonsend.xml
rename to safeDispatch/src/main/res/drawable/style_buttonsend.xml
diff --git a/res/layout/style_greenbutton.xml b/safeDispatch/src/main/res/drawable/style_greenbutton.xml
similarity index 100%
rename from res/layout/style_greenbutton.xml
rename to safeDispatch/src/main/res/drawable/style_greenbutton.xml
diff --git a/safeDispatch/src/main/res/drawable/style_grid.xml b/safeDispatch/src/main/res/drawable/style_grid.xml
new file mode 100644
index 0000000..dc37d7e
--- /dev/null
+++ b/safeDispatch/src/main/res/drawable/style_grid.xml
@@ -0,0 +1,17 @@
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/style_header.xml b/safeDispatch/src/main/res/drawable/style_header.xml
similarity index 100%
rename from res/layout/style_header.xml
rename to safeDispatch/src/main/res/drawable/style_header.xml
diff --git a/res/layout/style_menu_button_sd.xml b/safeDispatch/src/main/res/drawable/style_menu_button_sd.xml
similarity index 100%
rename from res/layout/style_menu_button_sd.xml
rename to safeDispatch/src/main/res/drawable/style_menu_button_sd.xml
diff --git a/res/layout/style_menu_button_sn.xml b/safeDispatch/src/main/res/drawable/style_menu_button_sn.xml
similarity index 100%
rename from res/layout/style_menu_button_sn.xml
rename to safeDispatch/src/main/res/drawable/style_menu_button_sn.xml
diff --git a/res/layout/style_nameoverlay.xml b/safeDispatch/src/main/res/drawable/style_nameoverlay.xml
similarity index 100%
rename from res/layout/style_nameoverlay.xml
rename to safeDispatch/src/main/res/drawable/style_nameoverlay.xml
diff --git a/safeDispatch/src/main/res/drawable/style_received.xml b/safeDispatch/src/main/res/drawable/style_received.xml
new file mode 100644
index 0000000..f407668
--- /dev/null
+++ b/safeDispatch/src/main/res/drawable/style_received.xml
@@ -0,0 +1,28 @@
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/style_redbutton.xml b/safeDispatch/src/main/res/drawable/style_redbutton.xml
similarity index 100%
rename from res/layout/style_redbutton.xml
rename to safeDispatch/src/main/res/drawable/style_redbutton.xml
diff --git a/res/layout/style_screen.xml b/safeDispatch/src/main/res/drawable/style_screen.xml
similarity index 100%
rename from res/layout/style_screen.xml
rename to safeDispatch/src/main/res/drawable/style_screen.xml
diff --git a/safeDispatch/src/main/res/drawable/style_send.xml b/safeDispatch/src/main/res/drawable/style_send.xml
new file mode 100644
index 0000000..edd9747
--- /dev/null
+++ b/safeDispatch/src/main/res/drawable/style_send.xml
@@ -0,0 +1,28 @@
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/style_sendbutton.xml b/safeDispatch/src/main/res/drawable/style_sendbutton.xml
similarity index 100%
rename from res/layout/style_sendbutton.xml
rename to safeDispatch/src/main/res/drawable/style_sendbutton.xml
diff --git a/res/layout/style_spinner.xml b/safeDispatch/src/main/res/drawable/style_spinner.xml
similarity index 100%
rename from res/layout/style_spinner.xml
rename to safeDispatch/src/main/res/drawable/style_spinner.xml
diff --git a/res/layout/style_toast.xml b/safeDispatch/src/main/res/drawable/style_toast.xml
similarity index 100%
rename from res/layout/style_toast.xml
rename to safeDispatch/src/main/res/drawable/style_toast.xml
diff --git a/res/layout/vision_style_button.xml b/safeDispatch/src/main/res/drawable/vision_style_button.xml
similarity index 100%
rename from res/layout/vision_style_button.xml
rename to safeDispatch/src/main/res/drawable/vision_style_button.xml
diff --git a/res/layout/vision_style_header.xml b/safeDispatch/src/main/res/drawable/vision_style_header.xml
similarity index 100%
rename from res/layout/vision_style_header.xml
rename to safeDispatch/src/main/res/drawable/vision_style_header.xml
diff --git a/res/layout-large/row_livevehicle.xml b/safeDispatch/src/main/res/layout-large/row_livevehicle.xml
similarity index 100%
rename from res/layout-large/row_livevehicle.xml
rename to safeDispatch/src/main/res/layout-large/row_livevehicle.xml
diff --git a/safeDispatch/src/main/res/layout-large/tablive.xml b/safeDispatch/src/main/res/layout-large/tablive.xml
new file mode 100644
index 0000000..7fc4d89
--- /dev/null
+++ b/safeDispatch/src/main/res/layout-large/tablive.xml
@@ -0,0 +1,243 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout-large/tabpanel.xml b/safeDispatch/src/main/res/layout-large/tabpanel.xml
similarity index 100%
rename from res/layout-large/tabpanel.xml
rename to safeDispatch/src/main/res/layout-large/tabpanel.xml
diff --git a/res/layout-large/tabsetup.xml b/safeDispatch/src/main/res/layout-large/tabsetup.xml
similarity index 98%
rename from res/layout-large/tabsetup.xml
rename to safeDispatch/src/main/res/layout-large/tabsetup.xml
index 7466502..63dcebb 100644
--- a/res/layout-large/tabsetup.xml
+++ b/safeDispatch/src/main/res/layout-large/tabsetup.xml
@@ -188,7 +188,7 @@
android:id="@+id/layoutSpinnerLanguage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@layout/style_spinner"
+ android:background="@drawable/style_spinner"
android:gravity="left|center_vertical"
android:minWidth="223dp"
android:orientation="horizontal"
@@ -239,7 +239,7 @@
android:text="@string/save"
style="@style/ButtonText"
android:textSize="26dp"
- android:background="@layout/style_bluebutton"/>
+ android:background="@drawable/style_bluebutton"/>
diff --git a/res/layout-large/tabtext.xml b/safeDispatch/src/main/res/layout-large/tabtext.xml
similarity index 97%
rename from res/layout-large/tabtext.xml
rename to safeDispatch/src/main/res/layout-large/tabtext.xml
index 7b397ac..433085a 100644
--- a/res/layout-large/tabtext.xml
+++ b/safeDispatch/src/main/res/layout-large/tabtext.xml
@@ -67,7 +67,7 @@
android:layout_marginRight="5dp"
android:paddingLeft="2dp"
android:visibility="invisible"
- android:background="@layout/addmessage_selector"/>
+ android:background="@drawable/addmessage_selector"/>
+ android:background="@drawable/addmessage_selector"/>
@@ -116,7 +116,7 @@
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:paddingLeft="2dp"
- android:background="@layout/messageback_selector"/>
+ android:background="@drawable/messageback_selector"/>
+
\ No newline at end of file
diff --git a/res/layout/balloon_overlay.xml b/safeDispatch/src/main/res/layout/balloon_overlay.xml
similarity index 100%
rename from res/layout/balloon_overlay.xml
rename to safeDispatch/src/main/res/layout/balloon_overlay.xml
diff --git a/res/layout/balloonname_overlay.xml b/safeDispatch/src/main/res/layout/balloonname_overlay.xml
similarity index 91%
rename from res/layout/balloonname_overlay.xml
rename to safeDispatch/src/main/res/layout/balloonname_overlay.xml
index b082156..2d0176a 100644
--- a/res/layout/balloonname_overlay.xml
+++ b/safeDispatch/src/main/res/layout/balloonname_overlay.xml
@@ -5,7 +5,7 @@
android:orientation="horizontal"
android:id="@+id/balloon_main_layout"
android:padding="2dp"
- android:background="@layout/style_nameoverlay">
+ android:background="@drawable/style_nameoverlay">
diff --git a/res/layout/dialogdatepicker.xml b/safeDispatch/src/main/res/layout/dialogdatepicker.xml
similarity index 92%
rename from res/layout/dialogdatepicker.xml
rename to safeDispatch/src/main/res/layout/dialogdatepicker.xml
index db71838..3e976bf 100644
--- a/res/layout/dialogdatepicker.xml
+++ b/safeDispatch/src/main/res/layout/dialogdatepicker.xml
@@ -1,63 +1,64 @@
-
-
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/res/layout/dialogimei.xml b/safeDispatch/src/main/res/layout/dialogimei.xml
similarity index 92%
rename from res/layout/dialogimei.xml
rename to safeDispatch/src/main/res/layout/dialogimei.xml
index e6a85cc..41b7dd1 100644
--- a/res/layout/dialogimei.xml
+++ b/safeDispatch/src/main/res/layout/dialogimei.xml
@@ -30,7 +30,7 @@
android:layout_height="wrap_content"
android:gravity="center"
android:layout_weight="1"
- android:background="@layout/style_buttoncancel" />
+ android:background="@drawable/style_buttoncancel" />
+ android:background="@drawable/style_buttonapply"/>
diff --git a/res/layout/dialogip.xml b/safeDispatch/src/main/res/layout/dialogip.xml
similarity index 93%
rename from res/layout/dialogip.xml
rename to safeDispatch/src/main/res/layout/dialogip.xml
index 1dcd706..9feba9a 100644
--- a/res/layout/dialogip.xml
+++ b/safeDispatch/src/main/res/layout/dialogip.xml
@@ -1,80 +1,82 @@
-
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/res/layout/dialogloading.xml b/safeDispatch/src/main/res/layout/dialogloading.xml
similarity index 96%
rename from res/layout/dialogloading.xml
rename to safeDispatch/src/main/res/layout/dialogloading.xml
index 8b6004b..0dd9a14 100644
--- a/res/layout/dialogloading.xml
+++ b/safeDispatch/src/main/res/layout/dialogloading.xml
@@ -43,7 +43,7 @@
android:gravity="center"
android:layout_width="76dp"
android:layout_height="wrap_content"
- android:background="@layout/style_bluebutton"
+ android:background="@drawable/style_bluebutton"
android:text="Cancel"
android:textSize="16dp" />
diff --git a/res/layout/layout.xml b/safeDispatch/src/main/res/layout/layout.xml
similarity index 100%
rename from res/layout/layout.xml
rename to safeDispatch/src/main/res/layout/layout.xml
diff --git a/res/layout/login_h.xml b/safeDispatch/src/main/res/layout/login_h.xml
similarity index 99%
rename from res/layout/login_h.xml
rename to safeDispatch/src/main/res/layout/login_h.xml
index abfca6e..e5b2af1 100644
--- a/res/layout/login_h.xml
+++ b/safeDispatch/src/main/res/layout/login_h.xml
@@ -161,7 +161,7 @@
android:layout_height="wrap_content"
android:layout_alignTop="@+id/btLogin"
android:layout_alignBottom="@+id/btLogin"
- android:background="@layout/style_toast">
+ android:background="@drawable/style_toast">
diff --git a/res/layout/main_before.xml b/safeDispatch/src/main/res/layout/main_before.xml
similarity index 98%
rename from res/layout/main_before.xml
rename to safeDispatch/src/main/res/layout/main_before.xml
index 53a50e2..aed4d79 100644
--- a/res/layout/main_before.xml
+++ b/safeDispatch/src/main/res/layout/main_before.xml
@@ -62,7 +62,7 @@
android:id="@+id/layoutSpinnerUsername"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@layout/style_spinner"
+ android:background="@drawable/style_spinner"
android:gravity="left|center_vertical"
android:minWidth="223dp"
android:orientation="horizontal"
@@ -180,7 +180,7 @@
android:id="@+id/layoutTCP"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@layout/style_toast"
+ android:background="@drawable/style_toast"
android:layout_below="@+id/imageSettings"
android:layout_alignRight="@+id/buttonLogin">
diff --git a/res/layout/mapdemo.xml b/safeDispatch/src/main/res/layout/mapdemo.xml
similarity index 100%
rename from res/layout/mapdemo.xml
rename to safeDispatch/src/main/res/layout/mapdemo.xml
diff --git a/res/layout/menu.xml b/safeDispatch/src/main/res/layout/menu.xml
similarity index 100%
rename from res/layout/menu.xml
rename to safeDispatch/src/main/res/layout/menu.xml
diff --git a/res/layout/menu_old.xml b/safeDispatch/src/main/res/layout/menu_old.xml
similarity index 83%
rename from res/layout/menu_old.xml
rename to safeDispatch/src/main/res/layout/menu_old.xml
index a4ce6e7..96852fa 100644
--- a/res/layout/menu_old.xml
+++ b/safeDispatch/src/main/res/layout/menu_old.xml
@@ -9,7 +9,7 @@
android:layout_width="fill_parent"
android:text="Live"
android:drawableTop="@drawable/ic_tab_live_selected"
- android:background="@layout/style_bluebutton"
+ android:background="@drawable/style_bluebutton"
style="@style/ButtonMenu" />
\ No newline at end of file
diff --git a/res/layout/notification.xml b/safeDispatch/src/main/res/layout/notification.xml
similarity index 100%
rename from res/layout/notification.xml
rename to safeDispatch/src/main/res/layout/notification.xml
diff --git a/res/layout/row_livevehicle.xml b/safeDispatch/src/main/res/layout/row_livevehicle.xml
similarity index 100%
rename from res/layout/row_livevehicle.xml
rename to safeDispatch/src/main/res/layout/row_livevehicle.xml
diff --git a/res/layout/row_vehicle.xml b/safeDispatch/src/main/res/layout/row_vehicle.xml
similarity index 96%
rename from res/layout/row_vehicle.xml
rename to safeDispatch/src/main/res/layout/row_vehicle.xml
index 351519f..0d25493 100644
--- a/res/layout/row_vehicle.xml
+++ b/safeDispatch/src/main/res/layout/row_vehicle.xml
@@ -4,7 +4,7 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="@+id/layoutVehicle"
- android:background="@layout/style_grid">
+ android:background="@drawable/style_grid">
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/style_header_alarm.xml b/safeDispatch/src/main/res/layout/style_header_alarm.xml
similarity index 97%
rename from res/layout/style_header_alarm.xml
rename to safeDispatch/src/main/res/layout/style_header_alarm.xml
index ae41b1e..c780ca1 100644
--- a/res/layout/style_header_alarm.xml
+++ b/safeDispatch/src/main/res/layout/style_header_alarm.xml
@@ -17,7 +17,7 @@
android:layout_marginRight="5dp"
android:paddingLeft="2dp"
android:visibility="invisible"
- android:background="@layout/addmessage_selector"/>
+ android:background="@drawable/addmessage_selector"/>
+ android:background="@drawable/addmessage_selector"/>
@@ -80,7 +80,7 @@
android:background="#999999"
android:drawSelectorOnTop="false"
android:horizontalSpacing="0dp"
- android:listSelector="@layout/gridalarm_selector"
+ android:listSelector="@drawable/gridalarm_selector"
android:numColumns="1"
android:verticalSpacing="1dp"
android:padding="5dp"/>
diff --git a/res/layout/tabempty.xml b/safeDispatch/src/main/res/layout/tabempty.xml
similarity index 100%
rename from res/layout/tabempty.xml
rename to safeDispatch/src/main/res/layout/tabempty.xml
diff --git a/res/layout/tabhistory.xml b/safeDispatch/src/main/res/layout/tabhistory.xml
similarity index 97%
rename from res/layout/tabhistory.xml
rename to safeDispatch/src/main/res/layout/tabhistory.xml
index 9410b46..10a0b62 100644
--- a/res/layout/tabhistory.xml
+++ b/safeDispatch/src/main/res/layout/tabhistory.xml
@@ -72,7 +72,7 @@
android:layout_marginRight="5dp"
android:paddingLeft="2dp"
android:visibility="invisible"
- android:background="@layout/addmessage_selector"/>
+ android:background="@drawable/addmessage_selector"/>
+ android:background="@drawable/style_spinner">
+ android:background="@drawable/style_spinner">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/tabpanel.xml b/safeDispatch/src/main/res/layout/tabpanel.xml
similarity index 100%
rename from res/layout/tabpanel.xml
rename to safeDispatch/src/main/res/layout/tabpanel.xml
diff --git a/res/layout/tabradio.xml b/safeDispatch/src/main/res/layout/tabradio.xml
similarity index 96%
rename from res/layout/tabradio.xml
rename to safeDispatch/src/main/res/layout/tabradio.xml
index 8ae55fd..6f0fc57 100644
--- a/res/layout/tabradio.xml
+++ b/safeDispatch/src/main/res/layout/tabradio.xml
@@ -101,7 +101,7 @@
android:layout_weight="0"
android:layout_marginRight="2dp"
android:paddingLeft="2dp"
- android:background="@layout/addmessage_selector"
+ android:background="@drawable/addmessage_selector"
android:visibility="invisible"/>
+ android:id="@+id/layoutGateway2">
@@ -459,7 +459,7 @@
style="@style/ButtonText"
android:layout_width="135dp"
android:layout_height="wrap_content"
- android:background="@layout/style_bluebutton"
+ android:background="@drawable/style_bluebutton"
android:text="@string/DeKey"
android:textSize="18dp" />
diff --git a/res/layout/tabrecordings.xml b/safeDispatch/src/main/res/layout/tabrecordings.xml
similarity index 96%
rename from res/layout/tabrecordings.xml
rename to safeDispatch/src/main/res/layout/tabrecordings.xml
index 361a78c..a47ca0a 100644
--- a/res/layout/tabrecordings.xml
+++ b/safeDispatch/src/main/res/layout/tabrecordings.xml
@@ -85,7 +85,7 @@
android:layout_marginRight="5dp"
android:paddingLeft="2dp"
android:visibility="invisible"
- android:background="@layout/addmessage_selector"/>
+ android:background="@drawable/addmessage_selector"/>
diff --git a/res/layout/tabsetup.xml b/safeDispatch/src/main/res/layout/tabsetup.xml
similarity index 98%
rename from res/layout/tabsetup.xml
rename to safeDispatch/src/main/res/layout/tabsetup.xml
index 40f9d23..0e0ec86 100644
--- a/res/layout/tabsetup.xml
+++ b/safeDispatch/src/main/res/layout/tabsetup.xml
@@ -192,7 +192,7 @@
android:id="@+id/layoutSpinnerLanguage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@layout/style_spinner"
+ android:background="@drawable/style_spinner"
android:gravity="left|center_vertical"
android:minWidth="223dp"
android:orientation="horizontal"
@@ -243,7 +243,7 @@
android:text="@string/save"
style="@style/ButtonText"
android:textSize="22dp"
- android:background="@layout/style_bluebutton"/>
+ android:background="@drawable/style_bluebutton"/>
diff --git a/res/layout/tabtext.xml b/safeDispatch/src/main/res/layout/tabtext.xml
similarity index 97%
rename from res/layout/tabtext.xml
rename to safeDispatch/src/main/res/layout/tabtext.xml
index d25f6c4..26dcaf3 100644
--- a/res/layout/tabtext.xml
+++ b/safeDispatch/src/main/res/layout/tabtext.xml
@@ -67,7 +67,7 @@
android:layout_marginRight="5dp"
android:paddingLeft="2dp"
android:visibility="invisible"
- android:background="@layout/addmessage_selector"/>
+ android:background="@drawable/addmessage_selector"/>
+ android:background="@drawable/addmessage_selector"/>
+ android:background="@drawable/messageback_selector"/>
+
diff --git a/safeDispatch/src/main/res/values/strings.xml b/safeDispatch/src/main/res/values/strings.xml
new file mode 100644
index 0000000..6630330
--- /dev/null
+++ b/safeDispatch/src/main/res/values/strings.xml
@@ -0,0 +1,257 @@
+
+
+
+ SafeMobile Dispatch
+ SafeMobile Dispatch Demo
+ RadioPod
+ RadioPad
+ RadioPod
+ RadioPad
+ RadioPod Demo
+ RadioPad Demo
+
+
+ AIzaSyB2OFS1zGx3nbfdSZ6tMY_8SRjSsdBzPaU
+ AIzaSyAIOlhfaGsosUk5daB_llTE4NmfDlU5zCs
+ AIzaSyAOTX8FR_0GJs1raKCcRfleEMrlZbwx8uc
+ SWWf2O7SWZMGAMqsJj8Am1x3zdE=
+ AIzaSyDRUP9xUCeercJvOjH26Ig28NP3qeZIwR0
+ AIzaSyANbpEqXiYL6aKawYO0gjkkAHWpZT4Gb8s
+ AIzaSyBJx0dvuoAnWD0dpwjtFljRltU5c85ih20
+
+
+
+ 0LoK1PwpD1-ZVnfSkXoirZJ5eYRYss3tM9b2Abw
+ 0rur5ag6QXrW51ii-CwqK5G-XSwdAe1wPTZDCeg
+ 0LoK1PwpD1-ZVnfSkXoirZJ5eYRYss3tM9b2Abw
+ 0LoK1PwpD1-YhGHazIDazDll3hkm-ReytXVny6A
+ Select Username
+ Language:
+ Select Language
+
+ - Channel1
+ - Channel2
+ - Ch3
+
+
+ - Zone1
+ - Zone2
+
+
+
+ Are you sure you want to exit?
+ Yes
+ Exit
+ Logout
+ No
+ Version
+ e-mail
+ New Message
+ New Alarm
+ Poll Reply
+ From
+ Type
+
+
+ TCP connection is down!
+ Username
+ Password
+ Login
+ Settings
+ Save as Default
+ Cancel
+ OK
+ And the communication port
+ Welcome to SafeDispatch Mobile!\nYou have to set the IP where the APPServer Mobile is installed.
+ Could not load users! Please check the connection and restart.
+ Connection Error
+ Getting users from database…
+ AppServer IP:PORT
+ Enter the IP:PORT combination for the AppServer Mobile.
+
+
+
+ Live
+ Display All
+ Hide All
+ Enable
+ Disable
+ Poll
+ Speed
+ Time
+ Options
+ Getting vehicles from database…
+
+
+ History
+ Vehicle
+ Start Date
+ End Date
+ Display
+ Positions
+ Results for
+ start
+ end
+ Data Error
+ Address
+ Unable to display more the 2000 points, please select smaller interval
+ Info data
+ End date has to be greater than start date
+ You don\'t have data for [x] on interval
+ You have [x] points please wait until all points will be on the map
+ Loading history from database…
+
+
+ Text Messaging
+ Message:
+ Select Vehicle
+ Sending Error
+ Send
+ not ACK
+ Barcode content
+ Barcode Scanner nor installed!
+
+
+ Dekey
+ PTT
+ PTT OFF
+ Emergency
+ Zone
+ Channel
+ Contacts:
+ IP:
+ port
+ ip
+ 127.0.0.1
+ 192.168.10.40
+ Status:
+ Call Type
+ All Call
+ Group Call
+ Private Call
+ Select Channel
+ Select Zone
+ Select Group
+ Offline!
+ Online
+ Hang Time
+
+
+ Name
+ Stop
+
+
+ Alarms
+ Unit Name
+ Alarm Type
+ Description
+ Date and Time
+
+
+ Server Port:
+ Server IP:
+ Save
+ Config File Name:
+ Load
+ Your config file is missing or is invalid! Loading default config file.
+
+
+
+
+ Message is being send…
+ Error on sending message. ACK not received
+ Sending Error
+ Select Contact
+ !!! Emergency !!!
+ Emergency FAILED
+ Emergency STOPED
+ Emergency Stop FAILED
+
+
+ Download completed successfully.
+ Failed to download config file. Verify URL and try again.
+ You must restart application for the changes to take effect!
+ Settings saved successfully.
+ Settings failed to complete!
+ Restart Application
+ Hint
+ Here you enter the serial (eg. 037TMA2845) generated after uploading your config file exported from Motorola CPS [Reports->Detailed Reports->Save As]. You will upload the file to the address: www.safemobile.com/uploadCodeplug.
+
+ English
+ Deutsch
+ Turkish
+ Romanian
+ Russian
+ Spanish
+
+
+
+
+
+
+
+
+
+
+
+
+ - English
+ - German
+ - Romanian
+
+ NewLiveActivity
+ GoogleMapsActivity
+
\ No newline at end of file
diff --git a/res/values/styles.xml b/safeDispatch/src/main/res/values/styles.xml
similarity index 86%
rename from res/values/styles.xml
rename to safeDispatch/src/main/res/values/styles.xml
index 03a057d..ffcc73b 100644
--- a/res/values/styles.xml
+++ b/safeDispatch/src/main/res/values/styles.xml
@@ -21,7 +21,7 @@
@@ -68,11 +68,11 @@
@@ -97,7 +97,7 @@
@@ -170,7 +170,7 @@
@@ -244,7 +244,7 @@
\ No newline at end of file
diff --git a/res/values/themes.xml b/safeDispatch/src/main/res/values/themes.xml
similarity index 87%
rename from res/values/themes.xml
rename to safeDispatch/src/main/res/values/themes.xml
index 7ee1929..78874cf 100644
--- a/res/values/themes.xml
+++ b/safeDispatch/src/main/res/values/themes.xml
@@ -1,7 +1,7 @@
-
+
-
-
-
-