diff --git a/trazador/.gitignore b/trazador/.gitignore new file mode 100644 index 0000000..c6cbe56 --- /dev/null +++ b/trazador/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/trazador/.idea/compiler.xml b/trazador/.idea/compiler.xml new file mode 100644 index 0000000..96cc43e --- /dev/null +++ b/trazador/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trazador/.idea/copyright/profiles_settings.xml b/trazador/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..e7bedf3 --- /dev/null +++ b/trazador/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/trazador/.idea/encodings.xml b/trazador/.idea/encodings.xml new file mode 100644 index 0000000..97626ba --- /dev/null +++ b/trazador/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/trazador/.idea/gradle.xml b/trazador/.idea/gradle.xml new file mode 100644 index 0000000..cd2ead8 --- /dev/null +++ b/trazador/.idea/gradle.xml @@ -0,0 +1,24 @@ + + + + + + \ No newline at end of file diff --git a/trazador/.idea/misc.xml b/trazador/.idea/misc.xml new file mode 100644 index 0000000..5d19981 --- /dev/null +++ b/trazador/.idea/misc.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trazador/.idea/modules.xml b/trazador/.idea/modules.xml new file mode 100644 index 0000000..67de8c2 --- /dev/null +++ b/trazador/.idea/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/trazador/.idea/runConfigurations.xml b/trazador/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/trazador/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/trazador/.idea/vcs.xml b/trazador/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/trazador/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/trazador/README.md b/trazador/README.md new file mode 100644 index 0000000..7e7f9d4 --- /dev/null +++ b/trazador/README.md @@ -0,0 +1,31 @@ +# Trazador + +![](http://s.pictub.club/2016/11/29/NcrRi.png) + +## Generar el APK + +Correr el comando + +``` +gradle assemble +``` + +Esto generará el APK en el folder /build/apk/ + +## Características del app + + +1. Grabar una ruta con puntos y paradas +2. Descartas o finalizar un ruta +3. Agregar metadatos a la ruta + + +## Por hacer + + +1. Prevenir problemas de pérdida de datos de ubicación debido a una pérdida de coneccion con el servidor. +2. Separar el SDK para conectarse al servidor del App para poder utilizarlo en otros proyectos. +3. Refactorizar codigo para adaptarlo a estándares adecuados. +6. Dibujar al trazado de ruta sobre el mapa + + diff --git a/trazador/app/.gitignore b/trazador/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/trazador/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/trazador/app/build.gradle b/trazador/app/build.gradle new file mode 100644 index 0000000..e9f05f1 --- /dev/null +++ b/trazador/app/build.gradle @@ -0,0 +1,54 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 24 + buildToolsVersion "24.0.2" + defaultConfig { + applicationId "com.example.xavi.trazador_v10" + minSdkVersion 16 + targetSdkVersion 24 + versionCode 1 + versionName "1.0" + vectorDrawables.useSupportLibrary = true + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + productFlavors { + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + testCompile 'junit:junit:4.12' + + compile 'com.google.code.gson:gson:2.6.2' + compile 'com.squareup.okhttp3:okhttp:3.4.2' + compile 'com.android.support:appcompat-v7:24.2.1' + compile 'com.jakewharton.threetenabp:threetenabp:1.0.4' + + compile 'com.android.support:appcompat-v7:24.2.0' + + compile 'com.android.support:design:24.2.0' + + compile 'org.osmdroid:osmdroid-android:5.5:release@aar' + + compile 'com.github.MKergall:osmbonuspack:6.0' + + compile ('com.mapbox.mapboxsdk:mapbox-android-sdk:4.2.0-beta.4@aar'){ + transitive=true + } + + + +} + + + + + + + diff --git a/trazador/app/proguard-rules.pro b/trazador/app/proguard-rules.pro new file mode 100644 index 0000000..28c9d78 --- /dev/null +++ b/trazador/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /home/xavi/Android/Sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# 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 *; +#} diff --git a/trazador/app/src/androidTest/java/com/example/xavi/trazador_v10/ApplicationTest.java b/trazador/app/src/androidTest/java/com/example/xavi/trazador_v10/ApplicationTest.java new file mode 100644 index 0000000..6a6ed82 --- /dev/null +++ b/trazador/app/src/androidTest/java/com/example/xavi/trazador_v10/ApplicationTest.java @@ -0,0 +1,13 @@ +package com.example.xavi.trazador_v10; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/trazador/app/src/main/AndroidManifest.xml b/trazador/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..4ed4fe4 --- /dev/null +++ b/trazador/app/src/main/AndroidManifest.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trazador/app/src/main/btn_savemetadata-web.png b/trazador/app/src/main/btn_savemetadata-web.png new file mode 100644 index 0000000..e46a8a0 Binary files /dev/null and b/trazador/app/src/main/btn_savemetadata-web.png differ diff --git a/trazador/app/src/main/ic_launcher-web.png b/trazador/app/src/main/ic_launcher-web.png new file mode 100644 index 0000000..3106933 Binary files /dev/null and b/trazador/app/src/main/ic_launcher-web.png differ diff --git a/trazador/app/src/main/java/com/example/xavi/trazador_v10/Finalize.java b/trazador/app/src/main/java/com/example/xavi/trazador_v10/Finalize.java new file mode 100644 index 0000000..2e479fb --- /dev/null +++ b/trazador/app/src/main/java/com/example/xavi/trazador_v10/Finalize.java @@ -0,0 +1,64 @@ +package com.example.xavi.trazador_v10; + +import android.content.Intent; +import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; +import android.widget.Toast; + +public class Finalize extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_finalize); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + FloatingActionButton guardar = (FloatingActionButton) findViewById(R.id.btn_guardar); + FloatingActionButton cancelar = (FloatingActionButton) findViewById(R.id.btn_cancelar); + + + + guardar.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + MainActivity.state = 0; + Toast.makeText(getBaseContext(), "Fin de ruta", Toast.LENGTH_SHORT).show(); + MainActivity.btnInicio.setBackgroundResource(R.drawable.btn_iniciar); + + MainActivity.trace.finished(); + Intent intent = new Intent(); + setResult(RESULT_OK, intent); + clearMapMarks(); + finish(); + + } + }); + cancelar.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + MainActivity.state = 0; + Toast.makeText(getBaseContext(), "Fin de ruta", Toast.LENGTH_SHORT).show(); + MainActivity.btnInicio.setBackgroundResource(R.drawable.btn_iniciar); + clearMapMarks(); + MainActivity.trace.discarded(); + Intent intent = new Intent(); + setResult(RESULT_OK, intent); + finish(); + + } + }); + } + + private void clearMapMarks() { + for (int x = 0; x< MainActivity.points.size() ; x++ ){ + MainActivity.map.getOverlays().remove(MainActivity.points.get(x)); + } + MainActivity.points.clear(); + } + +} diff --git a/trazador/app/src/main/java/com/example/xavi/trazador_v10/GPS_Service.java b/trazador/app/src/main/java/com/example/xavi/trazador_v10/GPS_Service.java new file mode 100644 index 0000000..230b40a --- /dev/null +++ b/trazador/app/src/main/java/com/example/xavi/trazador_v10/GPS_Service.java @@ -0,0 +1,142 @@ +package com.example.xavi.trazador_v10; + + +import android.Manifest; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Bundle; +import android.os.IBinder; +import android.provider.Settings; +import android.support.annotation.Nullable; + +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.support.v4.content.res.ResourcesCompat; +import android.widget.Toast; + +import com.mapbox.mapboxsdk.geometry.LatLng; + +import org.osmdroid.util.GeoPoint; +import org.osmdroid.views.overlay.Marker; + +/** + * Created by xavi on 29/09/16. + */ +public class GPS_Service extends Service { + + private LocationListener listener; + private LocationManager locationManager; + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + + @Override + public void onCreate() { + + + listener = new LocationListener() { + @Override + public void onLocationChanged(Location location) { + Intent i = new Intent("location_update"); + //i.putExtra("coordinates",location.getLongitude() + " " + location.getLatitude()); + + double latitude = location.getLatitude(); + double longitude = location.getLongitude(); + LatLng newPosition = new LatLng(latitude, longitude); + + i.putExtra("latitude", latitude); + i.putExtra("longitude", longitude); + i.putExtra("coordinates", location.getLongitude() + " " + location.getLatitude()); + i.putExtra("newPosition", newPosition); + + sendBroadcast(i); + if (MainActivity.state == 1) { + + MainActivity.trace.addPoint(location.getLatitude(), location.getLongitude()); + GeoPoint position = new GeoPoint(location.getLatitude(), location.getLongitude()); + String nombre = "punto"; + addPoint(position, nombre, R.drawable.ic_menu_mylocation); + + + } else if (MainActivity.state == 2) { + //Toast.makeText(getBaseContext(), "Agrega posicion como parada", Toast.LENGTH_SHORT).show(); + MainActivity.trace.addStop(location.getLatitude(), location.getLongitude()); + GeoPoint position = new GeoPoint(location.getLatitude(), location.getLongitude()); + String nombre = "parada"; + addPoint(position, nombre, R.drawable.ic_launcher); + MainActivity.state = 1; + } + + + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(String provider) { + + } + + @Override + public void onProviderDisabled(String provider) { + Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); + i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(i); + } + }; + + locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); + //noinspection MissingPermission + + + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, listener); + + + + + } + + private void addPoint(GeoPoint position, String nombre, int drawable ) { + Marker point; + point = new Marker(MainActivity.map); + point.setPosition(position); + point.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM); + + Drawable myIcon = ResourcesCompat.getDrawable(getResources(), drawable, null); + point.setIcon(myIcon); + MainActivity.map.getOverlays().add(point); + point.setTitle(nombre); + MainActivity.points.add(point); + MainActivity.map.invalidate(); + + } + + @Override + public void onTaskRemoved (Intent rootIntent){ + MainActivity.trace.discarded(); + super.onTaskRemoved (rootIntent); + } + @Override + public void onDestroy() { + + + super.onDestroy(); + if(locationManager != null) + //noinspection MissingPermission + locationManager.removeUpdates(listener); + } + +} diff --git a/trazador/app/src/main/java/com/example/xavi/trazador_v10/MainActivity.java b/trazador/app/src/main/java/com/example/xavi/trazador_v10/MainActivity.java new file mode 100644 index 0000000..d288d80 --- /dev/null +++ b/trazador/app/src/main/java/com/example/xavi/trazador_v10/MainActivity.java @@ -0,0 +1,305 @@ +package com.example.xavi.trazador_v10; + +import android.Manifest; +import android.app.Activity; +import android.app.Dialog; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.location.SettingInjectorService; +import android.os.Build; +import android.provider.Settings; +import android.support.design.widget.FloatingActionButton; +import android.support.v4.app.ActivityCompat; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentManager; +import android.support.v4.content.ContextCompat; +import android.support.v4.content.res.ResourcesCompat; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.util.SortedList; +import android.telephony.TelephonyManager; +import android.view.View; +import android.widget.Button; +import android.widget.Toast; + +import com.jakewharton.threetenabp.AndroidThreeTen; + +import org.labexp.traces.Trace; +import org.osmdroid.tileprovider.constants.OpenStreetMapTileProviderConstants; +import org.osmdroid.tileprovider.tilesource.TileSourceFactory; +import org.osmdroid.util.GeoPoint; +import org.osmdroid.views.MapView; +import org.osmdroid.views.overlay.ItemizedIconOverlay; +import org.osmdroid.views.overlay.ItemizedOverlay; +import org.osmdroid.views.overlay.ItemizedOverlayWithFocus; +import org.osmdroid.views.overlay.OverlayItem; +import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider; +import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.UUID; + + +import org.osmdroid.api.IMapController; +import org.osmdroid.bonuspack.routing.OSRMRoadManager; +import org.osmdroid.bonuspack.routing.Road; +import org.osmdroid.bonuspack.routing.RoadManager; +import org.osmdroid.views.overlay.Marker; +import com.mapbox.mapboxsdk.geometry.LatLng; +import org.osmdroid.views.overlay.PathOverlay; +import org.osmdroid.views.overlay.Polyline; +import org.osmdroid.views.overlay.mylocation.IMyLocationProvider; + + + + +public class MainActivity extends FragmentActivity implements NoticeDialogFragment.NoticeDialogListener{ + + public static Button btnInicio; + private FloatingActionButton btnStop; + private FloatingActionButton btnInfo; + + + public static Trace trace; + + private Button btnParada; + boolean isPressed = false; + + private BroadcastReceiver broadcastReceiver; + + Location location; + + private LocationManager locationManager; + private LocationListener locationListener; + + + + + private double latitud = 0.0; + private double longitud = 0.0; + + + + static MapView map; + static Marker actualPositionMarker; + + static ArrayList points = new ArrayList<>(); + + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + //important! set your user agent to prevent getting banned from the osm servers + OpenStreetMapTileProviderConstants.setUserAgentValue(BuildConfig.APPLICATION_ID); + + + Intent i = new Intent(getApplicationContext(),GPS_Service.class); + startService(i); + + btnInicio = (Button) findViewById(R.id.btn_iniciar); + btnStop = (FloatingActionButton) findViewById(R.id.btn_stop); + btnInfo = (FloatingActionButton) findViewById(R.id.btn_info); + + + + map = (MapView) findViewById(R.id.map); + + map.setTileSource(TileSourceFactory.MAPNIK); + map.setBuiltInZoomControls(true); + map.setMultiTouchControls(true); + map.getController().setZoom(18); + + + + if(!runtime_permissions()) { + enable_buttons(); + } + AndroidThreeTen.init(this); + + + + + } + @Override + protected void onResume() { + super.onResume(); + if(broadcastReceiver == null){ + broadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + /*Toast.makeText(getApplicationContext(), "Lat: " + intent.getExtras().get("latitude") + "Long: " + + intent.getExtras().get("longitude"), + Toast.LENGTH_LONG).show();*/ + + latitud = Double.parseDouble(intent.getExtras().get("latitude").toString()); + longitud = Double.parseDouble(intent.getExtras().get("longitude").toString()); + + GeoPoint position = new GeoPoint(latitud,longitud); + map.getController().setCenter(position); + + + + marketCurrentPosition(position); + + } + }; + } + + registerReceiver(broadcastReceiver, new IntentFilter("location_update")); + } + + private void marketCurrentPosition(GeoPoint position) { + map.getOverlays().remove(actualPositionMarker); + actualPositionMarker = new Marker(map); + actualPositionMarker.setPosition(position); + actualPositionMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM); + Drawable myIcon = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_follow_me, null); + actualPositionMarker.setIcon(myIcon); + map.getOverlays().add(actualPositionMarker); + map.invalidate(); + + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if(broadcastReceiver != null){ + unregisterReceiver(broadcastReceiver); + } + } + + static int state = 0; + private void enable_buttons(){ + + + btnInicio.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + if (v == btnInicio && state == 0) { + final TelephonyManager tm = (TelephonyManager) getBaseContext().getSystemService(Context.TELEPHONY_SERVICE); + final String tmDevice, tmSerial, androidId; + tmDevice = "" + tm.getDeviceId(); + tmSerial = "" + tm.getSimSerialNumber(); + androidId = "" + android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID); + UUID deviceUuid = new UUID(androidId.hashCode(), ((long)tmDevice.hashCode() << 32) | tmSerial.hashCode()); + String deviceId = deviceUuid.toString(); + MainActivity.trace = new Trace(deviceId); + + try { + MainActivity.trace.start("http://buses.tec.siua.ac.cr"); + } catch (IOException e) { + e.printStackTrace(); + } + state = 1; + //Toast.makeText(getBaseContext(), "Inicio de ruta", Toast.LENGTH_SHORT).show(); + btnInicio.setBackgroundResource( R.drawable.btn_parada); + GeoPoint parada = new GeoPoint(latitud, longitud); + marketCurrentPosition(parada); + } + else if (v == btnInicio && state == 1){ + state = 2; + } + } + }); + + btnStop.setOnClickListener(new View.OnClickListener(){ + @Override + public void onClick (View v){ + if (state != 0) { + Intent myIntent = new Intent(getApplicationContext(), Finalize.class); + startActivityForResult(myIntent, 0); + } + + } + + }); + + btnInfo.setOnClickListener(new View.OnClickListener(){ + @Override + public void onClick (View v){ + + Intent myIntent = new Intent(getApplicationContext(), metadata.class); + startActivityForResult(myIntent, 0); + + } + + }); + + + + } + + + private boolean runtime_permissions(){ + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ContextCompat.checkSelfPermission(this,Manifest.permission + .ACCESS_FINE_LOCATION)!=PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, + Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED + && ContextCompat.checkSelfPermission(this, + Manifest.permission.READ_PHONE_STATE ) != PackageManager.PERMISSION_GRANTED){ + requestPermissions(new String[]{ + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_NETWORK_STATE, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.INTERNET}, 100); + + return true; + } + return false; + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + if(requestCode == 100){ + + if(grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager + .PERMISSION_GRANTED){ + enable_buttons(); + }else { + runtime_permissions(); + } + + + } + } + + public void showNoticeDialog() { + // Create an instance of the dialog fragment and show it + DialogFragment dialog = new NoticeDialogFragment(); + dialog.show(getSupportFragmentManager(), "NoticeDialogFragment"); + + + + } + + + @Override + public void onDialogPositiveClick(DialogFragment dialog) { + + Toast.makeText(getBaseContext(),"Aceptar",Toast.LENGTH_SHORT).show(); + + } + + @Override + public void onDialogNegativeClick(DialogFragment dialog) { + + Toast.makeText(getBaseContext(),"Cancelar",Toast.LENGTH_SHORT).show(); + + } +} + diff --git a/trazador/app/src/main/java/com/example/xavi/trazador_v10/NoticeDialogFragment.java b/trazador/app/src/main/java/com/example/xavi/trazador_v10/NoticeDialogFragment.java new file mode 100644 index 0000000..0ce0073 --- /dev/null +++ b/trazador/app/src/main/java/com/example/xavi/trazador_v10/NoticeDialogFragment.java @@ -0,0 +1,37 @@ +package com.example.xavi.trazador_v10; + +import android.app.Activity; +import android.support.v4.app.DialogFragment; + +/** + * Created by xavi on 06/10/16. + */ +public class NoticeDialogFragment extends DialogFragment { + + /* The activity that creates an instance of this dialog fragment must + * implement this interface in order to receive event callbacks. + * Each method passes the DialogFragment in case the host needs to query it. */ + public interface NoticeDialogListener { + public void onDialogPositiveClick(DialogFragment dialog); + public void onDialogNegativeClick(DialogFragment dialog); + } + + // Use this instance of the interface to deliver action events + NoticeDialogListener mListener; + + // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + // Verify that the host activity implements the callback interface + try { + // Instantiate the NoticeDialogListener so we can send events to the host + mListener = (NoticeDialogListener) activity; + } catch (ClassCastException e) { + // The activity doesn't implement the interface, throw exception + throw new ClassCastException(activity.toString() + + " must implement NoticeDialogListener"); + } + } + +} diff --git a/trazador/app/src/main/java/com/example/xavi/trazador_v10/metadata.java b/trazador/app/src/main/java/com/example/xavi/trazador_v10/metadata.java new file mode 100644 index 0000000..ac0af5f --- /dev/null +++ b/trazador/app/src/main/java/com/example/xavi/trazador_v10/metadata.java @@ -0,0 +1,66 @@ +package com.example.xavi.trazador_v10; + +import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; +import android.support.design.widget.TextInputEditText; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; +import android.content.Intent; +import android.widget.EditText; + +public class metadata extends AppCompatActivity { + + EditText Codigo; + EditText Nombre; + EditText Costo; + + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_metadata); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + FloatingActionButton btnGuardar; + FloatingActionButton btnCancelar; + Codigo = (EditText) findViewById(R.id.editText); + Nombre = (EditText) findViewById(R.id.editText2); + Costo = (EditText) findViewById(R.id.editText3); + + btnGuardar = (FloatingActionButton) findViewById(R.id.btn_guardar); + btnCancelar = (FloatingActionButton) findViewById(R.id.btn_cancelar); + + btnGuardar.setOnClickListener(new View.OnClickListener(){ + @Override + public void onClick (View v){ + String textCodigo = Codigo.getText().toString(); + String textNombre = Nombre.getText().toString(); + String textCosto = Costo.getText().toString(); + MainActivity.trace.setMetadata(textCodigo, textNombre, textCosto); + + Intent intent = new Intent(); + setResult(RESULT_OK, intent); + finish(); + } + }); + + btnCancelar.setOnClickListener(new View.OnClickListener(){ + @Override + public void onClick (View v){ + + Intent intent = new Intent(); + setResult(RESULT_OK, intent); + finish(); + + + } + + }); + + } + +} diff --git "a/trazador/app/src/main/java/org/Icon\r" "b/trazador/app/src/main/java/org/Icon\r" new file mode 100644 index 0000000..e69de29 diff --git "a/trazador/app/src/main/java/org/labexp/Icon\r" "b/trazador/app/src/main/java/org/labexp/Icon\r" new file mode 100644 index 0000000..e69de29 diff --git a/trazador/app/src/main/java/org/labexp/traces/ApiConnector.java b/trazador/app/src/main/java/org/labexp/traces/ApiConnector.java new file mode 100644 index 0000000..15d4556 --- /dev/null +++ b/trazador/app/src/main/java/org/labexp/traces/ApiConnector.java @@ -0,0 +1,481 @@ +package org.labexp.traces; + +/* +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; + +import com.sun.jersey.api.client.config.DefaultClientConfig; + +import com.sun.jersey.api.json.JSONConfiguration; +import com.sun.jersey.json.impl.provider.entity.JSONListElementProvider; +import com.sun.jersey.api.client.config.ClientConfig; + + + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; +*/ +import android.os.Build; +import android.support.annotation.RequiresApi; + +import okhttp3.MediaType; +import okhttp3.OkHttpClient; + + +import java.io.IOException; +import java.util.ArrayList; +import java.util.concurrent.ExecutionException; + +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONArray; +import org.threeten.bp.Instant; +import org.threeten.bp.ZoneId; +import org.threeten.bp.ZonedDateTime; +import org.threeten.bp.format.DateTimeFormatter; + +/** + * This class is a direct connection to the API server . + */ +public class ApiConnector { + /** + * jersey client to connect the server. + */ + private static OkHttpClient client; + /*private static Client client; + /** + * Server url. + */ + private static String apiBaseUrl ; + /** + * Format to save date on the server. + */ + private static final String DATE_FORMAT = "MM/dd/yyyy HH:mm:ss"; + /** + * sub-url to Post trace start. + */ + private static final String POST_START_TRACE = "/buses/v0.1/trace"; + /** + * sub-url to Post a list of points. + */ + private static final String POST_POINTS = "/buses/v0.1/trace//points"; + /** + * sub-url to Post a stop point. + */ + private static final String POST_STOP = "/buses/v0.1/trace//stop"; + /** + * sub-url to put metadata + */ + private static final String PUT_METADATA = "/buses/v0.1/trace//metadata"; + /** + * sub-url to finalize trace. + */ + private static final String PUT_FINALIZE = "/buses/v0.1/trace/"; + /** + * server response ok. + */ + private static final int OK_RESPONSE = 200; + + public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + + public static String localtraceId = ""; + + + /** + * Starts Jersey client. + */ + public static void createClient(String url) { + apiBaseUrl = url; + + + /* + ClientConfig clientConfig = new DefaultClientConfig(); + clientConfig.getFeatures().put( + JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); + client = Client.create(clientConfig); + */ + } + /** + * Starts trace on server. + * @param deviceId A unique identificator for the client device. + * @return unique trace identificator + */ + public static String startTrace(final String deviceId) throws java.io.IOException{ + /* + // Creates a webResource with the API + WebResource webResource = client.resource(apiBaseUrl + POST_START_TRACE); + */ + // Building the Post content + String jsonInput = ""; + try { + jsonInput = new JSONObject() + .put("deviceId", deviceId) + .put("timestamp", getDate()) + .toString(); + } catch (JSONException e) { + e.printStackTrace(); + } + + Post async = new Post(); + try { + async.execute(apiBaseUrl + POST_START_TRACE, jsonInput, "Post").get(); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + + + + /* + // POST method + ClientResponse response = webResource + .accept("application/json") + .type("application/json") + .Post(ClientResponse.class, jsonInput); + + // Check response status code + if (response.getStatus() != OK_RESPONSE) { + throw new RuntimeException( + "Failed : HTTP error code : " + response.getStatus()); + } + + // Reads response + String output = response.getEntity(String.class); + String traceId = ""; + + try { + JSONObject result = new JSONObject(output); + traceId = result.getString("traceId"); + } catch (JSONException e) { + e.printStackTrace(); + } + + return traceId; +*/ + return ""; + } + + /** + * @param deviceId unique device id + * @param traceId unique trace id + * @param points list of points to be add + * @return server response + * @throws RuntimeException server connection error + */ + public static boolean addPoints( + final String deviceId, + final String traceId, + final ArrayList points)throws RuntimeException { + + /* + // Creates a webResource with the API url to Post start a trace + WebResource webResource = client.resource( + apiBaseUrl + POST_POINTS.replaceFirst("\\{traceId\\}", traceId)); + */ + // Building the Post content + + String url = apiBaseUrl + POST_POINTS.replaceFirst("", localtraceId); + String jsonInput = ""; + try { + + JSONArray jsonPointList = new JSONArray(); + for (MapPoint point : points){ + JSONObject pointElement = new JSONObject() + .put("latitude", point.getX()+"") + .put("longitude", point.getY()+""); + jsonPointList.put(pointElement); + } + + jsonInput = new JSONObject() + .put("deviceId", deviceId) + .put("timestamp", getDate()) + .put("points", jsonPointList) + .toString(); + System.out.println(jsonInput); + post(url, jsonInput); + + } catch (JSONException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + + /* + // POST method + ClientResponse response = webResource + .accept("application/json") + .type("application/json") + .Post(ClientResponse.class, jsonInput); + + // Check response status code + if (response.getStatus() != OK_RESPONSE) { + throw new RuntimeException( + "Failed : HTTP error code : " + response.getStatus()); + } + else{ + return true; + } + */ + return true; + + } + + + /** + * @param deviceId unique device id + * @param traceId unique trace id + * @param stop stop position + * @return server response + * @throws RuntimeException server connection error + */ + public static boolean addStop( + final String deviceId, + final String traceId, + final MapPoint stop)throws RuntimeException { +/* + // Creates a webResource with the API url + WebResource webResource = client.resource( + apiBaseUrl + POST_STOP.replaceFirst("\\{traceId\\}", traceId)); +*/ + // Building the Post content + String url = apiBaseUrl + POST_STOP.replaceFirst("", localtraceId); + String jsonInput = ""; + try { + + + JSONObject pointElement = + new JSONObject() + .put("latitude", stop.getX()+"") + .put("longitude", stop.getY()+""); + + jsonInput = new JSONObject() + .put("deviceId", deviceId) + .put("timestamp", getDate()) + .put("stop", pointElement) + .toString(); + System.out.println(jsonInput); + post(url, jsonInput); + + } catch (JSONException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + /* + // POST method + ClientResponse response = webResource + .accept("application/json") + .type("application/json") + .Post(ClientResponse.class, jsonInput); + + // Check response status code + if (response.getStatus() != OK_RESPONSE) { + throw new RuntimeException( + "Failed : HTTP error code : " + response.getStatus()); + } + else{ + return true; + } + */ + return true; + + } + + /** + * @param deviceId unique device id + * @param traceId unique trace id + * @param metadata information about the trace + * @return server response + * @throws RuntimeException server connection error + */ + public static boolean setMetadata( + final String deviceId, + final String traceId, + final Metadata metadata)throws RuntimeException { +/* + // Creates a webResource with the API url + WebResource webResource = client.resource( + apiBaseUrl + PUT_METADATA.replaceFirst("\\{traceId\\}", traceId)); +*/ + String url = apiBaseUrl + PUT_METADATA.replaceFirst("", localtraceId); + // Building the put content + String jsonInput = ""; + try { + + jsonInput = new JSONObject() + .put("deviceId", deviceId) + .put("timestamp", getDate()) + .put("routeCode", metadata.getRouteCode()) + .put("routeName", metadata.getRouteName()) + .put("routePrice", metadata.getRoutePrice()) + .toString(); + put(url, jsonInput); + + } catch (JSONException e) { + + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + /* + // Put method + ClientResponse response = webResource + .accept("application/json") + .type("application/json") + .put(ClientResponse.class, jsonInput); + + // Check response status code + if (response.getStatus() != OK_RESPONSE) { + throw new RuntimeException( + "Failed : HTTP error code : " + response.getStatus()); + } + else{ + return true; + } + */ + return true; + + } + + /** + * @param traceId unique trace id + * @return server response + * @throws RuntimeException server connection error + */ + public static boolean finished( + final String traceId)throws RuntimeException { +/* + // Creates a webResource with the API url + WebResource webResource = client.resource( + apiBaseUrl + PUT_FINALIZE.replaceFirst("\\{traceId\\}", traceId)); +*/ + String url = apiBaseUrl + PUT_FINALIZE.replaceFirst("", localtraceId); + // Building the Post content + String jsonInput = ""; + try { + + jsonInput = new JSONObject() + .put("status", "finished") + .toString(); + put(url, jsonInput); + + } catch (JSONException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + /* + // PUT method + ClientResponse response = webResource + .accept("application/json") + .type("application/json") + .put(ClientResponse.class, jsonInput); + + // Check response status code + if (response.getStatus() != OK_RESPONSE) { + throw new RuntimeException( + "Failed : HTTP error code : " + response.getStatus()); + } + else{ + return true; + } + */ + return true; + + } + + /** + * @param traceId unique trace id + * @return server response + * @throws RuntimeException server connection error + */ + public static boolean discarded( + final String traceId)throws RuntimeException { + + /* + // Creates a webResource with the API url + WebResource webResource = client.resource( + apiBaseUrl + PUT_FINALIZE.replaceFirst("\\{traceId\\}", traceId)); +*/ + String url = apiBaseUrl + PUT_FINALIZE.replaceFirst("", localtraceId); + // Building the Post content + String jsonInput = ""; + try { + + jsonInput = new JSONObject() + .put("status", "discarded") + .toString(); + + put(url, jsonInput); + + } catch (JSONException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + /* + // PUT method + ClientResponse response = webResource + .accept("application/json") + .type("application/json") + .put(ClientResponse.class, jsonInput); + + // Check response status code + if (response.getStatus() != OK_RESPONSE) { + throw new RuntimeException( + "Failed : HTTP error code : " + response.getStatus()); + } + else{ + return true; + } + */ + return true; + + } + + /** + * Calculates timeZone and formats date into a string. + * @return Date with the format of @DATE_FORMAT. + */ + private static String getDate() { + + Instant instant = Instant.now(); + ZoneId zoneId = ZoneId.of( "America/Costa_Rica" ); + ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId ); + DateTimeFormatter dtfOut = DateTimeFormatter.ofPattern(DATE_FORMAT); + return zdt.format(dtfOut).toString(); + + + + } + + public Instant now() { + return Instant.now(); + } + + @RequiresApi(api = Build.VERSION_CODES.KITKAT) + + static String post(String url, String json) throws java.io.IOException { + Post async = new Post(); + async.execute(url, json); + return ""; + + + } + + static String put(String url, String json) throws java.io.IOException { + Put async = new Put(); + async.execute(url, json); + return ""; + + + } + + +} diff --git a/trazador/app/src/main/java/org/labexp/traces/MapPoint.java b/trazador/app/src/main/java/org/labexp/traces/MapPoint.java new file mode 100644 index 0000000..b18faf8 --- /dev/null +++ b/trazador/app/src/main/java/org/labexp/traces/MapPoint.java @@ -0,0 +1,68 @@ + +package org.labexp.traces; + +/** + * @author Leo + * + */ +public class MapPoint { + /* + * Represents position over latitude. + */ + private double x; + /* + * Represents position over longitude. + */ + private double y; + + /** + * New MapPoint based on latitude and longitude values. + * @param x Latitude. + * @param y Longitude. + */ + public MapPoint(final double x, final double y) { + this.x = x; + this.y = y; + } + /** + * Get Latitude. + * @return latitude + */ + public double getX() { + return x; + } + + /** + * Set Latitude. + * @param x latitude + */ + public void setX(final double x) { + this.x = x; + } + + /** + * Get Longitude. + * @return longitude + */ + public double getY() { + return y; + } + + /** + * Set longitude. + * @param y longitude + */ + public void setY(final double y) { + this.y = y; + } + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "MapPoint [latitude=" + x + ", longitude=" + y + "]"; + } + + + +} diff --git a/trazador/app/src/main/java/org/labexp/traces/Metadata.java b/trazador/app/src/main/java/org/labexp/traces/Metadata.java new file mode 100644 index 0000000..c80751b --- /dev/null +++ b/trazador/app/src/main/java/org/labexp/traces/Metadata.java @@ -0,0 +1,76 @@ +package org.labexp.traces; + +/** + * Used to save the metadata related to a trace + * @author Leo + * + */ +public class Metadata { + /** + * The code of the route. + */ + private String routeCode; + /** + * The name of the route. + */ + private String routeName; + /** + * The price of the route. + */ + private String routePrice; + /** + * @return the route code + */ + public String getRouteCode() { + return routeCode; + } + /** + * @param routeCode the route code to set + */ + public void setRouteCode(final String routeCode) { + this.routeCode = routeCode; + } + /** + * @return the route name + */ + public String getRouteName() { + return routeName; + } + /** + * @param routeName the route name to set + */ + public void setRouteName(final String routeName) { + this.routeName = routeName; + } + /** + * @return the route price + */ + public String getRoutePrice() { + return routePrice; + } + /** + * @param routePrice the route price to set + */ + public void setRoutePrice(final String routePrice) { + this.routePrice = routePrice; + } + /** + * @param routeCode code + * @param routeName name + * @param routePrice price + */ + public Metadata(final String routeCode, final String routeName, final String routePrice) { + super(); + this.routeCode = routeCode; + this.routeName = routeName; + this.routePrice = routePrice; + } + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return "Metadata [Code=" + routeCode + ", Name=" + routeName + ", Price=" + routePrice + "]"; + } + +} diff --git a/trazador/app/src/main/java/org/labexp/traces/Put.java b/trazador/app/src/main/java/org/labexp/traces/Put.java new file mode 100644 index 0000000..236e15d --- /dev/null +++ b/trazador/app/src/main/java/org/labexp/traces/Put.java @@ -0,0 +1,56 @@ +package org.labexp.traces; + +import android.os.AsyncTask; + +import org.json.JSONException; +import org.json.JSONObject; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +import static org.labexp.traces.ApiConnector.JSON; + + +class Put extends AsyncTask { + + + private static OkHttpClient client; + + String response; + + protected String doInBackground(String... params) { + if (client == null){ + client = new OkHttpClient(); + } + String sb = params[1]; + RequestBody body = RequestBody.create(JSON, sb); + + + Request request = new Request.Builder() + .url(params[0]) + .put(body) + .build(); + + + try (Response response = client.newCall( request).execute()) { + if (params.length >2 ) + if (params[2].equals("Post")){ + JSONObject jsonObj = new JSONObject(ApiConnector.localtraceId = response.body().string()); + ApiConnector.localtraceId = jsonObj.getString("traceId"); + + } + } + catch (java.io.IOException x) { + return "null"; + + } catch (JSONException e) { + e.printStackTrace(); + } + return ""; + + + } + +} diff --git a/trazador/app/src/main/java/org/labexp/traces/Trace.java b/trazador/app/src/main/java/org/labexp/traces/Trace.java new file mode 100644 index 0000000..7eb3745 --- /dev/null +++ b/trazador/app/src/main/java/org/labexp/traces/Trace.java @@ -0,0 +1,162 @@ +/** + * + */ +package org.labexp.traces; + +import java.util.ArrayList; + +/** + * @author Leo + * + */ +public class Trace { + /* + * Trace identifier (provide by the server) + */ + private String traceId; + /* + * Device identifier (provide by the user) + */ + private String deviceId; + /* + * The url of the Api server + */ + private String apiBaseUrl; + /** + * @return the trace id + */ + public final String getTraceId() { + return traceId; + } + /** + * @return the device id + */ + public final String getDeviceId() { + return deviceId; + } + + + /** + * @return the apiBaseUrl + */ + public String getApiBaseUrl() { + return apiBaseUrl; + } + + /** + * Creates a trace using a unique device identificator. + * @param deviceId + */ + public Trace(String deviceId) { + super(); + this.deviceId = deviceId; + } + + /** + * Starts the trace on the server. + * @param apiBaseUrl the base url of the API Server: + * example: "http://10.173.1.153" + * @return a unique trace id and this is saved on traceId + * + */ + public void start(String apiBaseUrl) throws java.io.IOException{ + this.apiBaseUrl = apiBaseUrl; + ApiConnector.createClient(apiBaseUrl); + this.traceId = ApiConnector.startTrace (deviceId); + } + + /** + * @param routeCode code + * @param routeName name + * @param routePrice prices + * @return transaction success + */ + public boolean setMetadata( + final String routeCode, + final String routeName, + final String routePrice) { + Metadata metadata = new Metadata(routeCode, routeName, routePrice); + setMetadata(metadata); + return true; + } + + /** + * @param metadata trace metadata + * @return transaction success + */ + public boolean setMetadata(final Metadata metadata) { + return ApiConnector.setMetadata(deviceId, traceId, metadata); + + } + + /** + * @param points List of points to add + * @return transaction success + */ + public boolean addPoints(final ArrayList points) { + return ApiConnector.addPoints(deviceId, traceId, points); + } + + /** + * @param x latitude. + * @param y longitude. + * @return transaction success + */ + public boolean addPoint(final double x, final double y) { + MapPoint point = new MapPoint(x, y); + ArrayList points = new ArrayList(); + points.add(point); + addPoints (points); + return true; + } + + /** + * @param point position + * @return transaction success + */ + public boolean addPoint(final MapPoint point) { + ArrayList points = new ArrayList(); + points.add(point); + addPoints (points); + return true; + } + + /** + * @param stop stop position + * @return transaction success + */ + public boolean addStop(final MapPoint stop) { + return ApiConnector.addStop(deviceId, traceId, stop); + } + + /** + * @param x latitude. + * @param y longitude. + * @return transaction success + */ + public boolean addStop(final double x, final double y) { + MapPoint point = new MapPoint(x, y); + return addStop(point); + } + + + + /** + * Mark trace as finished on the server + * @return transaction success + */ + public boolean finished() { + ApiConnector.finished(traceId); + return true; + } + + /** + * Mark trace as finished on the server + * @return transaction success + */ + public boolean discarded() { + ApiConnector.discarded(traceId); + return true; + } + +} diff --git a/trazador/app/src/main/java/org/labexp/traces/post.java b/trazador/app/src/main/java/org/labexp/traces/post.java new file mode 100644 index 0000000..e89bb89 --- /dev/null +++ b/trazador/app/src/main/java/org/labexp/traces/post.java @@ -0,0 +1,56 @@ +package org.labexp.traces; + +import android.os.AsyncTask; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONArray; + +import static org.labexp.traces.ApiConnector.JSON; + + +class Post extends AsyncTask { + + + private static OkHttpClient client; + + String response; + + protected String doInBackground(String... params) { + if (client == null){ + client = new OkHttpClient(); + } + String sb = params[1]; + RequestBody body = RequestBody.create(JSON, sb); + + + Request request = new Request.Builder() + .url(params[0]) + .post(body) + .build(); + + + try (Response response = client.newCall( request).execute()) { + if (params.length >2 ) + if (params[2].equals("Post")){ + JSONObject jsonObj = new JSONObject(ApiConnector.localtraceId = response.body().string()); + ApiConnector.localtraceId = jsonObj.getString("traceId"); + + } + } + catch (java.io.IOException x) { + return "null"; + + } catch (JSONException e) { + e.printStackTrace(); + } + return ""; + + + } + +} diff --git a/trazador/app/src/main/res/drawable-hdpi/ic_action_info.png b/trazador/app/src/main/res/drawable-hdpi/ic_action_info.png new file mode 100644 index 0000000..eef197e Binary files /dev/null and b/trazador/app/src/main/res/drawable-hdpi/ic_action_info.png differ diff --git a/trazador/app/src/main/res/drawable-hdpi/ic_action_stop.png b/trazador/app/src/main/res/drawable-hdpi/ic_action_stop.png new file mode 100644 index 0000000..e373da2 Binary files /dev/null and b/trazador/app/src/main/res/drawable-hdpi/ic_action_stop.png differ diff --git a/trazador/app/src/main/res/drawable-mdpi/ic_action_info.png b/trazador/app/src/main/res/drawable-mdpi/ic_action_info.png new file mode 100644 index 0000000..1940892 Binary files /dev/null and b/trazador/app/src/main/res/drawable-mdpi/ic_action_info.png differ diff --git a/trazador/app/src/main/res/drawable-mdpi/ic_action_stop.png b/trazador/app/src/main/res/drawable-mdpi/ic_action_stop.png new file mode 100644 index 0000000..ea6a7ed Binary files /dev/null and b/trazador/app/src/main/res/drawable-mdpi/ic_action_stop.png differ diff --git a/trazador/app/src/main/res/drawable-xhdpi/ic_action_info.png b/trazador/app/src/main/res/drawable-xhdpi/ic_action_info.png new file mode 100644 index 0000000..310caaa Binary files /dev/null and b/trazador/app/src/main/res/drawable-xhdpi/ic_action_info.png differ diff --git a/trazador/app/src/main/res/drawable-xhdpi/ic_action_stop.png b/trazador/app/src/main/res/drawable-xhdpi/ic_action_stop.png new file mode 100644 index 0000000..8eca25a Binary files /dev/null and b/trazador/app/src/main/res/drawable-xhdpi/ic_action_stop.png differ diff --git a/trazador/app/src/main/res/drawable-xxhdpi/ic_action_info.png b/trazador/app/src/main/res/drawable-xxhdpi/ic_action_info.png new file mode 100644 index 0000000..f130249 Binary files /dev/null and b/trazador/app/src/main/res/drawable-xxhdpi/ic_action_info.png differ diff --git a/trazador/app/src/main/res/drawable-xxhdpi/ic_action_stop.png b/trazador/app/src/main/res/drawable-xxhdpi/ic_action_stop.png new file mode 100644 index 0000000..2ad2bfc Binary files /dev/null and b/trazador/app/src/main/res/drawable-xxhdpi/ic_action_stop.png differ diff --git a/trazador/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/trazador/app/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..de1f5ea Binary files /dev/null and b/trazador/app/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/trazador/app/src/main/res/drawable-xxhdpi/ic_menu_mylocation.png b/trazador/app/src/main/res/drawable-xxhdpi/ic_menu_mylocation.png new file mode 100644 index 0000000..fdbd5ca Binary files /dev/null and b/trazador/app/src/main/res/drawable-xxhdpi/ic_menu_mylocation.png differ diff --git a/trazador/app/src/main/res/drawable/btn_iniciar.png b/trazador/app/src/main/res/drawable/btn_iniciar.png new file mode 100644 index 0000000..97daa64 Binary files /dev/null and b/trazador/app/src/main/res/drawable/btn_iniciar.png differ diff --git a/trazador/app/src/main/res/drawable/btn_parada.png b/trazador/app/src/main/res/drawable/btn_parada.png new file mode 100644 index 0000000..667b46a Binary files /dev/null and b/trazador/app/src/main/res/drawable/btn_parada.png differ diff --git a/trazador/app/src/main/res/drawable/ic_center_map.png b/trazador/app/src/main/res/drawable/ic_center_map.png new file mode 100644 index 0000000..babd8ab Binary files /dev/null and b/trazador/app/src/main/res/drawable/ic_center_map.png differ diff --git a/trazador/app/src/main/res/drawable/ic_follow_me.png b/trazador/app/src/main/res/drawable/ic_follow_me.png new file mode 100644 index 0000000..53b7f5a Binary files /dev/null and b/trazador/app/src/main/res/drawable/ic_follow_me.png differ diff --git a/trazador/app/src/main/res/drawable/ic_follow_me_on.png b/trazador/app/src/main/res/drawable/ic_follow_me_on.png new file mode 100644 index 0000000..7df8c60 Binary files /dev/null and b/trazador/app/src/main/res/drawable/ic_follow_me_on.png differ diff --git a/trazador/app/src/main/res/drawable/ic_info_black_24dp.xml b/trazador/app/src/main/res/drawable/ic_info_black_24dp.xml new file mode 100644 index 0000000..34b8202 --- /dev/null +++ b/trazador/app/src/main/res/drawable/ic_info_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/trazador/app/src/main/res/drawable/ic_notifications_black_24dp.xml b/trazador/app/src/main/res/drawable/ic_notifications_black_24dp.xml new file mode 100644 index 0000000..e3400cf --- /dev/null +++ b/trazador/app/src/main/res/drawable/ic_notifications_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/trazador/app/src/main/res/drawable/ic_sync_black_24dp.xml b/trazador/app/src/main/res/drawable/ic_sync_black_24dp.xml new file mode 100644 index 0000000..5a283aa --- /dev/null +++ b/trazador/app/src/main/res/drawable/ic_sync_black_24dp.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/trazador/app/src/main/res/drawable/info.png b/trazador/app/src/main/res/drawable/info.png new file mode 100644 index 0000000..c1e2a03 Binary files /dev/null and b/trazador/app/src/main/res/drawable/info.png differ diff --git a/trazador/app/src/main/res/layout/activity_finalize.xml b/trazador/app/src/main/res/layout/activity_finalize.xml new file mode 100644 index 0000000..4152b1d --- /dev/null +++ b/trazador/app/src/main/res/layout/activity_finalize.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/trazador/app/src/main/res/layout/activity_main.xml b/trazador/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..f1fdf64 --- /dev/null +++ b/trazador/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,72 @@ + + + + + + + + + +