diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2b75303
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..ce889bd
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ xmlns:android
+
+ ^$
+
+
+
+
+
+
+
+
+ xmlns:.*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:id
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ .*:name
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ name
+
+ ^$
+
+
+
+
+
+
+
+
+ style
+
+ ^$
+
+
+
+
+
+
+
+
+ .*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*
+
+ http://schemas.android.com/apk/res/android
+
+
+ ANDROID_ATTRIBUTE_ORDER
+
+
+
+
+
+
+ .*
+
+ .*
+
+
+ BY_NAME
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..79ee123
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dictionaries/gutty.xml b/.idea/dictionaries/gutty.xml
new file mode 100644
index 0000000..f9729e1
--- /dev/null
+++ b/.idea/dictionaries/gutty.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..15a15b2
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..5cd135a
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..a5f05cd
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..37a7509
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
new file mode 100644
index 0000000..7f68460
--- /dev/null
+++ b/.idea/runConfigurations.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index e1baa3f..dd5d81c 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,26 @@
# Prueba técnica - Mobile Team
La prueba tiene como objetivo evaluar tus habilidades como desarrollador.
-# Descripción
-La prueba técnica consiste en desarrollar una pequeña aplicación con las siguientes características.
+# TAREAS
-* La aplicación (emisora) deberá de enviar las coordenadas de la ubicación en la cual el usuario haya presionado durante 3 segundos sobre el mapa. Como confirmación para la aplicación (emisora) se deberá de emitir un [hapatic feedback](https://material.io/design/platform-guidance/android-haptics.html#usage) como confirmación que se envió la ubicación.
-* La aplicación (receptora) deberá de mostrar la coordenada que envió la aplicación (emisora) dentro del mapa con un marcador el cual deberá desaparecer 10 segundos despues de haberse mostrado.
-* Dicha información se deberá enviar en tiempo real usando Firebase Real Time Database.
-* Se da por entendido que la función de emisor y receptor es una sola aplicación, la función se ve definida por la selección en el tab superior como se muestra en la siguiente imagen.
+* Analisis de requerimientos
+* Diseño de mockups
+* Diseño de la arquitectura de app
+* Añadir dependencias
+* Configurar sdk google maps
+* Configurar geocoding API
+* Configurar firebase realtime
+* Configurar Google api location
+* Configurar Retrofit para conectarse a geocoding api
+* Añadir repositorio de datos
+* Crear localizador de servicions para inyección dependendencias
+* Configurar Tabs
+* Configurar mapa
+* Añadir permisos para ubicacion
+* Crear viewmodel
+* Añadir casos de uso
+* Añadir patron obsever para subscribirse a cambios de la bd
+* Añadir patron de factoria para pasar repositorio a viewmodel
+* Configurar lista de ubicaciones enviadas
-
-## Consideraciones generales
-
-- Se deberá escribir un README en donde se describa las tareas que se llevaron a cabo para desarrollar la prueba.
-- Se evaluará la calidad del código, uso de git y practicas de programación, por lo que te recomendamos el código de tu proyecto.
-- Eres libre de mejorar y/o incluir nuevas funcionalidades que demuestren tus habilidades. Ten en cuenta que también evaluaremos las mejoras y funcionalidades que incluyas.
-- El proyecto deberá realizarse en Kotlin y eres libre de agregar dependencias.
-
-## Entrega
-
-Se deberá de hacer un _fork_ a este repositorio, y continuar el desarrollo de la prueba sobre el mismo. Una vez terminada la prueba se deberá hacer un _Pull Request_ al repositorio original.
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..f4ef459
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,65 @@
+apply plugin: 'com.android.application'
+
+apply plugin: 'kotlin-android'
+
+apply plugin: 'kotlin-android-extensions'
+
+apply plugin: 'com.google.gms.google-services'
+
+android {
+ compileSdkVersion 29
+ defaultConfig {
+ applicationId "com.omargtz.mobiletest"
+ minSdkVersion 23
+ targetSdkVersion 29
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ implementation 'androidx.appcompat:appcompat:1.2.0'
+ implementation 'androidx.core:core-ktx:1.3.2'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
+ implementation 'com.google.android.material:material:1.2.1'
+
+ //firebase dababase realtime
+ implementation 'com.google.firebase:firebase-database:19.2.0'
+ implementation 'com.google.firebase:firebase-core:17.2.0'
+
+ //google play services
+ implementation "com.google.android.gms:play-services-maps:$google_play_version"
+ implementation "com.google.android.gms:play-services-location:$google_play_version"
+
+ //Retrofit
+ implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
+ implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
+
+ //lottie animations
+ implementation "com.airbnb.android:lottie:$lottieVersion"
+
+ //Life components
+ implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.archLifecycleVersion"
+ annotationProcessor "androidx.lifecycle:lifecycle-compiler:$rootProject.archLifecycleVersion"
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+
+ //rx
+ implementation "io.reactivex.rxjava2:rxandroid:$rootProject.rxAndroid"
+ implementation "io.reactivex.rxjava2:rxjava:$rootProject.rxJava"
+
+ implementation "com.squareup.retrofit2:adapter-rxjava2:$rootProject.adapterRxjava2"
+
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test:runner:1.2.0'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+
+}
diff --git a/app/google-services.json b/app/google-services.json
new file mode 100644
index 0000000..f551c5d
--- /dev/null
+++ b/app/google-services.json
@@ -0,0 +1,51 @@
+{
+ "project_info": {
+ "project_number": "874193764794",
+ "firebase_url": "https://urbvantest.firebaseio.com",
+ "project_id": "urbvantest",
+ "storage_bucket": "urbvantest.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:874193764794:android:d78f6e2ca7c41f24989d83",
+ "android_client_info": {
+ "package_name": "com.omargtz.mobiletest"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "874193764794-3k243t09hhnfk05rufg8ku4c7gda5uk3.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.omargtz.mobiletest",
+ "certificate_hash": "000458eca3d42f69781225ddbaf34c76548273df"
+ }
+ },
+ {
+ "client_id": "874193764794-h9uf2htm4hb3aqu40qc9iiikn7kr81vi.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyA9l-G1T5QcDKaIuhOpJkjijZZJVkrVoSY"
+ },
+ {
+ "current_key": "AIzaSyB7wn5al8vFkYyKWS1ajXR6GdCILY70vms"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "874193764794-h9uf2htm4hb3aqu40qc9iiikn7kr81vi.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/app/src/androidTest/java/com/omargtz/mobiletest/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/omargtz/mobiletest/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..23b607a
--- /dev/null
+++ b/app/src/androidTest/java/com/omargtz/mobiletest/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.omargtz.mobiletest
+
+import androidx.test.InstrumentationRegistry
+import androidx.test.runner.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getTargetContext()
+ assertEquals("com.omargtz.mobiletest", appContext.packageName)
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..f8f5ae9
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/omargtz/mobiletest/app/App.kt b/app/src/main/java/com/omargtz/mobiletest/app/App.kt
new file mode 100644
index 0000000..abe4ae9
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/app/App.kt
@@ -0,0 +1,21 @@
+package com.omargtz.mobiletest.app
+
+import android.app.Application
+import com.omargtz.mobiletest.data.LocationRepository
+import com.omargtz.mobiletest.utils.ServiceLocator
+
+class App: Application(){
+
+
+ val LocationRepository: LocationRepository
+ get() = ServiceLocator.provideTasksRepository()
+
+ override fun onCreate() {
+ super.onCreate()
+ }
+
+
+}
+
+
+
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/LocationRepository.kt b/app/src/main/java/com/omargtz/mobiletest/data/LocationRepository.kt
new file mode 100644
index 0000000..17c798a
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/LocationRepository.kt
@@ -0,0 +1,14 @@
+package com.omargtz.mobiletest.data
+
+import com.omargtz.mobiletest.data.remote.firebase.FirebaseDbDataSource
+import com.omargtz.mobiletest.data.remote.firebase.model.LocationDTO
+import com.omargtz.mobiletest.data.remote.geocoding.GeocodingDataSource
+import com.omargtz.mobiletest.data.remote.model.GeocodingResponse
+import io.reactivex.Observable
+
+interface LocationRepository {
+
+ fun sendLocation(locationDTO: LocationDTO)
+ fun loadLocations(onGetLocations: FirebaseDbDataSource.OnGetLocations)
+ fun loadDirection(lat: Double,lng: Double): Observable
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/LocationRepositoryImp.kt b/app/src/main/java/com/omargtz/mobiletest/data/LocationRepositoryImp.kt
new file mode 100644
index 0000000..3e4d3e3
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/LocationRepositoryImp.kt
@@ -0,0 +1,25 @@
+package com.omargtz.mobiletest.data
+
+import com.omargtz.mobiletest.data.remote.firebase.FirebaseDbDataSource
+import com.omargtz.mobiletest.data.remote.firebase.model.LocationDTO
+import com.omargtz.mobiletest.data.remote.geocoding.GeocodingDataSource
+import com.omargtz.mobiletest.data.remote.model.GeocodingResponse
+import io.reactivex.Observable
+
+class LocationRepositoryImp(val geocodingDataSource: GeocodingDataSource, val firebaseDatasource: FirebaseDbDataSource ):LocationRepository{
+
+ override fun loadLocations(onGetLocations: FirebaseDbDataSource.OnGetLocations) {
+ firebaseDatasource.receiverLocations(onGetLocations)
+ }
+
+ override fun loadDirection(lat: Double,lng:Double): Observable {
+ return geocodingDataSource.getDirection(lat,lng)
+ }
+
+ override fun sendLocation(locationDTO: LocationDTO) {
+ firebaseDatasource.sendLocation(locationDTO)
+ }
+}
+
+
+
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/firebase/FirebaseDbDataSource.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/firebase/FirebaseDbDataSource.kt
new file mode 100644
index 0000000..b011a5c
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/firebase/FirebaseDbDataSource.kt
@@ -0,0 +1,17 @@
+package com.omargtz.mobiletest.data.remote.firebase
+
+import com.omargtz.mobiletest.data.remote.firebase.model.LocationDTO
+
+interface FirebaseDbDataSource {
+
+ interface OnGetLocations{
+ fun onSucess(locations: List)
+ fun onEmpty()
+ fun onError()
+ }
+
+
+
+ fun sendLocation(location: LocationDTO)
+ fun receiverLocations(onGetLocations: OnGetLocations)
+}
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/firebase/FirebaseDbDataSourceImp.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/firebase/FirebaseDbDataSourceImp.kt
new file mode 100644
index 0000000..cb04d5e
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/firebase/FirebaseDbDataSourceImp.kt
@@ -0,0 +1,40 @@
+package com.omargtz.mobiletest.data.remote.firebase
+
+import com.google.android.gms.tasks.OnSuccessListener
+import com.google.android.gms.tasks.Task
+import com.google.firebase.database.*
+import com.omargtz.mobiletest.data.remote.firebase.model.LocationDTO
+
+class FirebaseDbDataSourceImp(val dbReference: DatabaseReference) :FirebaseDbDataSource{
+
+ private val CHILD = "locations"
+
+ override fun receiverLocations(onGetLocations: FirebaseDbDataSource.OnGetLocations) {
+ val locationListener = object : ValueEventListener{
+ override fun onCancelled(data: DatabaseError) {
+ onGetLocations.onError()
+ }
+ override fun onDataChange(dataSnap: DataSnapshot) {
+ val locations = ArrayList()
+ for (data in dataSnap.children){
+ val location = data.getValue(LocationDTO::class.java)
+ locations.add(location!!)
+ }
+ if(locations.isEmpty()){
+ onGetLocations.onEmpty()
+ }else{
+ onGetLocations.onSucess(locations)
+ }
+ }
+ }
+
+ dbReference.child(CHILD).addValueEventListener(locationListener)
+ }
+
+ override fun sendLocation(location: LocationDTO) {
+ dbReference.child(CHILD).child(location.dateTime.toString()).setValue(location)
+
+ }
+}
+
+
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/firebase/FirebaseService.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/firebase/FirebaseService.kt
new file mode 100644
index 0000000..f1b8872
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/firebase/FirebaseService.kt
@@ -0,0 +1,16 @@
+package com.omargtz.mobiletest.data.remote.firebase
+
+import com.google.firebase.database.DatabaseReference
+import com.google.firebase.database.FirebaseDatabase
+
+object FirebaseService {
+
+ val firebaseDb: FirebaseDatabase
+ get() = FirebaseDatabase.getInstance()
+
+ val dbReference: DatabaseReference
+ get() = firebaseDb.reference
+
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/firebase/model/LocationDTO.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/firebase/model/LocationDTO.kt
new file mode 100644
index 0000000..c15b2e0
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/firebase/model/LocationDTO.kt
@@ -0,0 +1,9 @@
+package com.omargtz.mobiletest.data.remote.firebase.model
+
+data class LocationDTO(
+ val lat: Double? = 0.0,
+ val lng: Double?= 0.0,
+ val direction: String? = "",
+ val dateTime: Long = 0){
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/geocoding/GeocodingDataSource.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/geocoding/GeocodingDataSource.kt
new file mode 100644
index 0000000..4f880b2
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/geocoding/GeocodingDataSource.kt
@@ -0,0 +1,10 @@
+package com.omargtz.mobiletest.data.remote.geocoding
+
+import com.omargtz.mobiletest.data.remote.model.GeocodingResponse
+import io.reactivex.Observable
+
+interface GeocodingDataSource {
+
+ fun getDirection(lat: Double, lng: Double): Observable
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/geocoding/GeocodingDataSourceImp.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/geocoding/GeocodingDataSourceImp.kt
new file mode 100644
index 0000000..9733d50
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/geocoding/GeocodingDataSourceImp.kt
@@ -0,0 +1,17 @@
+package com.omargtz.mobiletest.data.remote.geocoding
+
+import com.omargtz.mobiletest.data.remote.model.GeocodingResponse
+import io.reactivex.Observable
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+import java.lang.StringBuilder
+
+class GeocodingDataSourceImp(private val geocodingApi:GoogleGeocodingApi ):GeocodingDataSource {
+
+ override fun getDirection(lat: Double, lng: Double):Observable{
+ val latLng = StringBuilder().append(lat).append(",").append(lng).toString()
+ return geocodingApi.getDirection(latLng)
+ }
+}
+
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/geocoding/GeocodingService.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/geocoding/GeocodingService.kt
new file mode 100644
index 0000000..83e3d07
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/geocoding/GeocodingService.kt
@@ -0,0 +1,18 @@
+package com.omargtz.mobiletest.data.remote.geocoding
+
+import retrofit2.Retrofit
+import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
+
+import retrofit2.converter.gson.GsonConverterFactory
+
+object GeocodingService {
+
+ val geocodingServiceProvider: GoogleGeocodingApi
+ get() = Retrofit.Builder()
+ .baseUrl("https://maps.googleapis.com/maps/")
+ .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
+ .addConverterFactory(GsonConverterFactory.create())
+ .build()
+ .create(GoogleGeocodingApi::class.java)
+
+}
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/geocoding/GoogleGeocodingApi.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/geocoding/GoogleGeocodingApi.kt
new file mode 100644
index 0000000..76875c3
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/geocoding/GoogleGeocodingApi.kt
@@ -0,0 +1,15 @@
+package com.omargtz.mobiletest.data.remote.geocoding
+
+import com.omargtz.mobiletest.data.remote.model.GeocodingResponse
+import io.reactivex.Observable
+import retrofit2.Call
+import retrofit2.http.GET
+import retrofit2.http.Query
+
+
+interface GoogleGeocodingApi {
+
+ @GET("api/geocode/json?key=AIzaSyBHHlRJ8j6ME__Y4oPv9zx1OLKgH48SQFs")
+ fun getDirection(@Query("latlng") latlng: String): Observable
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/model/AddressComponent.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/AddressComponent.kt
new file mode 100644
index 0000000..2fbe5fa
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/AddressComponent.kt
@@ -0,0 +1,11 @@
+package com.omargtz.mobiletest.data.remote.model
+
+import com.google.gson.annotations.Expose
+import com.google.gson.annotations.SerializedName
+
+
+data class AddressComponent(
+ @SerializedName("long_name") var longName: String?,
+ @SerializedName("short_name") var shortName: String?,
+ @SerializedName("types") var types: List?
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/model/GeocodingResponse.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/GeocodingResponse.kt
new file mode 100644
index 0000000..958bd7a
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/GeocodingResponse.kt
@@ -0,0 +1,11 @@
+package com.omargtz.mobiletest.data.remote.model
+
+import com.google.gson.annotations.Expose
+import com.google.gson.annotations.SerializedName
+
+
+data class GeocodingResponse(
+ @SerializedName("plus_code")var plusCode: PlusCode?,
+ @SerializedName("results") var results: List?,
+ @SerializedName("status") var status:String?
+)
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Geometry.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Geometry.kt
new file mode 100644
index 0000000..253ba71
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Geometry.kt
@@ -0,0 +1,12 @@
+package com.omargtz.mobiletest.data.remote.model
+
+import android.view.View
+
+import com.google.gson.annotations.SerializedName
+
+data class Geometry(
+ @SerializedName("location") var location: Location?,
+ @SerializedName("location_type") var locationType: String?,
+ @SerializedName("viewport") var viewPort: ViewPort?
+)
+
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Location.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Location.kt
new file mode 100644
index 0000000..0dfa0cd
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Location.kt
@@ -0,0 +1,8 @@
+package com.omargtz.mobiletest.data.remote.model
+
+import com.google.gson.annotations.SerializedName
+
+data class Location(
+ @SerializedName("Lat") var lat: Double,
+ @SerializedName("lng") var lng: Double
+)
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Northeast.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Northeast.kt
new file mode 100644
index 0000000..4cf845c
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Northeast.kt
@@ -0,0 +1,8 @@
+package com.omargtz.mobiletest.data.remote.model
+
+import com.google.gson.annotations.SerializedName
+
+data class Northeast(
+ @SerializedName("lat") var lat: Double?,
+ @SerializedName("lng") var lng: Double?
+)
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/model/PlusCode.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/PlusCode.kt
new file mode 100644
index 0000000..32f316b
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/PlusCode.kt
@@ -0,0 +1,8 @@
+package com.omargtz.mobiletest.data.remote.model
+
+import com.google.gson.annotations.SerializedName
+
+data class PlusCode(
+ @SerializedName("compound_code") var compoundCode: String?,
+ @SerializedName("global_code") var globalCode: String?
+)
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Result.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Result.kt
new file mode 100644
index 0000000..205e35a
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Result.kt
@@ -0,0 +1,14 @@
+package com.omargtz.mobiletest.data.remote.model
+
+import com.google.gson.annotations.Expose
+import com.google.gson.annotations.SerializedName
+
+
+data class Result(
+ @SerializedName("address_components") var addressComponents: List?,
+ @SerializedName("formatted_address") var formattedAddress: String?,
+ @SerializedName("geometry") var geometry: Geometry?,
+ @SerializedName("place_id") var placeId: String?,
+ @SerializedName("plus_code") var plusCode: PlusCode?,
+ @SerializedName("types") var types: List?
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Southwest.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Southwest.kt
new file mode 100644
index 0000000..80b592a
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/Southwest.kt
@@ -0,0 +1,8 @@
+package com.omargtz.mobiletest.data.remote.model
+
+import com.google.gson.annotations.SerializedName
+
+data class Southwest(
+ @SerializedName("lat") var lat:Double?,
+ @SerializedName("lng") var lng: Double?
+)
diff --git a/app/src/main/java/com/omargtz/mobiletest/data/remote/model/ViewPort.kt b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/ViewPort.kt
new file mode 100644
index 0000000..3d3adc1
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/data/remote/model/ViewPort.kt
@@ -0,0 +1,8 @@
+package com.omargtz.mobiletest.data.remote.model
+
+import com.google.gson.annotations.SerializedName
+
+data class ViewPort(
+ @SerializedName("northeast") var northeast: Northeast?,
+ @SerializedName("southwest") var southwest: Southwest?
+)
diff --git a/app/src/main/java/com/omargtz/mobiletest/location/view/LocationActivity.kt b/app/src/main/java/com/omargtz/mobiletest/location/view/LocationActivity.kt
new file mode 100644
index 0000000..0663c3e
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/location/view/LocationActivity.kt
@@ -0,0 +1,65 @@
+package com.omargtz.mobiletest.location.view
+
+import android.app.Application
+import android.content.Context
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import android.view.View
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProviders
+import androidx.viewpager.widget.ViewPager
+import com.google.android.material.tabs.TabLayout
+import com.omargtz.mobiletest.R
+import com.omargtz.mobiletest.app.App
+import com.omargtz.mobiletest.location.view.adapter.ViewPagerAdapter
+import com.omargtz.mobiletest.location.view.fragment.TransmitterFragment
+import com.omargtz.mobiletest.location.viewmodel.LocationViewModel
+import com.omargtz.mobiletest.utils.ViewModelFactory
+
+class LocationActivity : AppCompatActivity() {
+
+ private lateinit var toolbar: androidx.appcompat.widget.Toolbar
+ private lateinit var viewModel: LocationViewModel
+ private lateinit var pagerAdapter: ViewPagerAdapter
+
+ val Context.app: App
+ get() = applicationContext as App
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_location)
+ setViewModel()
+ initViews()
+ initToolbar()
+ //setupMap()
+ }
+
+ private fun initViews(){
+ toolbar = findViewById(R.id.home_toolbar)
+
+ }
+
+ private fun initToolbar(){
+ setSupportActionBar(toolbar)
+ supportActionBar?.title = getString(R.string.location_title)
+ }
+
+
+ private fun setViewModel(){
+ val viewModelFactory = ViewModelFactory(app.LocationRepository)
+ viewModel = ViewModelProviders.of(this,viewModelFactory)[LocationViewModel::class.java]
+
+ }
+
+
+
+ private fun setupMap(){
+ supportFragmentManager.beginTransaction()
+ .add(R.id.fragment_content, TransmitterFragment())
+ .commit()
+ }
+
+
+
+}
diff --git a/app/src/main/java/com/omargtz/mobiletest/location/view/adapter/LocationsAdapter.kt b/app/src/main/java/com/omargtz/mobiletest/location/view/adapter/LocationsAdapter.kt
new file mode 100644
index 0000000..6325aad
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/location/view/adapter/LocationsAdapter.kt
@@ -0,0 +1,42 @@
+package com.omargtz.mobiletest.location.view.adapter
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.omargtz.mobiletest.R
+import com.omargtz.mobiletest.data.remote.firebase.model.LocationDTO
+import com.omargtz.mobiletest.location.viewmodel.LocationViewModel
+import kotlinx.android.synthetic.main.item_location.view.*
+
+class LocationsAdapter(var locations: List,val locationViewModel:LocationViewModel):
+ RecyclerView.Adapter() {
+
+ override fun getItemCount(): Int {
+ return locations.size
+ }
+
+ // Inflates the item views
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LocationViewHolder {
+ return LocationViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_location, parent, false))
+ }
+
+ // Binds each animal in the ArrayList to a view
+ override fun onBindViewHolder(holder: LocationViewHolder, position: Int) {
+ holder.tvDirection?.text = locations.get(holder.adapterPosition).direction
+ holder.itemView.setOnClickListener(){
+ _ -> locationViewModel.clickItemLocation(locations.get(holder.adapterPosition))
+ }
+ }
+ public fun updateList(newlocations: List){
+ locations = newlocations
+ notifyDataSetChanged()
+ }
+
+}
+ class LocationViewHolder (view: View) : RecyclerView.ViewHolder(view) {
+ // Holds the TextView that will add each animal to
+ val tvDirection = view.item_tv_direction;
+ }
+
+
diff --git a/app/src/main/java/com/omargtz/mobiletest/location/view/adapter/ViewPagerAdapter.kt b/app/src/main/java/com/omargtz/mobiletest/location/view/adapter/ViewPagerAdapter.kt
new file mode 100644
index 0000000..91c2ce6
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/location/view/adapter/ViewPagerAdapter.kt
@@ -0,0 +1,31 @@
+package com.omargtz.mobiletest.location.view.adapter
+
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentManager
+import androidx.fragment.app.FragmentPagerAdapter
+import com.omargtz.mobiletest.location.view.fragment.ReceiverFragment
+import com.omargtz.mobiletest.location.view.fragment.TransmitterFragment
+
+
+class ViewPagerAdapter(manager: FragmentManager, titles: List): FragmentPagerAdapter(manager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT){
+
+ private val COUNT = 2
+ private val RECEIVER = 0
+ private val TRANSMITTER = 1;
+ private var titles = titles
+
+ override fun getItem(position: Int): Fragment {
+ return when (position) {
+ RECEIVER -> TransmitterFragment()
+ else -> ReceiverFragment()
+ }
+ }
+
+ override fun getPageTitle(position: Int): CharSequence? {
+ return titles[position]
+ }
+
+ override fun getCount(): Int {
+ return titles.size
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omargtz/mobiletest/location/view/fragment/ReceiverFragment.kt b/app/src/main/java/com/omargtz/mobiletest/location/view/fragment/ReceiverFragment.kt
new file mode 100644
index 0000000..ef6404a
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/location/view/fragment/ReceiverFragment.kt
@@ -0,0 +1,162 @@
+package com.omargtz.mobiletest.location.view.fragment
+
+
+import android.location.Location
+import android.os.Bundle
+import android.util.Log
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.lifecycle.Observer
+import androidx.lifecycle.ViewModelProviders
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.google.android.gms.maps.CameraUpdateFactory
+import com.google.android.gms.maps.GoogleMap
+import com.google.android.gms.maps.MapView
+import com.google.android.gms.maps.OnMapReadyCallback
+import com.google.android.gms.maps.model.BitmapDescriptorFactory
+import com.google.android.gms.maps.model.LatLng
+import com.google.android.gms.maps.model.Marker
+import com.google.android.gms.maps.model.MarkerOptions
+
+import com.omargtz.mobiletest.R
+import com.omargtz.mobiletest.data.remote.firebase.model.LocationDTO
+import com.omargtz.mobiletest.location.view.adapter.LocationsAdapter
+import com.omargtz.mobiletest.location.viewmodel.LocationViewModel
+import com.omargtz.mobiletest.utils.Event
+import kotlinx.android.synthetic.*
+
+class ReceiverFragment : Fragment(), OnMapReadyCallback {
+ private lateinit var mapView: MapView
+ private var mMap: GoogleMap? = null
+ private lateinit var viewmodel: LocationViewModel
+ private lateinit var listOfLocations: RecyclerView
+ private lateinit var locationsAdapter: LocationsAdapter
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.fragment_receiver, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ mapView = view.findViewById(R.id.receiver_map_view)
+ listOfLocations = view.findViewById(R.id.list_of_locations)
+ mapView.onCreate(savedInstanceState)
+ mapView.getMapAsync(this)
+
+ }
+
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ viewmodel = ViewModelProviders.of(activity!!)[LocationViewModel::class.java]
+ setupListLocations()
+ subscribeLocationsError()
+ subscribeLoadLocations()
+ subscribeClickItemLocationEvent()
+ }
+
+ override fun onStart() {
+ super.onStart()
+ mapView.onStart()
+
+ }
+
+ override fun onStop() {
+ super.onStop()
+ mapView.onStop()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ mapView.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ mapView.onResume()
+ viewmodel.loadLocations()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ mapView.onDestroy()
+ }
+
+ override fun onLowMemory() {
+ super.onLowMemory()
+ mapView.onLowMemory()
+ }
+
+ override fun onMapReady(googleMap: GoogleMap?) {
+ mMap = googleMap
+ initMap()
+ }
+
+ private fun initMap(){
+ mMap!!.isMyLocationEnabled = true
+ mMap!!.uiSettings.isMyLocationButtonEnabled = true;
+ mMap!!.uiSettings.isCompassEnabled = true
+ }
+
+ private fun moveCamera(lat: Double, lng: Double ){
+ val cameraUpdate = CameraUpdateFactory.newLatLngZoom(LatLng(lat,lng),15.0f)
+ mMap!!.animateCamera(cameraUpdate)
+ }
+
+ fun addMarkers( locations: List) {
+ for (locationDTO in locations){
+ val latLng = LatLng(locationDTO.lat!!,locationDTO.lng!!)
+ mMap!!.addMarker(
+ MarkerOptions()
+ .position(latLng)
+ .title("marker")
+ .draggable(false)
+ .icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_marker)))
+ }
+ }
+
+ private fun setupListLocations(){
+ locationsAdapter = LocationsAdapter(viewmodel.mLocations.value!!,viewmodel)
+ listOfLocations.adapter = locationsAdapter;
+ listOfLocations.layoutManager = LinearLayoutManager(context!!,LinearLayoutManager.HORIZONTAL,false)
+
+ }
+
+ private fun subscribeLoadLocations(){
+ viewmodel.mLocations.observe(this, object : Observer>{
+ override fun onChanged(locations: List?) {
+ if(locations!=null){
+ locationsAdapter.updateList(locations)
+ addMarkers(locations)
+ }
+ }
+ })
+ }
+
+ private fun subscribeLocationsError(){
+ viewmodel.locationErrorEvent.observe(this,object : Observer>{
+ override fun onChanged(event: Event?) {
+ if(event!!.getContentIfNotHandled()!=null){
+ Log.e("Locations","ERROR")
+ }
+ }
+ })
+ }
+
+ private fun subscribeClickItemLocationEvent(){
+ viewmodel.clickLocatinEvent.observe(this,object : Observer>{
+ override fun onChanged(event: Event?) {
+ val locationItem = event!!.getContentIfNotHandled();
+ if(locationItem!=null){
+ moveCamera(locationItem.lat!!,locationItem.lng!!)
+ }
+ }
+ })
+ }
+}
diff --git a/app/src/main/java/com/omargtz/mobiletest/location/view/fragment/TransmitterFragment.kt b/app/src/main/java/com/omargtz/mobiletest/location/view/fragment/TransmitterFragment.kt
new file mode 100644
index 0000000..4f1b450
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/location/view/fragment/TransmitterFragment.kt
@@ -0,0 +1,206 @@
+package com.omargtz.mobiletest.location.view.fragment
+
+
+import android.Manifest
+import android.annotation.SuppressLint
+import android.content.pm.PackageManager
+import android.location.Location
+import android.os.Bundle
+import android.util.Log
+import android.view.Gravity
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.TextView
+import android.widget.Toast
+import androidx.core.content.ContextCompat.checkSelfPermission
+import androidx.lifecycle.Observer
+import androidx.lifecycle.ViewModelProviders
+import com.airbnb.lottie.LottieAnimationView
+import com.google.android.gms.location.FusedLocationProviderClient
+import com.google.android.gms.location.LocationServices
+import com.google.android.gms.maps.CameraUpdateFactory
+import com.google.android.gms.maps.GoogleMap
+import com.google.android.gms.maps.MapView
+import com.google.android.gms.maps.OnMapReadyCallback
+import com.google.android.gms.maps.model.BitmapDescriptorFactory
+import com.google.android.gms.maps.model.LatLng
+import com.google.android.gms.maps.model.Marker
+import com.google.android.gms.maps.model.MarkerOptions
+
+import com.omargtz.mobiletest.R
+import com.omargtz.mobiletest.data.remote.model.GeocodingResponse
+import com.omargtz.mobiletest.location.viewmodel.LocationViewModel
+import com.omargtz.mobiletest.utils.Event
+
+/**
+ * A simple [Fragment] subclass.
+ */
+class TransmitterFragment : Fragment(), OnMapReadyCallback, GoogleMap.OnCameraIdleListener,
+ GoogleMap.OnCameraMoveListener {
+
+ private lateinit var mapView: MapView
+ private var mMap: GoogleMap? = null
+ private lateinit var fusedLocationClient: FusedLocationProviderClient
+ private val LOCATION_PERMISSION = 42
+ private lateinit var viewmodel: LocationViewModel
+ private var marker: Marker? = null
+ private lateinit var btnSendLocation: Button
+ private lateinit var tvDirection: TextView
+ private lateinit var animationSearchLocation: LottieAnimationView
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.fragment_transmitter, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ viewmodel = ViewModelProviders.of(activity!!)[LocationViewModel::class.java]
+ setLocationClient()
+ subscribeLoadDirection()
+ subscribeloadDirectionConnectionErrorEvent()
+ subscribeloadDirectionErrorEvent()
+
+ mapView = view.findViewById(R.id.transmiter_map_view)
+ btnSendLocation = view.findViewById(R.id.btn_send_location);
+
+ btnSendLocation.setOnClickListener(){_->
+ val address = viewmodel.mDirection.value!!.results!!.get(0).formattedAddress!!
+ viewmodel.sendLocation(getLatLngMarker().latitude,getLatLngMarker().longitude,address)
+ Toast.makeText(activity,"Ubicación enviada",Toast.LENGTH_SHORT).show()
+ }
+
+ tvDirection = view.findViewById(R.id.tv_direction)
+ animationSearchLocation = view.findViewById(R.id.animation_search_location)
+ mapView.onCreate(savedInstanceState)
+ mapView.getMapAsync(this)
+ }
+
+ override fun onResume() {
+ super.onResume()
+ mapView.onResume()
+ }
+
+ override fun onStart() {
+ super.onStart()
+ mapView.onStart()
+ }
+
+ override fun onStop() {
+ super.onStop()
+ mapView.onStop()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ mapView.onPause()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ mapView.onDestroy()
+ }
+
+ override fun onLowMemory() {
+ super.onLowMemory()
+ mapView.onLowMemory()
+ }
+
+
+ override fun onMapReady(googleMap: GoogleMap?) {
+ mMap = googleMap
+ if (checkSelfPermission(context!!,Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
+ initMap()
+ getLastLocation()
+ } else {
+ requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
+ LOCATION_PERMISSION)
+ }
+ }
+
+ override fun onCameraIdle() {
+ viewmodel.loadDirection(getLatLngMarker().latitude,getLatLngMarker().longitude)
+ }
+
+ override fun onCameraMove() {
+ addMarker(getLatLngMarker())
+ }
+
+ private fun getLatLngMarker():LatLng{
+ return mMap!!.cameraPosition.target
+ }
+
+ @SuppressLint("MissingPermission")
+ private fun initMap(){
+ mMap!!.isMyLocationEnabled = true
+ mMap!!.uiSettings.isMyLocationButtonEnabled = true;
+ mMap!!.uiSettings.isCompassEnabled = true
+ mMap!!.setOnCameraIdleListener(this)
+ mMap!!.setOnCameraMoveListener(this)
+ }
+
+ private fun setLocationClient(){
+ fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)
+ }
+
+ @SuppressLint("MissingPermission")
+ private fun getLastLocation(){
+ fusedLocationClient.lastLocation.addOnSuccessListener { location : Location ->
+ moveCamera(location)
+ viewmodel.loadDirection(location.latitude,location.longitude)
+ }
+ }
+
+ private fun moveCamera(location: Location){
+ val cameraUpdate = CameraUpdateFactory.newLatLngZoom(LatLng(location.latitude,location.longitude),15.0f)
+ mMap!!.animateCamera(cameraUpdate)
+ }
+
+ fun addMarker(latLng: LatLng) {
+ if(marker==null) {
+ marker = mMap!!.addMarker(MarkerOptions()
+ .position(latLng)
+ .title("marker")
+ .draggable(false)
+ .icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_marker)))
+
+ }else {
+ marker!!.position = latLng
+ }
+ }
+
+ private fun subscribeLoadDirection(){
+ viewmodel.mDirection.observe(this,object : Observer {
+ override fun onChanged(geocodingDirections: GeocodingResponse?) {
+ if(!geocodingDirections!!.results!!.isEmpty()){
+ val address = geocodingDirections.results?.get(0)!!.formattedAddress;
+ tvDirection.setText(address)
+ }
+ }
+ })
+ }
+
+ private fun subscribeloadDirectionErrorEvent(){
+ viewmodel.directionErrorEvent.observe(this,
+ Observer> { event ->
+ if(event!!.getContentIfNotHandled()!=null){
+ Log.e("Direction","Error")
+ }
+ })
+ }
+
+ private fun subscribeloadDirectionConnectionErrorEvent(){
+ viewmodel.directionErrorConnectionEvent.observe(this,
+ Observer> { event ->
+ if(event!!.getContentIfNotHandled()!=null){
+ Log.e("Direction","ErrorConnection")
+ }
+ })
+ }
+}
diff --git a/app/src/main/java/com/omargtz/mobiletest/location/viewmodel/LocationViewModel.kt b/app/src/main/java/com/omargtz/mobiletest/location/viewmodel/LocationViewModel.kt
new file mode 100644
index 0000000..de04da3
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/location/viewmodel/LocationViewModel.kt
@@ -0,0 +1,103 @@
+package com.omargtz.mobiletest.location.viewmodel
+
+import androidx.lifecycle.*
+import com.omargtz.mobiletest.data.LocationRepository
+import com.omargtz.mobiletest.data.remote.firebase.FirebaseDbDataSource
+import com.omargtz.mobiletest.data.remote.firebase.model.LocationDTO
+import com.omargtz.mobiletest.data.remote.geocoding.GeocodingDataSource
+import com.omargtz.mobiletest.data.remote.model.GeocodingResponse
+import com.omargtz.mobiletest.utils.Event
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.CompositeDisposable
+import io.reactivex.disposables.Disposable
+import io.reactivex.schedulers.Schedulers
+import kotlin.math.E
+
+class LocationViewModel(val locationRepository: LocationRepository): ViewModel() {
+
+ private val _mLocations = MutableLiveData>().apply { value = emptyList() }
+ val mLocations: LiveData> = _mLocations
+
+
+ private val _locationErrorConnectionEvent = MutableLiveData>()
+
+ private val _locationErrorEvent = MutableLiveData>()
+ val locationErrorEvent: LiveData> = _locationErrorEvent
+
+ private val _mDirection = MutableLiveData()
+ val mDirection : LiveData = _mDirection
+
+ private val _directionErrorConnectionEvent = MutableLiveData>()
+ val directionErrorConnectionEvent: LiveData> = _directionErrorConnectionEvent
+
+ private val _directionErrorEvent = MutableLiveData>()
+ val directionErrorEvent: LiveData> = _directionErrorEvent
+
+ private val _clickLocationEvent = MutableLiveData>()
+ val clickLocatinEvent : LiveData> = _clickLocationEvent
+
+ private val subscriptions = CompositeDisposable()
+
+
+ public fun clickItemLocation(location: LocationDTO){
+ _clickLocationEvent.value = Event(location)
+ }
+
+ fun sendLocation(lat: Double, lng: Double, direction: String ){
+ val locationRequest = LocationDTO(lat,lng,direction,System.currentTimeMillis());
+ locationRepository.sendLocation(locationRequest)
+ }
+
+ fun loadLocations(){
+ locationRepository.loadLocations(object : FirebaseDbDataSource.OnGetLocations {
+
+ override fun onSucess(locations: List) {
+ _mLocations.value = locations
+ }
+
+ override fun onEmpty() {
+ _locationErrorEvent.value = Event("NO hay ubicaciones")
+ }
+
+ override fun onError() {
+ _locationErrorConnectionEvent.value = Event("Error de conexión")
+ }
+ })
+ }
+
+ fun loadDirection(lat:Double,lng: Double) {
+ val disposable = locationRepository.loadDirection(lat,lng)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .doOnSubscribe {
+
+ }
+ .doOnTerminate {
+
+ }
+ .subscribe ({
+ _mDirection.value = it
+ }, {
+ _locationErrorEvent.value = Event("Error al obtener dirección")
+ })
+
+ subscribe(disposable)
+ }
+
+ fun subscribe(disposable: Disposable): Disposable {
+ subscriptions.add(disposable)
+ return disposable
+ }
+
+ @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
+ fun dispose() {
+ subscriptions.clear()
+ }
+
+ override fun onCleared() {
+ dispose()
+ super.onCleared()
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omargtz/mobiletest/utils/Event.kt b/app/src/main/java/com/omargtz/mobiletest/utils/Event.kt
new file mode 100644
index 0000000..3214d06
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/utils/Event.kt
@@ -0,0 +1,41 @@
+package com.omargtz.mobiletest.utils
+
+import androidx.lifecycle.Observer
+
+open class Event(private val content: T) {
+
+ @Suppress("MemberVisibilityCanBePrivate")
+ var hasBeenHandled = false
+ private set // Allow external read but not write
+
+ /**
+ * Returns the content and prevents its use again.
+ */
+ fun getContentIfNotHandled(): T? {
+ return if (hasBeenHandled) {
+ null
+ } else {
+ hasBeenHandled = true
+ content
+ }
+ }
+
+ /**
+ * Returns the content, even if it's already been handled.
+ */
+ fun peekContent(): T = content
+}
+
+/**
+ * An [Observer] for [Event]s, simplifying the pattern of checking if the [Event]'s content has
+ * already been handled.
+ *
+ * [onEventUnhandledContent] is *only* called if the [Event]'s contents has not been handled.
+ */
+class EventObserver(private val onEventUnhandledContent: (T) -> Unit) : Observer> {
+ override fun onChanged(event: Event?) {
+ event?.getContentIfNotHandled()?.let {
+ onEventUnhandledContent(it)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/omargtz/mobiletest/utils/ServiceLocator.kt b/app/src/main/java/com/omargtz/mobiletest/utils/ServiceLocator.kt
new file mode 100644
index 0000000..9a31530
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/utils/ServiceLocator.kt
@@ -0,0 +1,42 @@
+package com.omargtz.mobiletest.utils
+
+import androidx.annotation.VisibleForTesting
+import com.omargtz.mobiletest.data.LocationRepository
+import com.omargtz.mobiletest.data.LocationRepositoryImp
+import com.omargtz.mobiletest.data.remote.firebase.FirebaseDbDataSource
+import com.omargtz.mobiletest.data.remote.firebase.FirebaseDbDataSourceImp
+import com.omargtz.mobiletest.data.remote.firebase.FirebaseService
+import com.omargtz.mobiletest.data.remote.geocoding.GeocodingDataSource
+import com.omargtz.mobiletest.data.remote.geocoding.GeocodingDataSourceImp
+import com.omargtz.mobiletest.data.remote.geocoding.GeocodingService
+
+object ServiceLocator{
+
+ @Volatile
+ var locationRepository: LocationRepository? = null
+ @VisibleForTesting set
+
+ fun provideTasksRepository(): LocationRepository{
+ synchronized(this) {
+ return locationRepository ?: locationRepository ?: createLocationRepository()
+ }
+ }
+
+
+ fun createLocationRepository():LocationRepository{
+ return LocationRepositoryImp(createGeocodingDataSource(), createFirebaseDataSource())
+ }
+
+
+ fun createGeocodingDataSource(): GeocodingDataSource{
+ return GeocodingDataSourceImp(GeocodingService.geocodingServiceProvider)
+ }
+
+
+ fun createFirebaseDataSource():FirebaseDbDataSource{
+ return FirebaseDbDataSourceImp(FirebaseService.dbReference)
+ }
+
+}
+
+
diff --git a/app/src/main/java/com/omargtz/mobiletest/utils/ViewModelFactory.kt b/app/src/main/java/com/omargtz/mobiletest/utils/ViewModelFactory.kt
new file mode 100644
index 0000000..e376872
--- /dev/null
+++ b/app/src/main/java/com/omargtz/mobiletest/utils/ViewModelFactory.kt
@@ -0,0 +1,22 @@
+package com.omargtz.mobiletest.utils
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.omargtz.mobiletest.data.LocationRepository
+import com.omargtz.mobiletest.location.viewmodel.LocationViewModel
+
+@Suppress("UNCHECKED_CAST")
+class ViewModelFactory constructor(
+ private val locationRepository: LocationRepository
+) : ViewModelProvider.NewInstanceFactory() {
+
+ override fun create(modelClass: Class) =
+ with(modelClass) {
+ when {
+ isAssignableFrom(LocationViewModel::class.java) ->
+ LocationViewModel(locationRepository)
+ else ->
+ throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
+ }
+ } as T
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..6348baa
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/btn_background.xml b/app/src/main/res/drawable/btn_background.xml
new file mode 100644
index 0000000..d80cb28
--- /dev/null
+++ b/app/src/main/res/drawable/btn_background.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..a0ad202
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_location.xml b/app/src/main/res/layout/activity_location.xml
new file mode 100644
index 0000000..0931966
--- /dev/null
+++ b/app/src/main/res/layout/activity_location.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_receiver.xml b/app/src/main/res/layout/fragment_receiver.xml
new file mode 100644
index 0000000..724adde
--- /dev/null
+++ b/app/src/main/res/layout/fragment_receiver.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_transmitter.xml b/app/src/main/res/layout/fragment_transmitter.xml
new file mode 100644
index 0000000..dc13f6f
--- /dev/null
+++ b/app/src/main/res/layout/fragment_transmitter.xml
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_location.xml b/app/src/main/res/layout/item_location.xml
new file mode 100644
index 0000000..394e45c
--- /dev/null
+++ b/app/src/main/res/layout/item_location.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/toolbar.xml b/app/src/main/res/layout/toolbar.xml
new file mode 100644
index 0000000..a4f64a7
--- /dev/null
+++ b/app/src/main/res/layout/toolbar.xml
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..bbd3e02
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..bbd3e02
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..898f3ed
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dffca36
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_marker.png b/app/src/main/res/mipmap-hdpi/ic_marker.png
new file mode 100644
index 0000000..0cf1b5f
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_marker.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..64ba76f
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dae5e08
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_marker.png b/app/src/main/res/mipmap-mdpi/ic_marker.png
new file mode 100644
index 0000000..b991f38
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_marker.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..e5ed465
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..14ed0af
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_marker.png b/app/src/main/res/mipmap-xhdpi/ic_marker.png
new file mode 100644
index 0000000..4bcf886
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_marker.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b0907ca
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..d8ae031
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_marker.png b/app/src/main/res/mipmap-xxhdpi/ic_marker.png
new file mode 100644
index 0000000..f437030
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_marker.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..2c18de9
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..beed3cd
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_marker.png b/app/src/main/res/mipmap-xxxhdpi/ic_marker.png
new file mode 100644
index 0000000..518dac2
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_marker.png differ
diff --git a/app/src/main/res/raw/searcha_location.json b/app/src/main/res/raw/searcha_location.json
new file mode 100644
index 0000000..a3aeb94
--- /dev/null
+++ b/app/src/main/res/raw/searcha_location.json
@@ -0,0 +1 @@
+{"v":"4.6.9","fr":28,"ip":0,"op":70,"w":144,"h":144,"nm":"For_animation 2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"handle2","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":92},"p":{"a":1,"k":[{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":46.01,"s":[72,67.906,0],"e":[72,67.906,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":48.01,"s":[72,67.906,0],"e":[72,73.938,0],"to":[0,1.00520837306976,0],"ti":[0,-0.6875,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":55.01,"s":[72,73.938,0],"e":[72,72.031,0],"to":[0,0.6875,0],"ti":[0,0.31770834326744,0]},{"t":57.009765625}]},"a":{"a":0,"k":[7.639,16.821,0]},"s":{"a":0,"k":[110.147,84.081,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":46.01,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13.098,9.697],[13.169,9.405]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13.098,9.697],[18.893,0.982]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":51.01,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13.098,9.697],[18.893,0.982]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13.098,9.697],[18.212,1.947]],"c":false}]},{"t":53.009765625}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[7.676,16.794],"ix":2},"a":{"a":0,"k":[7.676,16.794],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":46,"op":70,"st":106,"bm":0,"sr":1},{"ddd":0,"ind":2,"ty":4,"nm":"handle","ks":{"o":{"a":0,"k":100},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[0.667]},"o":{"x":[0.167],"y":[0.167]},"n":["0p667_0p667_0p167_0p167"],"t":0,"s":[92],"e":[92]},{"i":{"x":[0.667],"y":[0.941]},"o":{"x":[0.333],"y":[0]},"n":["0p667_0p941_0p333_0"],"t":5,"s":[92],"e":[452]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0.062]},"n":["0p833_1_0p167_0p062"],"t":17,"s":[452],"e":[495]},{"t":20}]},"p":{"a":1,"k":[{"i":{"x":0.667,"y":0.667},"o":{"x":0.167,"y":0.167},"n":"0p667_0p667_0p167_0p167","t":0,"s":[72,72.031,0],"e":[72,72.031,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":8,"s":[72,72.031,0],"e":[72,62.094,0],"to":[0,-1.65625,0],"ti":[0,0.6875,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":12,"s":[72,62.094,0],"e":[72,67.906,0],"to":[0,-0.6875,0],"ti":[0,-2.34375,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":15,"s":[72,67.906,0],"e":[72,76.156,0],"to":[0,2.34375,0],"ti":[0,-1.375,0]},{"t":18}]},"a":{"a":0,"k":[7.639,16.821,0]},"s":{"a":0,"k":[110.147,84.081,100]}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":10,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13.098,9.697],[18.167,2.036]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[13.098,9.697],[13.169,9.405]],"c":false}]},{"t":14}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"st","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"w":{"a":0,"k":5},"lc":2,"lj":1,"ml":4,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke"},{"ty":"tr","p":{"a":0,"k":[7.676,16.794],"ix":2},"a":{"a":0,"k":[7.676,16.794],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":17,"st":61,"bm":0,"sr":1},{"ddd":0,"ind":3,"ty":4,"nm":"mapmarker1","ks":{"o":{"a":0,"k":100},"r":{"a":0,"k":0},"p":{"a":1,"k":[{"i":{"x":0.667,"y":0.667},"o":{"x":0.167,"y":0.167},"n":"0p667_0p667_0p167_0p167","t":0,"s":[72,71.891,0],"e":[72,71.891,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":6,"s":[72,71.891,0],"e":[72,67.641,0],"to":[0,-0.70833331346512,0],"ti":[0,0.70833331346512,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":10,"s":[72,67.641,0],"e":[72,67.641,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":15,"s":[72,67.641,0],"e":[72,75.391,0],"to":[0,1.29166662693024,0],"ti":[0,-0.84375,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":18,"s":[72,75.391,0],"e":[72,72.703,0],"to":[0,0.84375,0],"ti":[0,0.44791665673256,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.167,"y":0.167},"n":"0p667_0p667_0p167_0p167","t":21,"s":[72,72.703,0],"e":[72,72.703,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":39,"s":[72,72.703,0],"e":[72,75.391,0],"to":[0,0.44791665673256,0],"ti":[0,0.84375,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":42,"s":[72,75.391,0],"e":[72,67.641,0],"to":[0,-0.84375,0],"ti":[0,1.29166662693024,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":45,"s":[72,67.641,0],"e":[72,67.641,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":51.02,"s":[72,67.641,0],"e":[72,73.797,0],"to":[0,1.02604162693024,0],"ti":[0,-0.70833331346512,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":55.02,"s":[72,73.797,0],"e":[72,71.891,0],"to":[0,0.70833331346512,0],"ti":[0,0.31770834326744,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0.333},"n":"0p833_0p833_0p333_0p333","t":57.02,"s":[72,71.891,0],"e":[72,71.891,0],"to":[0,0,0],"ti":[0,0,0]},{"t":70.009765625}]},"a":{"a":0,"k":[0,0,0]},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_0p667_0p333_0p333"],"t":6,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[0.667,0.667,0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0.333,0.333,0.333]},"n":["0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":11,"s":[115,115,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_0p667_0p333_0p333"],"t":17,"s":[115,115,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[0.667,0.667,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p667_0p667_0p167_0p167","0p667_0p667_0p167_0p167","0p667_0p667_0p167_0p167"],"t":19,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,0.667]},"o":{"x":[0.167,0.167,0.167],"y":[0,0,0.167]},"n":["0p667_1_0p167_0","0p667_1_0p167_0","0p667_0p667_0p167_0p167"],"t":41,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[0.667,0.667,0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0.333,0.333,0.333]},"n":["0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333","0p667_0p667_0p333_0p333"],"t":43,"s":[115,115,100],"e":[115,115,100]},{"i":{"x":[0.833,0.833,0.833],"y":[1,1,0.833]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0.333]},"n":["0p833_1_0p333_0","0p833_1_0p333_0","0p833_0p833_0p333_0p333"],"t":46.01,"s":[115,115,100],"e":[100,100,100]},{"t":51.009765625}]}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"s","pt":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p667_1_0p167_0p167","t":0,"s":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.123,-5.109],[-5.371,0.178],[-0.088,5.887],[5.621,0.604],[0.338,-5.105]],"c":true}],"e":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.123,-5.109],[-5.371,0.178],[-0.088,5.887],[5.621,0.604],[0.338,-5.105]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":6,"s":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.123,-5.109],[-5.371,0.178],[-0.088,5.887],[5.621,0.604],[0.338,-5.105]],"c":true}],"e":[{"i":[[0.061,0],[0.098,-2.527],[-2.588,-0.1],[-0.1,2.588],[2.588,0.101]],"o":[[-2.507,0],[-0.1,2.588],[2.583,0.1],[0.1,-2.588],[-0.061,-0.002]],"v":[[0.123,-4.298],[-4.569,0.217],[-0.057,5.093],[4.819,0.581],[0.307,-4.295]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":10,"s":[{"i":[[0.061,0],[0.098,-2.527],[-2.588,-0.1],[-0.1,2.588],[2.588,0.101]],"o":[[-2.507,0],[-0.1,2.588],[2.583,0.1],[0.1,-2.588],[-0.061,-0.002]],"v":[[0.123,-4.298],[-4.569,0.217],[-0.057,5.093],[4.819,0.581],[0.307,-4.295]],"c":true}],"e":[{"i":[[0.061,0],[0.098,-2.527],[-2.588,-0.1],[-0.1,2.588],[2.588,0.101]],"o":[[-2.507,0],[-0.1,2.588],[2.583,0.1],[0.1,-2.588],[-0.061,-0.002]],"v":[[0.123,-4.298],[-4.569,0.217],[-0.057,5.093],[4.819,0.581],[0.307,-4.295]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":17,"s":[{"i":[[0.061,0],[0.098,-2.527],[-2.588,-0.1],[-0.1,2.588],[2.588,0.101]],"o":[[-2.507,0],[-0.1,2.588],[2.583,0.1],[0.1,-2.588],[-0.061,-0.002]],"v":[[0.123,-4.298],[-4.569,0.217],[-0.057,5.093],[4.819,0.581],[0.307,-4.295]],"c":true}],"e":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.117,-6.203],[-5.377,-0.916],[-0.094,4.793],[5.615,-0.49],[0.332,-6.199]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":20,"s":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.117,-6.203],[-5.377,-0.916],[-0.094,4.793],[5.615,-0.49],[0.332,-6.199]],"c":true}],"e":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.12,-7.672],[-5.374,-2.385],[-0.09,3.324],[5.619,-1.959],[0.335,-7.668]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":22,"s":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.12,-7.672],[-5.374,-2.385],[-0.09,3.324],[5.619,-1.959],[0.335,-7.668]],"c":true}],"e":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.12,-7.672],[-5.374,-2.385],[-0.09,3.324],[5.619,-1.959],[0.335,-7.668]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":38,"s":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.12,-7.672],[-5.374,-2.385],[-0.09,3.324],[5.619,-1.959],[0.335,-7.668]],"c":true}],"e":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.117,-6.203],[-5.377,-0.916],[-0.094,4.793],[5.615,-0.49],[0.332,-6.199]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":40,"s":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.117,-6.203],[-5.377,-0.916],[-0.094,4.793],[5.615,-0.49],[0.332,-6.199]],"c":true}],"e":[{"i":[[0.061,0],[0.098,-2.527],[-2.588,-0.1],[-0.1,2.588],[2.588,0.101]],"o":[[-2.507,0],[-0.1,2.588],[2.583,0.1],[0.1,-2.588],[-0.061,-0.002]],"v":[[0.123,-4.298],[-4.569,0.217],[-0.057,5.093],[4.819,0.581],[0.307,-4.295]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":43,"s":[{"i":[[0.061,0],[0.098,-2.527],[-2.588,-0.1],[-0.1,2.588],[2.588,0.101]],"o":[[-2.507,0],[-0.1,2.588],[2.583,0.1],[0.1,-2.588],[-0.061,-0.002]],"v":[[0.123,-4.298],[-4.569,0.217],[-0.057,5.093],[4.819,0.581],[0.307,-4.295]],"c":true}],"e":[{"i":[[0.061,0],[0.098,-2.527],[-2.588,-0.1],[-0.1,2.588],[2.588,0.101]],"o":[[-2.507,0],[-0.1,2.588],[2.583,0.1],[0.1,-2.588],[-0.061,-0.002]],"v":[[0.123,-4.298],[-4.569,0.217],[-0.057,5.093],[4.819,0.581],[0.307,-4.295]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":47.01,"s":[{"i":[[0.061,0],[0.098,-2.527],[-2.588,-0.1],[-0.1,2.588],[2.588,0.101]],"o":[[-2.507,0],[-0.1,2.588],[2.583,0.1],[0.1,-2.588],[-0.061,-0.002]],"v":[[0.123,-4.298],[-4.569,0.217],[-0.057,5.093],[4.819,0.581],[0.307,-4.295]],"c":true}],"e":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.123,-5.109],[-5.371,0.178],[-0.088,5.887],[5.621,0.604],[0.338,-5.105]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":51.01,"s":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.123,-5.109],[-5.371,0.178],[-0.088,5.887],[5.621,0.604],[0.338,-5.105]],"c":true}],"e":[{"i":[[0.071,0],[0.114,-2.959],[-3.03,-0.117],[-0.117,3.03],[3.03,0.118]],"o":[[-2.936,0],[-0.117,3.03],[3.025,0.117],[0.117,-3.03],[-0.072,-0.003]],"v":[[0.123,-5.109],[-5.371,0.178],[-0.088,5.887],[5.621,0.604],[0.338,-5.105]],"c":true}]},{"t":70.009765625}]},"o":{"a":0,"k":100},"x":{"a":0,"k":0},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":17,"s":[{"i":[[5.799,0],[0,5.799],[-5.799,0],[0,-5.799]],"o":[[-5.799,0],[0,-5.799],[5.799,0],[0,5.799]],"v":[[0,10.5],[-10.5,0],[0,-10.5],[10.5,0]],"c":true}],"e":[{"i":[[2.42,0],[0,6.051],[-6.014,0],[0,-6.051]],"o":[[-2.42,0],[0,-6.051],[6.014,0],[0,6.051]],"v":[[0,14],[-10.889,-3.044],[0,-14],[10.889,-3.044]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":21,"s":[{"i":[[2.42,0],[0,6.051],[-6.014,0],[0,-6.051]],"o":[[-2.42,0],[0,-6.051],[6.014,0],[0,6.051]],"v":[[0,14],[-10.889,-3.044],[0,-14],[10.889,-3.044]],"c":true}],"e":[{"i":[[2.42,0],[0,6.051],[-6.014,0],[0,-6.051]],"o":[[-2.42,0],[0,-6.051],[6.014,0],[0,6.051]],"v":[[0,14],[-10.889,-3.044],[0,-14],[10.889,-3.044]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":39,"s":[{"i":[[2.42,0],[0,6.051],[-6.014,0],[0,-6.051]],"o":[[-2.42,0],[0,-6.051],[6.014,0],[0,6.051]],"v":[[0,14],[-10.889,-3.044],[0,-14],[10.889,-3.044]],"c":true}],"e":[{"i":[[5.799,0],[0,5.799],[-5.799,0],[0,-5.799]],"o":[[-5.799,0],[0,-5.799],[5.799,0],[0,5.799]],"v":[[0,10.5],[-10.5,0],[0,-10.5],[10.5,0]],"c":true}]},{"t":43}]},"nm":"Path 1","mn":"ADBE Vector Shape - Group"},{"ty":"fl","c":{"a":0,"k":[0,0,0,1]},"o":{"a":0,"k":100},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill"},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group"}],"ip":0,"op":70,"st":-25,"bm":0,"sr":1}]}
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..427ff7e
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,13 @@
+
+
+ #FF5252
+ #00574B
+ #D81B60
+
+ #9A000000
+ #61000000
+ #DF000000
+
+
+
+
diff --git a/app/src/main/res/values/dimen.xml b/app/src/main/res/values/dimen.xml
new file mode 100644
index 0000000..9440d77
--- /dev/null
+++ b/app/src/main/res/values/dimen.xml
@@ -0,0 +1,16 @@
+
+
+
+ 8dp
+ 150dp
+
+ 15sp
+ 56dp
+ 36dp
+
+ 13sp
+ 8dp
+ 12dp
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/google_maps_api.xml b/app/src/main/res/values/google_maps_api.xml
new file mode 100644
index 0000000..2c1e6a9
--- /dev/null
+++ b/app/src/main/res/values/google_maps_api.xml
@@ -0,0 +1,6 @@
+
+
+
+ AIzaSyBHHlRJ8j6ME__Y4oPv9zx1OLKgH48SQFs
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..26f7a9c
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,11 @@
+
+ Mobile-test
+
+
+ Emisor
+ Receptor
+ Mi ubicación
+ Confirmar ubicación
+
+
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5e404d9
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/app/src/test/java/com/omargtz/mobiletest/ExampleUnitTest.kt b/app/src/test/java/com/omargtz/mobiletest/ExampleUnitTest.kt
new file mode 100644
index 0000000..3fed7b9
--- /dev/null
+++ b/app/src/test/java/com/omargtz/mobiletest/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.omargtz.mobiletest
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..cacc27d
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,42 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ ext.kotlin_version = '1.3.50'
+ repositories {
+ google()
+ jcenter()
+
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.5.1'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath 'com.google.gms:google-services:4.3.2'
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
+
+ext {
+
+ archLifecycleVersion = '2.2.0'
+ retrofit_version = "2.5.0"
+ google_play_version = "17.0.0"
+ lottieVersion = "3.1.0"
+ //rx
+ rxAndroid ='2.0.2'
+ rxJava ='2.1.13'
+ adapterRxjava2='2.3.0'
+
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..23339e0
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,21 @@
+# 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.
+org.gradle.jvmargs=-Xmx1536m
+# 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
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..f6b961f
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..b45e3a2
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Oct 23 04:33:05 CDT 2019
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..e95643d
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'