+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index e1baa3f..debd15c 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,27 @@
# Prueba técnica - Mobile Team
-La prueba tiene como objetivo evaluar tus habilidades como desarrollador.
+#### Aplicación para compartir ubicaciones en mapa
+Al dejar pulsado sobre en punto en el mapa de la tab "Enviar", se envían las coordenadas a la base de datos remota. Se pueden enviar multiples ubicaciones a la vez.
+Las ubicaciones enviadas desde la tab "Enviar" podran ser vistas en la tab "Mostrar" de esta app, cada ubicación tiene un ciclo de vida de 10 segundos. Al transcurrir este tiempo, la ubicación desaparecerá.
-# Descripción
-La prueba técnica consiste en desarrollar una pequeña aplicación con las siguientes características.
+#### Bitacora de desarrollo
-* 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.
+ - Fork al proyecto original
+ - Inicialización del proyecto en Android Studio
+ - Analisis de requerimientos
+ - Creación de estructura de carpetas
+ - Creación de fragments y navegación (tabs)
+ - Integración de mapas en los fragments
+ - Definición de modelo Ubicacion
+ - Integración de Firebase y creación de base de datos
+ - Implementación de envio de coordenadas a base de datos
+ - Pintado de ubicaciones guardadas en base de datos
+ - Desarrollo de algoritmo de actualización y borrado de ubicaciones para evitar casos de ConcurrentModificationException
+ - Implementación de Hapatic feedback (vibración)
+
+#### Dependencias y tecnologías
-
-
-## 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.
+ - Material components
+ - Google maps
+ - Firebase core
+ - Firebase database
+ - Kotlin <3
diff --git a/Urbvan mobile test.iml b/Urbvan mobile test.iml
new file mode 100644
index 0000000..4d5a707
--- /dev/null
+++ b/Urbvan mobile test.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
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/app.iml b/app/app.iml
new file mode 100644
index 0000000..1139dce
--- /dev/null
+++ b/app/app.iml
@@ -0,0 +1,211 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ generateDebugSources
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..0079f38
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,41 @@
+apply plugin: 'com.android.application'
+
+apply plugin: 'kotlin-android'
+
+apply plugin: 'kotlin-android-extensions'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.1"
+ defaultConfig {
+ applicationId "com.example.urbvanmobiletest"
+ minSdkVersion 16
+ 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.1.0'
+ implementation 'androidx.core:core-ktx:1.0.2'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'com.google.firebase:firebase-database:19.1.0'
+ testImplementation 'junit:junit:4.12'
+ implementation 'com.google.android.material:material:1.0.0'
+ implementation 'com.google.android.gms:play-services-maps:17.0.0'
+ implementation 'com.google.firebase:firebase-core:17.2.0'
+ androidTestImplementation 'androidx.test:runner:1.2.0'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+}
+
+apply plugin: 'com.google.gms.google-services'
diff --git a/app/google-services.json b/app/google-services.json
new file mode 100644
index 0000000..a03a61a
--- /dev/null
+++ b/app/google-services.json
@@ -0,0 +1,48 @@
+{
+ "project_info": {
+ "project_number": "595639630525",
+ "firebase_url": "https://urbvan-test-d7ae6.firebaseio.com",
+ "project_id": "urbvan-test-d7ae6",
+ "storage_bucket": "urbvan-test-d7ae6.appspot.com"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:595639630525:android:3c174caeca2e136d1e95d4",
+ "android_client_info": {
+ "package_name": "com.example.urbvanmobiletest"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "595639630525-25fhu78qnk3108fngcicrhee7fcvedj7.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.example.urbvanmobiletest",
+ "certificate_hash": "53705739a5a6e211c94ca0a49a4058985bc7e6c0"
+ }
+ },
+ {
+ "client_id": "595639630525-te86eh8dvhf7cvgafh6g4kcd2hs5bgn7.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyCVkMXwwR9VANT4-Wlb3Bsljx4sEVUDtVM"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "595639630525-te86eh8dvhf7cvgafh6g4kcd2hs5bgn7.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/example/urbvanmobiletest/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/urbvanmobiletest/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..81820ba
--- /dev/null
+++ b/app/src/androidTest/java/com/example/urbvanmobiletest/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.example.urbvanmobiletest
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.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.getInstrumentation().targetContext
+ assertEquals("com.example.urbvanmobiletest", appContext.packageName)
+ }
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..e300b17
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/example/urbvanmobiletest/models/MapLocation.kt b/app/src/main/java/com/example/urbvanmobiletest/models/MapLocation.kt
new file mode 100644
index 0000000..8e6551e
--- /dev/null
+++ b/app/src/main/java/com/example/urbvanmobiletest/models/MapLocation.kt
@@ -0,0 +1,16 @@
+package com.example.urbvanmobiletest.models
+
+class MapLocation {
+ var id = ""
+ var latitude = ""
+ var longitude = ""
+ var timeLeft = 10000
+
+ constructor()
+
+ constructor(id: String, latitude: String, longitude: String) {
+ this.id = id
+ this.latitude = latitude
+ this.longitude = longitude
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/urbvanmobiletest/modules/dashboard/adapters/ViewPagerAdapter.kt b/app/src/main/java/com/example/urbvanmobiletest/modules/dashboard/adapters/ViewPagerAdapter.kt
new file mode 100644
index 0000000..616be92
--- /dev/null
+++ b/app/src/main/java/com/example/urbvanmobiletest/modules/dashboard/adapters/ViewPagerAdapter.kt
@@ -0,0 +1,34 @@
+package com.example.urbvanmobiletest.modules.dashboard.adapters
+
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentManager
+import androidx.fragment.app.FragmentPagerAdapter
+import com.example.urbvanmobiletest.modules.receiver.views.ReceiverFragment
+import com.example.urbvanmobiletest.modules.transmitter.views.TransmitterFragment
+
+
+
+class ViewPagerAdapter(manager: FragmentManager): FragmentPagerAdapter(manager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT){
+
+ private val COUNT = 2
+
+ private var titles = ArrayList()
+
+ override fun getItem(position: Int): Fragment {
+
+ return when (position) {
+ 0 -> TransmitterFragment()
+ else -> ReceiverFragment()
+ }
+ }
+
+ override fun getPageTitle(position: Int): CharSequence? {
+ titles.add("Enviar")
+ titles.add("Mostrar")
+ return titles[position]
+ }
+
+ override fun getCount(): Int {
+ return COUNT
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/urbvanmobiletest/modules/dashboard/views/DashboardActivity.kt b/app/src/main/java/com/example/urbvanmobiletest/modules/dashboard/views/DashboardActivity.kt
new file mode 100644
index 0000000..9d992ba
--- /dev/null
+++ b/app/src/main/java/com/example/urbvanmobiletest/modules/dashboard/views/DashboardActivity.kt
@@ -0,0 +1,46 @@
+package com.example.urbvanmobiletest.modules.dashboard.views
+
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import androidx.viewpager.widget.ViewPager
+import com.example.urbvanmobiletest.R
+import com.example.urbvanmobiletest.modules.dashboard.adapters.ViewPagerAdapter
+import com.google.android.material.tabs.TabLayout
+
+class DashboardActivity : AppCompatActivity() {
+
+ private lateinit var toolbar: androidx.appcompat.widget.Toolbar
+
+ private lateinit var pager: ViewPager
+ private lateinit var adapter: ViewPagerAdapter
+
+ private lateinit var tabs: TabLayout
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_dashboard)
+
+ initViews()
+ initToolbar()
+ initViewPager()
+ }
+
+ private fun initViews(){
+ toolbar = findViewById(R.id.toolbar)
+ pager = findViewById(R.id.pager)
+ tabs = findViewById(R.id.tabs)
+ }
+
+ private fun initToolbar(){
+ setSupportActionBar(toolbar)
+ supportActionBar?.title = getString(R.string.toolbar_title)
+ }
+
+ private fun initViewPager(){
+ val fm = supportFragmentManager
+ adapter = ViewPagerAdapter(fm)
+ pager.adapter = adapter
+
+ }
+}
diff --git a/app/src/main/java/com/example/urbvanmobiletest/modules/receiver/presenter/ReceiverPresenter.kt b/app/src/main/java/com/example/urbvanmobiletest/modules/receiver/presenter/ReceiverPresenter.kt
new file mode 100644
index 0000000..51f97c3
--- /dev/null
+++ b/app/src/main/java/com/example/urbvanmobiletest/modules/receiver/presenter/ReceiverPresenter.kt
@@ -0,0 +1,92 @@
+package com.example.urbvanmobiletest.modules.receiver.presenter
+
+import android.os.CountDownTimer
+import com.example.urbvanmobiletest.models.MapLocation
+import com.example.urbvanmobiletest.modules.receiver.views.ReceiverFragment
+import com.google.firebase.FirebaseApp
+import com.google.firebase.database.*
+
+class ReceiverPresenter(val view: ReceiverFragment, val delegate: OnEventInReceiver) {
+
+ private lateinit var database: FirebaseDatabase
+ private lateinit var databaseReference: DatabaseReference
+
+ private var locations = ArrayList()
+ private var activeLocations = ArrayList()
+
+ private var countDownTimer: CountDownTimer? = null
+
+ private val DB_ROOT_NODE = "Locations"
+ private val ID_KEY = "id"
+ private val LATITUDE_KEY = "latitude"
+ private val LONGITUDE_KEY = "longitude"
+
+ private val TIME = 100000L
+
+ fun initFirebase(){
+ view.context?.let {
+ FirebaseApp.initializeApp(it)
+ }
+ database = FirebaseDatabase.getInstance()
+ databaseReference = database.reference
+
+ setLocationListener()
+ }
+
+ fun initTimeCounter(){
+ if (countDownTimer == null){
+ countDownTimer = object : CountDownTimer(TIME, 1000) {
+ override fun onTick(millisUntilFinished: Long) {
+ for (location in locations){
+ if (location.timeLeft == 0){
+ deleteLocationFromDatabase(location.id)
+ activeLocations.remove(location)
+ }
+ else{
+ location.timeLeft -= 1000
+ if (!activeLocations.contains(location)){
+ activeLocations.add(location)
+ }
+ }
+ delegate.onChangeInLocations(activeLocations)
+ }
+ }
+
+ override fun onFinish() {
+ initTimeCounter()
+ }
+ }
+ }
+ countDownTimer?.start()
+ }
+
+ private fun setLocationListener(){
+ databaseReference.child(DB_ROOT_NODE).addValueEventListener(object: ValueEventListener{
+ override fun onDataChange(data: DataSnapshot) {
+ for (item in data.children){
+ addLocation(item)
+ }
+ }
+ override fun onCancelled(p0: DatabaseError) {
+ delegate.onError()
+ }
+ })
+ }
+
+ private fun addLocation(item: DataSnapshot){
+ val location = MapLocation()
+ location.id = item.child(ID_KEY).value as String
+ location.latitude = item.child(LATITUDE_KEY).value as String
+ location.longitude = item.child(LONGITUDE_KEY).value as String
+ locations.add(location)
+ }
+
+ private fun deleteLocationFromDatabase(id: String){
+ databaseReference.child(DB_ROOT_NODE).child(id).removeValue()
+ }
+
+ interface OnEventInReceiver{
+ fun onChangeInLocations(locations: ArrayList)
+ fun onError()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/urbvanmobiletest/modules/receiver/views/ReceiverFragment.kt b/app/src/main/java/com/example/urbvanmobiletest/modules/receiver/views/ReceiverFragment.kt
new file mode 100644
index 0000000..b39edee
--- /dev/null
+++ b/app/src/main/java/com/example/urbvanmobiletest/modules/receiver/views/ReceiverFragment.kt
@@ -0,0 +1,79 @@
+package com.example.urbvanmobiletest.modules.receiver.views
+
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+
+import com.example.urbvanmobiletest.R
+import com.example.urbvanmobiletest.models.MapLocation
+import com.example.urbvanmobiletest.modules.receiver.presenter.ReceiverPresenter
+import com.example.urbvanmobiletest.utils.AlertUtils
+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.LatLng
+import com.google.android.gms.maps.model.Marker
+import com.google.android.gms.maps.model.MarkerOptions
+
+class ReceiverFragment : Fragment(), OnMapReadyCallback, ReceiverPresenter.OnEventInReceiver {
+
+ private lateinit var presenter: ReceiverPresenter
+
+ private lateinit var mapView: MapView
+ private var mMap: GoogleMap? = null
+
+ val DEFAULT_LATITUDE = 19.416058
+ val DEFAULT_LONGITUDE = -99.163625
+ val DEFAULT_ZOOM = 15f
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+
+ val view = inflater.inflate(R.layout.fragment_receiver, container, false)
+
+ return view
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ presenter = ReceiverPresenter(this, this)
+
+ presenter.initFirebase()
+ presenter.initTimeCounter()
+
+ initMap()
+ }
+
+ private fun initMap(){
+ mapView = view?.findViewById(R.id.map_view) as MapView
+
+ mapView.onCreate(null)
+ mapView.onResume()
+ mapView.getMapAsync(this)
+ }
+
+ override fun onMapReady(map: GoogleMap?) {
+ mMap = map
+ val myPlace = LatLng(DEFAULT_LATITUDE, DEFAULT_LONGITUDE)
+ map?.moveCamera(CameraUpdateFactory.newLatLngZoom(myPlace,DEFAULT_ZOOM))
+ }
+
+ override fun onChangeInLocations(locations: ArrayList) {
+ mMap?.clear()
+
+ for(location in locations){
+ val latLng = LatLng(location.latitude.toDouble(),location.longitude.toDouble())
+ val markerOptions = MarkerOptions().position(latLng)
+ mMap?.addMarker(markerOptions)
+ }
+ }
+
+ override fun onError() {
+ context?.let { AlertUtils.makeToast(it,it.getString(R.string.error_message)) }
+ }
+}
diff --git a/app/src/main/java/com/example/urbvanmobiletest/modules/transmitter/presenter/TransmitterPresenter.kt b/app/src/main/java/com/example/urbvanmobiletest/modules/transmitter/presenter/TransmitterPresenter.kt
new file mode 100644
index 0000000..994d340
--- /dev/null
+++ b/app/src/main/java/com/example/urbvanmobiletest/modules/transmitter/presenter/TransmitterPresenter.kt
@@ -0,0 +1,32 @@
+package com.example.urbvanmobiletest.modules.transmitter.presenter
+
+import com.example.urbvanmobiletest.models.MapLocation
+import com.example.urbvanmobiletest.modules.transmitter.views.TransmitterFragment
+import com.google.firebase.FirebaseApp
+import com.google.firebase.database.DatabaseReference
+import com.google.firebase.database.FirebaseDatabase
+
+class TransmitterPresenter (val view: TransmitterFragment, val delegate: OnEventInTransmitter){
+
+ private lateinit var database: FirebaseDatabase
+ private lateinit var databaseReference: DatabaseReference
+
+ private val DB_ROOT_NODE = "Locations"
+
+ fun initFirebase(){
+ view.context?.let {
+ FirebaseApp.initializeApp(it)
+ }
+ database = FirebaseDatabase.getInstance()
+ databaseReference = database.reference
+ }
+
+ fun sendLocationToDataBase(location: MapLocation){
+ databaseReference.child(DB_ROOT_NODE).child(location.id).setValue(location)
+ delegate.onLocationSended()
+ }
+
+ interface OnEventInTransmitter{
+ fun onLocationSended()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/urbvanmobiletest/modules/transmitter/views/TransmitterFragment.kt b/app/src/main/java/com/example/urbvanmobiletest/modules/transmitter/views/TransmitterFragment.kt
new file mode 100644
index 0000000..a2276e4
--- /dev/null
+++ b/app/src/main/java/com/example/urbvanmobiletest/modules/transmitter/views/TransmitterFragment.kt
@@ -0,0 +1,98 @@
+package com.example.urbvanmobiletest.modules.transmitter.views
+
+
+import android.content.Context
+import android.os.*
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewGroup
+
+import com.example.urbvanmobiletest.R
+import com.example.urbvanmobiletest.models.MapLocation
+import com.example.urbvanmobiletest.modules.transmitter.presenter.TransmitterPresenter
+import com.example.urbvanmobiletest.utils.AlertUtils
+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.LatLng
+import java.util.*
+
+class TransmitterFragment : Fragment(), OnMapReadyCallback, GoogleMap.OnMapClickListener, GoogleMap.OnMapLongClickListener, TransmitterPresenter.OnEventInTransmitter {
+
+ private lateinit var presenter: TransmitterPresenter
+
+ private lateinit var mapView: MapView
+ private var mMap: GoogleMap? = null
+
+ val DEFAULT_LATITUDE = 19.416058
+ val DEFAULT_LONGITUDE = -99.163625
+ val DEFAULT_ZOOM = 15f
+
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+
+ val view = inflater.inflate(R.layout.fragment_transmitter, container, false)
+
+ return view
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ presenter = TransmitterPresenter(this, this)
+
+ presenter.initFirebase()
+
+ initMap()
+ }
+
+ private fun initMap(){
+ mapView = view?.findViewById(R.id.map_view) as MapView
+
+ mapView.onCreate(null)
+ mapView.onResume()
+ mapView.getMapAsync(this)
+
+
+ }
+
+ override fun onMapReady(map: GoogleMap?) {
+ mMap = map
+
+ mMap?.setOnMapLongClickListener(this)
+ mMap?.setOnMapClickListener(this)
+
+ val myPlace = LatLng(DEFAULT_LATITUDE, DEFAULT_LONGITUDE)
+ mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(myPlace,DEFAULT_ZOOM))
+ }
+
+ override fun onMapClick(position: LatLng?) {
+ context?.let {
+ AlertUtils.makeToast(it,getString(R.string.keep_press_to_send))
+ }
+ }
+
+ override fun onMapLongClick(position: LatLng?) {
+ vibratePhone()
+ val location = MapLocation(UUID.randomUUID().toString(),position?.latitude.toString(),position?.longitude.toString())
+ presenter.sendLocationToDataBase(location)
+ }
+
+ override fun onLocationSended() {
+ context?.let {
+ AlertUtils.makeToast(it,getString(R.string.location_sended))
+ }
+ }
+
+ private fun Fragment.vibratePhone() {
+ val vibrator = context?.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
+ if (Build.VERSION.SDK_INT >= 26) {
+ vibrator.vibrate(VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE))
+ } else {
+ vibrator.vibrate(200)
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/urbvanmobiletest/utils/AlertUtils.kt b/app/src/main/java/com/example/urbvanmobiletest/utils/AlertUtils.kt
new file mode 100644
index 0000000..78cae83
--- /dev/null
+++ b/app/src/main/java/com/example/urbvanmobiletest/utils/AlertUtils.kt
@@ -0,0 +1,11 @@
+package com.example.urbvanmobiletest.utils
+
+import android.content.Context
+import android.widget.Toast
+
+object AlertUtils {
+
+ fun makeToast(context: Context, message: String){
+ Toast.makeText(context,message,Toast.LENGTH_SHORT).show()
+ }
+}
\ 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..1f6bb29
--- /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/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..0d025f9
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_dashboard.xml b/app/src/main/res/layout/activity_dashboard.xml
new file mode 100644
index 0000000..a967cd3
--- /dev/null
+++ b/app/src/main/res/layout/activity_dashboard.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ 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..eddbc64
--- /dev/null
+++ b/app/src/main/res/layout/fragment_receiver.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ 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..77da263
--- /dev/null
+++ b/app/src/main/res/layout/fragment_transmitter.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/toolbar.xml b/app/src/main/res/layout/toolbar.xml
new file mode 100644
index 0000000..f0f1c59
--- /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..eca70cf
--- /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..eca70cf
--- /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-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-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-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-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/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..9ae2f90
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #FFFF
+ #9E9E9E
+ #d5333d
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..222a624
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,13 @@
+
+ Urbvan mobile test
+ AIzaSyBKYHVDvJysre-AcAWThrr-ofuThhO_5pE
+ Mantén presionado para enviar tu ubicación
+ Location Sender
+ La ubicación ha sido enviada
+ Ocurrió un error inesperado
+
+
+ Enviar
+ Mostrar
+
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..0eb88fe
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/app/src/test/java/com/example/urbvanmobiletest/ExampleUnitTest.kt b/app/src/test/java/com/example/urbvanmobiletest/ExampleUnitTest.kt
new file mode 100644
index 0000000..f1575c0
--- /dev/null
+++ b/app/src/test/java/com/example/urbvanmobiletest/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.urbvanmobiletest
+
+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..b78eab1
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,29 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ ext.kotlin_version = '1.3.41'
+ repositories {
+ google()
+ jcenter()
+
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.5.0'
+ 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
+}
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..c1ada69
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Tue Oct 08 17:28:42 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..f955316
--- /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/local.properties b/local.properties
new file mode 100644
index 0000000..d307d03
--- /dev/null
+++ b/local.properties
@@ -0,0 +1,10 @@
+## This file is automatically generated by Android Studio.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file should *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+#
+# Location of the SDK. This is only used by Gradle.
+# For customization when using a Version Control System, please read the
+# header note.
+sdk.dir=/Users/saulgargar/Library/Android/sdk
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..ddafcde
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,2 @@
+include ':app'
+rootProject.name='Urbvan mobile test'