());
+ String cookiesConcat = new String();
+
+ for (String cookie : csrfCookies) {
+ cookiesConcat = cookie.substring(0, cookie.indexOf(";"));
+ builder.header(CSRF_TOKEN, cookie.substring(10, cookie.indexOf(";")));
+ Log.v(LOG_TAG, cookie);
+ }
+
+ for (String cookie : sessionCookies) {
+ cookiesConcat = cookiesConcat + "; " + cookie.substring(0, cookie.indexOf(";"));
+ Log.v(LOG_TAG, cookie);
+ }
+
+ builder.header(COOKIE, cookiesConcat);
+
+ return chain.proceed(builder.build());
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/smarttraffic/smartparking/Interceptors/AddGeoJsonInterceptor.java b/app/src/main/java/smarttraffic/smartparking/Interceptors/AddGeoJsonInterceptor.java
new file mode 100644
index 0000000..7815570
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/Interceptors/AddGeoJsonInterceptor.java
@@ -0,0 +1,28 @@
+package smarttraffic.smartparking.Interceptors;
+
+import java.io.IOException;
+
+import okhttp3.Interceptor;
+import okhttp3.Request;
+import okhttp3.Response;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.tokenInterceptors
+ */
+
+public class AddGeoJsonInterceptor implements Interceptor {
+
+ public AddGeoJsonInterceptor(){
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request newRequest = chain.request().newBuilder()
+ .addHeader("Accept", "application/vnd.geo+json")
+ .build();
+ return chain.proceed(newRequest);
+ }
+
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/Interceptors/AddSmartParkingTokenInterceptor.java b/app/src/main/java/smarttraffic/smartparking/Interceptors/AddSmartParkingTokenInterceptor.java
new file mode 100644
index 0000000..53f59b8
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/Interceptors/AddSmartParkingTokenInterceptor.java
@@ -0,0 +1,29 @@
+package smarttraffic.smartparking.Interceptors;
+
+import java.io.IOException;
+
+import okhttp3.Interceptor;
+import okhttp3.Request;
+import okhttp3.Response;
+import smarttraffic.smartparking.SmartParkingInitialData;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.tokenInterceptors
+ */
+
+public class AddSmartParkingTokenInterceptor implements Interceptor {
+
+ public AddSmartParkingTokenInterceptor(){
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request newRequest = chain.request().newBuilder()
+ .addHeader("Authorization", "Token "
+ + SmartParkingInitialData.getToken())
+ .build();
+ return chain.proceed(newRequest);
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/Interceptors/AddUserTokenInterceptor.java b/app/src/main/java/smarttraffic/smartparking/Interceptors/AddUserTokenInterceptor.java
new file mode 100644
index 0000000..dcac6bc
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/Interceptors/AddUserTokenInterceptor.java
@@ -0,0 +1,41 @@
+package smarttraffic.smartparking.Interceptors;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import java.io.IOException;
+
+import okhttp3.Interceptor;
+import okhttp3.Request;
+import okhttp3.Response;
+import smarttraffic.smartparking.Constants;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.tokenInterceptors
+ */
+
+public class AddUserTokenInterceptor implements Interceptor {
+
+ private Context context;
+
+ public AddUserTokenInterceptor(Context context){
+ this.context = context;
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ SharedPreferences sharedPreferences = context.getSharedPreferences(
+ Constants.CLIENTE_DATA, Context.MODE_PRIVATE);
+ String userToken = sharedPreferences.getString(Constants.USER_TOKEN,
+ Constants.CLIENT_NOT_LOGIN);
+
+ Request newRequest = chain.request().newBuilder()
+ .addHeader("Authorization", "Token "
+ + userToken)
+ .build();
+ return chain.proceed(newRequest);
+ }
+}
+
diff --git a/app/src/main/java/smarttraffic/smartparking/Interceptors/ReceivedCookiesInterceptor.java b/app/src/main/java/smarttraffic/smartparking/Interceptors/ReceivedCookiesInterceptor.java
new file mode 100644
index 0000000..57adc3f
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/Interceptors/ReceivedCookiesInterceptor.java
@@ -0,0 +1,61 @@
+package smarttraffic.smartparking.Interceptors;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.HashSet;
+
+import okhttp3.Interceptor;
+import okhttp3.Response;
+
+/**
+ * Created by Joaquin Olivera on july 19.
+ *
+ * @author joaquin
+ */
+
+public class ReceivedCookiesInterceptor implements Interceptor {
+ public static final String CSRF_COOKIES = "CSRF_COOKIES";
+ public static final String SESSION_COOKIES = "SESSION_COOKIES";
+ public static final String SET_COOKIE = "Set-Cookie";
+
+ public static final String LOG_TAG = ReceivedCookiesInterceptor.class.getSimpleName();
+ private static final String COOKIES_CLIENT = "Cookies Client";
+
+ private Context context;
+
+ public ReceivedCookiesInterceptor(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Response originalResponse = chain.proceed(chain.request());
+
+ if (!originalResponse.headers(SET_COOKIE).isEmpty()) {
+ SharedPreferences sharedPreferences = context.getSharedPreferences(COOKIES_CLIENT, Context.MODE_PRIVATE);
+ HashSet sessionCookies = new HashSet();
+ HashSet csrfCookies = new HashSet();
+
+ for (String header : originalResponse.headers(SET_COOKIE)) {
+ if(header.startsWith("sessionid")){
+ sessionCookies.add(header);
+ }else{
+ csrfCookies.add(header);
+ }
+ }
+
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putStringSet(CSRF_COOKIES, csrfCookies).apply();
+ editor.putStringSet(SESSION_COOKIES, sessionCookies).apply();
+ editor.commit();
+
+ Log.v(LOG_TAG, originalResponse.headers().get(SET_COOKIE));
+
+ }
+
+ return originalResponse;
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/Interceptors/ReceivedTimeStampInterceptor.java b/app/src/main/java/smarttraffic/smartparking/Interceptors/ReceivedTimeStampInterceptor.java
new file mode 100644
index 0000000..61e1ca3
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/Interceptors/ReceivedTimeStampInterceptor.java
@@ -0,0 +1,46 @@
+package smarttraffic.smartparking.Interceptors;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Log;
+
+import java.io.IOException;
+
+import okhttp3.Interceptor;
+import okhttp3.Response;
+
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.Interceptors
+ */
+
+public class ReceivedTimeStampInterceptor implements Interceptor {
+
+ private static final String LOG_TAG = "X-TimeStamp Interceptor";
+
+ public static final String X_TIMESTAMP = "X-Timestamp";
+
+ private Context context;
+
+ public ReceivedTimeStampInterceptor(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Response originalResponse = chain.proceed(chain.request());
+ SharedPreferences sharedPreferences = context.getSharedPreferences(X_TIMESTAMP,
+ Context.MODE_PRIVATE);
+
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ editor.putString(X_TIMESTAMP, originalResponse.header(X_TIMESTAMP)).apply();
+ editor.commit();
+
+ Log.v(LOG_TAG, X_TIMESTAMP);
+
+ return originalResponse;
+
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/SmartParkingAPI.java b/app/src/main/java/smarttraffic/smartparking/SmartParkingAPI.java
new file mode 100644
index 0000000..d240d61
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/SmartParkingAPI.java
@@ -0,0 +1,78 @@
+package smarttraffic.smartparking;
+
+import java.util.HashMap;
+
+import okhttp3.ResponseBody;
+import retrofit2.Call;
+import retrofit2.http.Body;
+import retrofit2.http.GET;
+import retrofit2.http.Header;
+import retrofit2.http.PATCH;
+import retrofit2.http.POST;
+import retrofit2.http.Path;
+import smarttraffic.smartparking.activities.ChangePasswordActivity;
+import smarttraffic.smartparking.dataModels.Credentials;
+import smarttraffic.smartparking.dataModels.Events;
+import smarttraffic.smartparking.dataModels.Lots.Lot;
+import smarttraffic.smartparking.dataModels.Lots.LotList;
+import smarttraffic.smartparking.dataModels.NearbyLocation;
+import smarttraffic.smartparking.dataModels.ProfileUser;
+import smarttraffic.smartparking.dataModels.ProfileRegistry;
+import smarttraffic.smartparking.dataModels.Spots.Spot;
+import smarttraffic.smartparking.dataModels.Spots.SpotList;
+import smarttraffic.smartparking.dataModels.UserToken;
+
+public interface SmartParkingAPI {
+
+ /**USERS**/
+
+ @POST("smartparking/auth-token/")
+ Call getUserToken(@Body Credentials userCredentials);
+
+ @POST("smartparking/users/")
+ Call signUpUser(@Body ProfileRegistry profileRegistry);
+
+ @PATCH("smartparking/users/{identifier}/")
+ Call updateUserProfile(@Path("identifier") Integer userId,
+ @Body ChangePasswordActivity.Password newProfile);
+
+ /**SPOTS**/
+
+ @POST("smartparking/spots/{spotId}/reset/")
+ Call resetFreeSpot(@Path("spotId") Integer spotId);
+
+ @POST("smartparking/spots/{spotId}/set/")
+ Call setOccupiedSpot(@Path("spotId") Integer spotId);
+
+ @POST("smartparking/spots/nearby/")
+ Call> getMapNearbySpots(@Body NearbyLocation nearbyLocation);
+
+ @POST("smartparking/spots/nearby/")
+ Call getGeoJsonNearbySpots(@Body NearbyLocation nearbyLocation);
+
+ @GET("smartparking/spots/")
+ Call getAllSpots();
+
+ @GET("smartparking/spots/{spotId}/")
+ Call getASpot(@Path("spotId") Integer spotId);
+
+ /**LOTS**/
+
+ @GET("smartparking/lots/")
+ Call getAllLots();
+
+ @GET("smartparking/lots/{lotId}/")
+ Call getALot(@Path("lotId") Integer lotId);
+
+ @GET("smartparking/lots/{lotId}/spots/")
+ Call> getAllMapSpotsInLot(@Path("lotId") Integer lotId);
+
+ @GET("smartparking/lots/{lotId}/spots/")
+ Call getAllGeoJsonSpotsInLot(@Path("lotId") Integer lotId);
+
+ /**EVENTS**/
+
+ @POST("services/events/")
+ Call setUserEvent(@Header("Content-Type") String content_type, @Body Events event);
+
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/StatesEnumerations.java b/app/src/main/java/smarttraffic/smartparking/StatesEnumerations.java
new file mode 100644
index 0000000..41da985
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/StatesEnumerations.java
@@ -0,0 +1,24 @@
+package smarttraffic.smartparking;
+
+/**
+ * Created by Joaquin on 08/2019.
+ *
+ * smarttraffic.smartparking
+ */
+
+public enum StatesEnumerations {
+ FREE("F"),
+ UNKNOWN("U"),
+ OCCUPIED("O");
+
+ private String estado;
+
+ public String getEstado() {
+ return estado;
+ }
+
+ StatesEnumerations(String f) {
+ this.estado = f;
+ }
+}
+
diff --git a/app/src/main/java/smarttraffic/smartparking/Utils.java b/app/src/main/java/smarttraffic/smartparking/Utils.java
new file mode 100644
index 0000000..e43adc7
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/Utils.java
@@ -0,0 +1,233 @@
+package smarttraffic.smartparking;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.location.Location;
+import android.util.Log;
+import android.view.Gravity;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.Toast;
+
+import com.google.android.gms.location.DetectedActivity;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.Headers;
+import okhttp3.OkHttpClient;
+import okhttp3.ResponseBody;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+import smarttraffic.smartparking.Interceptors.AddUserTokenInterceptor;
+import smarttraffic.smartparking.dataModels.EventProperties;
+import smarttraffic.smartparking.dataModels.Events;
+import smarttraffic.smartparking.dataModels.Lots.Lot;
+import smarttraffic.smartparking.dataModels.Lots.PointGeometry;
+
+public class Utils {
+
+ private static final String LOG_TAG = "Utils class";
+
+ public static final String LOTS_SYSTEM = "Lots in the System";
+
+ private Utils() {}
+
+ /**
+ * Returns a human readable String corresponding to a detected activity type.
+ */
+ @SuppressLint("StringFormatInvalid")
+ public static String getActivityString(Context context, int detectedActivityType) {
+ Resources resources = context.getResources();
+ switch(detectedActivityType) {
+ case DetectedActivity.IN_VEHICLE:
+ return resources.getString(R.string.in_vehicle);
+ case DetectedActivity.ON_BICYCLE:
+ return resources.getString(R.string.on_bicycle);
+ case DetectedActivity.ON_FOOT:
+ return resources.getString(R.string.on_foot);
+ case DetectedActivity.RUNNING:
+ return resources.getString(R.string.running);
+ case DetectedActivity.STILL:
+ return resources.getString(R.string.still);
+ case DetectedActivity.TILTING:
+ return resources.getString(R.string.tilting);
+ case DetectedActivity.UNKNOWN:
+ return resources.getString(R.string.unknown);
+ case DetectedActivity.WALKING:
+ return resources.getString(R.string.walking);
+ default:
+ return resources.getString(R.string.unidentifiable_activity, detectedActivityType);
+ }
+ }
+
+ public static String detectedActivitiesToJson(ArrayList detectedActivitiesList) {
+ Type type = new TypeToken>() {}.getType();
+ return new Gson().toJson(detectedActivitiesList, type);
+ }
+
+ static ArrayList detectedActivitiesFromJson(String jsonArray) {
+ Type listType = new TypeToken>(){}.getType();
+ ArrayList detectedActivities = new Gson().fromJson(jsonArray, listType);
+ if (detectedActivities == null) {
+ detectedActivities = new ArrayList<>();
+ }
+ return detectedActivities;
+ }
+
+ public static void saveLotInSharedPreferences(Context context, List lots) {
+ SharedPreferences prefs = context.getSharedPreferences(LOTS_SYSTEM,
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = prefs.edit();
+ for(Lot lot : lots){
+ editor.putInt(lot.getProperties().getName(),lot.getProperties().getIdFromUrl());
+ editor.apply();
+ }
+ }
+
+ public static int getLotInSharedPreferences(Context context, String lotName) {
+ SharedPreferences prefs = context.getSharedPreferences(LOTS_SYSTEM,
+ Context.MODE_PRIVATE);
+ int id = prefs.getInt(lotName, -1);
+ return id;
+ }
+
+ public static void showToast(String message, Context context) {
+ Toast toast = Toast.makeText(context, message, Toast.LENGTH_LONG);
+ toast.setGravity(Gravity.CENTER, 0, 0);
+ LinearLayout toastContentView = (LinearLayout) toast.getView();
+ ImageView imageView = new ImageView(context);
+ imageView.setImageResource(R.mipmap.smartparking_logo_round);
+ toastContentView.addView(imageView, 0);
+ toast.show();
+ }
+
+ public static void setNewStateOnSpot(final Context context, boolean isParking, int spotId) {
+ Gson gson = new GsonBuilder()
+ .setLenient()
+ .create();
+
+ final OkHttpClient okHttpClient = new OkHttpClient.Builder()
+ .connectTimeout(5, TimeUnit.SECONDS)
+ .writeTimeout(20, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .addInterceptor(new AddUserTokenInterceptor(context))
+ .build();
+
+ Retrofit retrofit = new Retrofit.Builder()
+ .client(okHttpClient)
+ .baseUrl(Constants.BASE_URL)
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .build();
+
+ SmartParkingAPI smartParkingAPI = retrofit.create(SmartParkingAPI.class);
+ if(isParking){
+ Call call = smartParkingAPI.setOccupiedSpot(spotId);
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ switch (response.code()) {
+ case 200:
+ showToast(String.valueOf(R.string.parked_successfull), context);
+ break;
+ default:
+ showToast(String.valueOf(R.string.unsuccessful), context);
+ break;
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ t.printStackTrace();
+ }
+ });
+ }else{
+ Call call = smartParkingAPI.resetFreeSpot(spotId);
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ switch (response.code()) {
+ case 200:
+ showToast(String.valueOf(R.string.free_successfull), context);
+ break;
+ default:
+ showToast(String.valueOf(R.string.unsuccessful), context);
+ break;
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ t.printStackTrace();
+ }
+ });
+ }
+
+ }
+
+ public static void setEntranceEvent(Context context, Location location, String eventType){
+ SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.CLIENTE_DATA,
+ Context.MODE_PRIVATE);
+
+ String userUrl = sharedPreferences.getString(Constants.USER_URL, "");
+ Events events = new Events();
+ EventProperties properties = new EventProperties();
+ PointGeometry geometry = new PointGeometry();
+ properties.setApplication(Constants.APPLICATION_ID);
+ properties.setAgent(userUrl);
+ properties.setE_type(Constants.BASE_URL + Constants.EVENT_BASIC + eventType);
+ geometry.setPointCoordinates(location);
+ events.setType("Feature");
+ events.setProperties(properties);
+ events.setGeometry(geometry);
+
+ Gson gson = new GsonBuilder()
+ .setLenient()
+ .create();
+
+ final OkHttpClient okHttpClient = new OkHttpClient.Builder()
+ .connectTimeout(5, TimeUnit.SECONDS)
+ .writeTimeout(20, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .addInterceptor(new AddUserTokenInterceptor(context))
+ .build();
+
+ Retrofit retrofit = new Retrofit.Builder()
+ .client(okHttpClient)
+ .baseUrl(Constants.BASE_URL)
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .build();
+
+ SmartParkingAPI smartParkingAPI = retrofit.create(SmartParkingAPI.class);
+ Call call = smartParkingAPI.setUserEvent("application/vnd.geo+json", events);
+
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ switch (response.code()) {
+ case 200:
+ Log.i(LOG_TAG, "Evento de entrada enviado correctamente");
+ break;
+ default:
+ Log.e(LOG_TAG, "Evento de entrada enviado incorrectamente");
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ t.printStackTrace();
+ Log.e(LOG_TAG, t.toString());
+ }
+ });
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/smarttraffic/smartparking/activities/ChangePasswordActivity.java b/app/src/main/java/smarttraffic/smartparking/activities/ChangePasswordActivity.java
new file mode 100644
index 0000000..c158c0d
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/activities/ChangePasswordActivity.java
@@ -0,0 +1,221 @@
+package smarttraffic.smartparking.activities;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import java.util.concurrent.TimeUnit;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import okhttp3.OkHttpClient;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+import smarttraffic.smartparking.Constants;
+import smarttraffic.smartparking.R;
+import smarttraffic.smartparking.SmartParkingAPI;
+import smarttraffic.smartparking.dataModels.ProfileUser;
+import smarttraffic.smartparking.Interceptors.AddUserTokenInterceptor;
+
+/**
+ * Created by Joaquin Olivera on july 19.
+ *
+ * @author joaquin
+ */
+
+public class ChangePasswordActivity extends AppCompatActivity {
+
+ private static final String LOG_TAG = "ChangePasswordActivity";
+
+ private static final String PASSWORDS_NOT_MATCH = "Las contraseñas no coinciden!";
+ private static final String CHANGE_SUCCESS = "EXITOSO!";
+ private static final String CHANGE_NOT_SUCCESS = "La contraseña actual no coincide con la de su usuario!";
+ private static final String SERVER_MISTAQUE = "Las contraseña no se ha podido cambiar.";
+
+ @BindView(R.id.changePasswordButton)
+ Button changePassButton;
+ @BindView(R.id.currentPassword)
+ EditText currentPassword;
+ @BindView(R.id.newPassword1)
+ EditText firstNewPassword;
+ @BindView(R.id.newPassword2)
+ EditText secondNewPassword;
+ @BindView(R.id.passwordNotMatch)
+ TextView passwordNotMatch;
+
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.change_password_layout);
+ ButterKnife.bind(this);
+ final SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(
+ Constants.CLIENTE_DATA, Context.MODE_PRIVATE);
+
+ final String userPassword = sharedPreferences.getString(Constants.USER_PASSWORD, "");
+
+ firstNewPassword.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ //Not needed...
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ //Not needed...
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if(!firstNewPassword.getText().toString().equals(
+ secondNewPassword.getText().toString())){
+ passwordNotMatch.setVisibility(View.VISIBLE);
+ }else{
+ passwordNotMatch.setVisibility(View.INVISIBLE);
+ }
+ }
+ });
+
+ secondNewPassword.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ //Not needed...
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ //Not needed...
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if(!firstNewPassword.getText().toString().equals(
+ secondNewPassword.getText().toString())){
+ passwordNotMatch.setVisibility(View.VISIBLE);
+
+ }else{
+ passwordNotMatch.setVisibility(View.INVISIBLE);
+ }
+ }
+ });
+
+ changePassButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Log.v(LOG_TAG, "User trying to change his password");
+ if(currentPassword.getText().toString().equals(userPassword)){
+ changeProfileUser(sharedPreferences);
+ }else{
+ showToast(PASSWORDS_NOT_MATCH);
+ }
+ }
+ });
+ }
+
+ private void changeProfileUser(SharedPreferences sharedPreferences) {
+ Password password = new Password();
+ password.setNewPassword(firstNewPassword.getText().toString());
+ Gson gson = new GsonBuilder()
+ .setLenient()
+ .create();
+
+ final OkHttpClient okHttpClient = new OkHttpClient.Builder()
+ .connectTimeout(5, TimeUnit.SECONDS)
+ .writeTimeout(20, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .addInterceptor(new AddUserTokenInterceptor(this))
+ .build();
+
+ Retrofit retrofit = new Retrofit.Builder()
+ .client(okHttpClient)
+ .baseUrl(Constants.BASE_URL)
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .build();
+
+ int userId = sharedPreferences.getInt(Constants.USER_ID, -1);
+
+ SmartParkingAPI smartParkingAPI = retrofit.create(SmartParkingAPI.class);
+ Call call = smartParkingAPI.updateUserProfile(userId, password);
+
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ switch (response.code()) {
+ case 200:
+ showToast(CHANGE_SUCCESS);
+ Intent intent = new Intent(ChangePasswordActivity.this,
+ HomeActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ break;
+ case 400:
+ showToast(CHANGE_NOT_SUCCESS);
+ break;
+ default:
+ break;
+ }
+ }
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ t.printStackTrace();
+ showToast(SERVER_MISTAQUE);
+ Log.e(LOG_TAG,t.toString());
+ }
+ });
+
+ }
+
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ }
+
+ // Show images in Toast prompt.
+ private void showToast(String message) {
+ Toast toast = Toast.makeText(this, message, Toast.LENGTH_LONG);
+ toast.setGravity(Gravity.CENTER, 0, 0);
+ LinearLayout toastContentView = (LinearLayout) toast.getView();
+ ImageView imageView = new ImageView(this);
+ imageView.setImageResource(R.mipmap.smartparking_logo_round);
+ toastContentView.addView(imageView, 0);
+ toast.show();
+ }
+
+ public class Password {
+ private String password;
+
+ public String getNewPassword() {
+ return password;
+ }
+
+ public void setNewPassword(String newPassword) {
+ this.password = newPassword;
+ }
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/activities/HomeActivity.java b/app/src/main/java/smarttraffic/smartparking/activities/HomeActivity.java
new file mode 100644
index 0000000..ac7c4d6
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/activities/HomeActivity.java
@@ -0,0 +1,1121 @@
+package smarttraffic.smartparking.activities;
+
+import android.Manifest;
+import android.annotation.SuppressLint;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.graphics.Color;
+import android.location.Location;
+import android.location.LocationManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.preference.PreferenceManager;
+import android.provider.Settings;
+import android.support.annotation.NonNull;
+import android.support.design.widget.Snackbar;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.LocalBroadcastManager;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.util.Base64;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.Toast;
+import android.support.v7.widget.Toolbar;
+
+import com.google.android.gms.common.api.ApiException;
+import com.google.android.gms.common.api.ResolvableApiException;
+import com.google.android.gms.location.ActivityRecognitionClient;
+import com.google.android.gms.location.DetectedActivity;
+import com.google.android.gms.location.FusedLocationProviderClient;
+import com.google.android.gms.location.Geofence;
+import com.google.android.gms.location.GeofencingClient;
+import com.google.android.gms.location.GeofencingRequest;
+import com.google.android.gms.location.LocationCallback;
+import com.google.android.gms.location.LocationRequest;
+import com.google.android.gms.location.LocationResult;
+import com.google.android.gms.location.LocationServices;
+import com.google.android.gms.location.LocationSettingsRequest;
+import com.google.android.gms.location.LocationSettingsResponse;
+import com.google.android.gms.location.LocationSettingsStatusCodes;
+import com.google.android.gms.location.SettingsClient;
+import com.google.android.gms.tasks.OnCompleteListener;
+import com.google.android.gms.tasks.OnFailureListener;
+import com.google.android.gms.tasks.OnSuccessListener;
+import com.google.android.gms.tasks.Task;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.maps.android.PolyUtil;
+
+import org.osmdroid.api.IMapController;
+import org.osmdroid.config.Configuration;
+import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase;
+import org.osmdroid.util.GeoPoint;
+import org.osmdroid.util.MapTileIndex;
+import org.osmdroid.views.MapView;
+import org.osmdroid.views.overlay.ItemizedIconOverlay;
+import org.osmdroid.views.overlay.ItemizedOverlayWithFocus;
+import org.osmdroid.views.overlay.OverlayItem;
+import org.osmdroid.views.overlay.Polygon;
+import org.osmdroid.views.overlay.ScaleBarOverlay;
+import org.osmdroid.views.overlay.compass.CompassOverlay;
+import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
+import org.osmdroid.views.overlay.gestures.RotationGestureOverlay;
+import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
+import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.TimeUnit;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+import okhttp3.OkHttpClient;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+import smarttraffic.smartparking.BuildConfig;
+import smarttraffic.smartparking.Constants;
+import smarttraffic.smartparking.Interceptors.AddGeoJsonInterceptor;
+import smarttraffic.smartparking.Interceptors.AddUserTokenInterceptor;
+import smarttraffic.smartparking.Interceptors.ReceivedTimeStampInterceptor;
+import smarttraffic.smartparking.R;
+import smarttraffic.smartparking.SmartParkingAPI;
+import smarttraffic.smartparking.SmartParkingInitialData;
+import smarttraffic.smartparking.StatesEnumerations;
+import smarttraffic.smartparking.Utils;
+import smarttraffic.smartparking.dataModels.Lots.Lot;
+import smarttraffic.smartparking.dataModels.Lots.LotList;
+import smarttraffic.smartparking.dataModels.Lots.LotProperties;
+import smarttraffic.smartparking.dataModels.NearbyLocation;
+import smarttraffic.smartparking.dataModels.NearbyPoint;
+import smarttraffic.smartparking.dataModels.Point;
+import smarttraffic.smartparking.dataModels.Spots.Spot;
+import smarttraffic.smartparking.dataModels.Spots.SpotList;
+import smarttraffic.smartparking.dataModels.Spots.SpotProperties;
+import smarttraffic.smartparking.receivers.GeofenceBroadcastReceiver;
+import smarttraffic.smartparking.services.DetectedActivitiesService;
+import smarttraffic.smartparking.services.GeofenceTransitionsJobIntentService;
+
+import static smarttraffic.smartparking.Interceptors.ReceivedTimeStampInterceptor.X_TIMESTAMP;
+
+/**
+ * Created by Joaquin Olivera on july 19.
+ *
+ * @author joaquin
+ */
+
+public class HomeActivity extends AppCompatActivity {
+
+ private static final String LOG_TAG = "HomeActivity";
+
+ @BindView(R.id.mapFragment)
+ MapView mapView;
+ @BindView(R.id.toolbar)
+ Toolbar toolbar;
+ @BindView(R.id.buttonRecenter)
+ ImageButton buttonRecenter;
+
+
+ private FusedLocationProviderClient mFusedLocationClient;
+ private ActivityRecognitionClient mActivityRecognitionClient;
+
+ private SettingsClient mSettingsClient;
+ int activityTransition;
+ int geofenceTransition;
+ int confidence;
+ boolean dialogSendAllready = false;
+ private LocationRequest mLocationRequest;
+ private LocationSettingsRequest mLocationSettingsRequest;
+ private LocationCallback mLocationCallback;
+ private Location mCurrentLocation;
+ private List spots = new ArrayList();
+ private ArrayList geofencesTrigger = new ArrayList<>();
+ private BroadcastReceiver broadcastReceiver;
+ private BroadcastReceiver geofenceReceiver;
+ private GeofencingClient geofencingClient;
+ private PendingIntent mGeofencePendingIntent;
+ private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
+ //MAP...
+ private MyLocationNewOverlay mLocationOverlay;
+ private CompassOverlay mCompassOverlay;
+ private ScaleBarOverlay mScaleBarOverlay;
+ private RotationGestureOverlay mRotationGestureOverlay;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.home_layout);
+ ButterKnife.bind(this);
+
+ setMapView();
+
+ createLocationCallback();
+ createLocationRequest(Constants.getSecondsInMilliseconds() * 2,
+ Constants.getSecondsInMilliseconds());
+ buildLocationSettingsRequest();
+
+ mSettingsClient = LocationServices.getSettingsClient(this);
+ geofencingClient = LocationServices.getGeofencingClient(this);
+ mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
+ mActivityRecognitionClient = new ActivityRecognitionClient(this);
+
+ if (getIntent().getExtras() == null) {
+ addParkingLotsGeofences();
+ }
+
+ buttonRecenter.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if(mLocationOverlay != null){
+ mapView.getController().setCenter(mLocationOverlay.getMyLocation());
+ }
+ }
+ });
+
+ broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(Constants.BROADCAST_TRANSITION_ACTIVITY_INTENT)) {
+ activityTransition = intent.getIntExtra(Constants.ACTIVITY_TYPE_TRANSITION, -1);
+ confidence = intent.getIntExtra(Constants.ACTIVITY_CONFIDENCE_TRANSITION, -1);
+ }
+ }
+ };
+
+ geofenceReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(Constants.getBroadcastGeofenceTriggerIntent())) {
+ geofencesTrigger = intent.getStringArrayListExtra(
+ GeofenceTransitionsJobIntentService.GEOFENCE_TRIGGED);
+ geofenceTransition = intent.getIntExtra(
+ GeofenceTransitionsJobIntentService.TRANSITION,
+ -1);
+ managerOfTransitions();
+ }
+ }
+ };
+ setSupportActionBar(toolbar);
+ }
+
+ private void setMapView() {
+
+ final String basic =
+ "Basic " + Base64.encodeToString(SmartParkingInitialData.getCredentials().getBytes(), Base64.NO_WRAP);
+ final Map AuthHeader = new HashMap<>();
+ AuthHeader.put("Authorization", basic);
+ SharedPreferences preferencesManager = PreferenceManager.getDefaultSharedPreferences(this);
+ SharedPreferences.Editor editor = preferencesManager.edit();
+ for (final Map.Entry entry : AuthHeader.entrySet()) {
+ final String key = "osmdroid.additionalHttpRequestProperty." + entry.getKey();
+ editor.putString(key, entry.getValue()).apply();
+ }
+
+ editor.commit();
+
+ Configuration.getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(
+ this));
+
+ mapView.setTileSource(new OnlineTileSourceBase("SMARTPARKING CartoDB",
+ 16, 22, 256, ".png",
+ new String[]{Constants.TILE_SERVER}) {
+ @Override
+ public String getTileURLString(long pMapTileIndex) {
+ return getBaseUrl()
+ + MapTileIndex.getZoom(pMapTileIndex)
+ + "/" + MapTileIndex.getX(pMapTileIndex)
+ + "/" + MapTileIndex.getY(pMapTileIndex)
+ + mImageFilenameEnding;
+ }
+ });
+
+
+ IMapController mapController = mapView.getController();
+
+ setGralMapConfiguration(mapController);
+ //scale bar
+ setScaleBar();
+
+ setLocationOverlay();
+
+ setCompassGestureOverlays();
+// setMarkersOnMap();
+ //add all overlays
+ addOverlays();
+ }
+
+ private void setMarkersOnMap() {
+ ArrayList items = new ArrayList();
+ OverlayItem overlayItem = new OverlayItem("Title1", "Description",
+ new GeoPoint(-25.30604186, -57.59168641));
+// overlayItem.setMarker(getDrawable(R.drawable.about_menu));
+ items.add(overlayItem);
+ //the overlay
+ ItemizedOverlayWithFocus mOverlay = new ItemizedOverlayWithFocus(items,
+ new ItemizedIconOverlay.OnItemGestureListener() {
+ @Override
+ public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
+ //do something
+ return true;
+ }
+
+ @Override
+ public boolean onItemLongPress(final int index, final OverlayItem item) {
+ return false;
+ }
+ }, this);
+ mOverlay.setFocusItemsOnTap(true);
+
+ mapView.getOverlays().add(mOverlay);
+ }
+
+ private void addOverlays() {
+ mapView.getOverlays().add(mRotationGestureOverlay);
+ mapView.getOverlays().add(mCompassOverlay);
+ mapView.getOverlays().add(mLocationOverlay);
+ mapView.getOverlays().add(mScaleBarOverlay);
+ }
+
+ private void setGralMapConfiguration(IMapController mapController) {
+ mapView.setTilesScaledToDpi(true);
+ mapView.setBuiltInZoomControls(true);
+ mapView.setMultiTouchControls(true);
+ mapView.setFlingEnabled(true);
+ mapController.setZoom(17);
+ }
+
+ private void setScaleBar() {
+ final DisplayMetrics dm = this.getResources().getDisplayMetrics();
+ mScaleBarOverlay = new ScaleBarOverlay(mapView);
+ mScaleBarOverlay.setCentred(true);
+ //play around with these values to get the location on screen in the right place for your application
+ mScaleBarOverlay.setScaleBarOffset(dm.widthPixels / 2, 10);
+ }
+
+ private void setLocationOverlay() {
+ mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(this), mapView);
+ mLocationOverlay.enableMyLocation();
+ mLocationOverlay.enableFollowLocation();
+ mLocationOverlay.setOptionsMenuEnabled(true);
+ }
+
+ private void setCompassGestureOverlays() {
+ //add compass
+ mCompassOverlay = new CompassOverlay(this, new InternalCompassOrientationProvider(this), mapView);
+ mCompassOverlay.enableCompass();
+
+ //rotation gestures
+ mRotationGestureOverlay = new RotationGestureOverlay(this, mapView);
+ mRotationGestureOverlay.setEnabled(true);
+ }
+
+ private void drawPolygon(List geoPoints, String status) {
+ Polygon polygon = new Polygon();
+ String color = "#C0C0C0";
+ if (status.equals(StatesEnumerations.FREE.getEstado())) {
+ color = "#00FF00";
+ } else if (status.equals(StatesEnumerations.OCCUPIED.getEstado())) {
+ color = "#FF0000";
+ }
+ polygon.setFillColor(Color.parseColor(color));
+ polygon.setStrokeColor(Color.parseColor(color));
+ geoPoints.add(geoPoints.get(0)); //forces the loop to close
+ polygon.setPoints(geoPoints);
+ mapView.getOverlayManager().add(polygon);
+ }
+
+ private List spotToListOfGeoPoints(Spot spot) {
+ List polygon = new ArrayList<>();
+ List polygonPoints = spot.getGeometry().getPolygonPoints();
+ if (polygonPoints != null) {
+ for (Point point : polygonPoints) {
+ polygon.add(new GeoPoint(point.getLatitud(), point.getLongitud()));
+ }
+ }
+ return polygon;
+ }
+
+ private void managerOfTransitions() {
+ getSpotsFromGeofence(geofencesTrigger, false);
+ final Handler handler = new Handler();
+ final long delay = Constants.getMinutesInMilliseconds();
+ Runnable cronJob = new Runnable() {
+ public void run() {
+ getSpotsFromGeofence(geofencesTrigger, true);
+ handler.postDelayed(this, delay);
+ }
+ };
+ switch (geofenceTransition) {
+ case Geofence.GEOFENCE_TRANSITION_ENTER:
+ Log.i(LOG_TAG, "Enter Transition");
+ if (checkPermissions()) {
+ startLocationUpdates(mLocationRequest);
+ } else if (!checkPermissions()) {
+ requestPermissions();
+ }
+ handler.postDelayed(cronJob, delay);
+ requestActivityUpdates();
+ Utils.setEntranceEvent(this, mCurrentLocation, "enter_lot");
+ break;
+ case Geofence.GEOFENCE_TRANSITION_EXIT:
+ Log.i(LOG_TAG, "Exit Transition");
+ stopLocationUpdates();
+ removeActivityUpdates();
+ handler.removeCallbacks(cronJob);
+ Utils.setEntranceEvent(this, mCurrentLocation,"exit_lot");
+ break;
+ case Geofence.GEOFENCE_TRANSITION_DWELL:
+ Log.i(LOG_TAG, "Dwell Transition");
+ break;
+ default:
+ Log.i(LOG_TAG, "No transition detected");
+ }
+ }
+
+ private void getSpotsFromGeofence(ArrayList geofencesTrigger, boolean isForUpdate) {
+ if(geofencesTrigger != null) {
+ if(isForUpdate){
+ for (String geofenceTrigger : geofencesTrigger) {
+ updatesSpotsFromGeofence();
+ }
+ }else{
+ for (String geofenceTrigger : geofencesTrigger) {
+ getSpotsGeographicValues(geofenceTrigger);
+ }
+ }
+ }
+ }
+
+ private void getSpotsGeographicValues(String geofencesTrigger) {
+ Gson gson = new GsonBuilder()
+ .setLenient()
+ .create();
+
+ final OkHttpClient okHttpClient = new OkHttpClient.Builder()
+ .connectTimeout(5, TimeUnit.SECONDS)
+ .writeTimeout(20, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .addInterceptor(new AddGeoJsonInterceptor())
+ .addInterceptor(new AddUserTokenInterceptor(this))
+ .build();
+
+ Retrofit retrofit = new Retrofit.Builder()
+ .client(okHttpClient)
+ .baseUrl(Constants.BASE_URL)
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .build();
+ int lotId = Utils.getLotInSharedPreferences(HomeActivity.this, geofencesTrigger);
+ SmartParkingAPI smartParkingAPI = retrofit.create(SmartParkingAPI.class);
+ Call call = smartParkingAPI.getAllGeoJsonSpotsInLot(lotId);
+
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ switch (response.code()) {
+ case 200:
+ SpotList testSpots = response.body();
+ spots = testSpots.getFeatures();
+ if(spots != null){
+ for (Spot spot : spots) {
+ drawPolygon(spotToListOfGeoPoints(spot), spot.getProperties().getState());
+ }
+ }
+ break;
+ default:
+ Toast.makeText(HomeActivity.this, "Por alguna razón no fue posible la conexión",
+ Toast.LENGTH_SHORT).show();
+ break;
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ t.printStackTrace();
+ Log.e(LOG_TAG, t.toString());
+ }
+ });
+ }
+
+ private void updatesSpotsFromGeofence() {
+ SharedPreferences sharedPreferences = this.getSharedPreferences(
+ X_TIMESTAMP,MODE_PRIVATE);
+ NearbyPoint point = new NearbyPoint();
+ if(mCurrentLocation != null){
+ point.setLat(mCurrentLocation.getLatitude());
+ point.setLon(mCurrentLocation.getLongitude());
+ }
+ NearbyLocation nearbyLocation = new NearbyLocation();
+ nearbyLocation.setPoint(point);
+ nearbyLocation.setPrevious_timestamp(sharedPreferences.getString(
+ X_TIMESTAMP,
+ "1559447999"));
+ Gson gson = new GsonBuilder()
+ .setLenient()
+ .create();
+
+ final OkHttpClient okHttpClient = new OkHttpClient.Builder()
+ .connectTimeout(5, TimeUnit.SECONDS)
+ .writeTimeout(20, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .addInterceptor(new ReceivedTimeStampInterceptor(this))
+ .addInterceptor(new AddUserTokenInterceptor(this))
+ .addInterceptor(new AddGeoJsonInterceptor())
+ .build();
+
+ Retrofit retrofit = new Retrofit.Builder()
+ .client(okHttpClient)
+ .baseUrl(Constants.BASE_URL)
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .build();
+
+ SmartParkingAPI smartParkingAPI = retrofit.create(SmartParkingAPI.class);
+ Call call = smartParkingAPI.getGeoJsonNearbySpots(nearbyLocation);
+
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ switch (response.code()) {
+ case 200:
+ List changedSpots = response.body().getFeatures();
+ if(changedSpots != null){
+ for (Spot spot : changedSpots) {
+ drawPolygon(spotToListOfGeoPoints(spot), spot.getProperties().getState());
+ }
+ }
+ break;
+ default:
+ Toast.makeText(HomeActivity.this, "Por alguna razón no fue posible la conexión",
+ Toast.LENGTH_SHORT).show();
+ break;
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ t.printStackTrace();
+ Log.e(LOG_TAG, t.toString());
+ }
+ });
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ if (!checkPermissions()) {
+ requestPermissions();
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ removeActivityUpdates();
+ stopLocationUpdates();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver,
+ new IntentFilter(Constants.BROADCAST_TRANSITION_ACTIVITY_INTENT));
+ LocalBroadcastManager.getInstance(this).registerReceiver(geofenceReceiver,
+ new IntentFilter(Constants.getBroadcastGeofenceTriggerIntent()));
+// managerOfTransitions();
+ mapView.onResume();
+ }
+
+ @Override
+ public void onBackPressed() {
+ super.onBackPressed();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
+ LocalBroadcastManager.getInstance(this).unregisterReceiver(geofenceReceiver);
+ stopLocationUpdates();
+ removeActivityUpdates();
+ mapView.onPause();
+ }
+
+ private void addParkingLotsGeofences() {
+ Gson gson = new GsonBuilder()
+ .setLenient()
+ .create();
+
+ final OkHttpClient okHttpClient = new OkHttpClient.Builder()
+ .connectTimeout(5, TimeUnit.SECONDS)
+ .writeTimeout(20, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .addInterceptor(new AddUserTokenInterceptor(this))
+ .build();
+
+ Retrofit retrofit = new Retrofit.Builder()
+ .client(okHttpClient)
+ .baseUrl(Constants.BASE_URL)
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .build();
+ SmartParkingAPI smartParkingAPI = retrofit.create(SmartParkingAPI.class);
+ Call call = smartParkingAPI.getAllLots();
+
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ switch (response.code()) {
+ case 200:
+ List lots = response.body().getFeatures();
+ Utils.saveLotInSharedPreferences(HomeActivity.this, lots);
+ ArrayList geofenceList = new ArrayList<>();
+ for (Lot lot : lots) {
+ LotProperties properties = lot.getProperties();
+ Point center = properties.getCenter().getCenterPoint();
+ geofenceList.add(generateGeofence(center.getLatitud(),
+ center.getLongitud(),
+ properties.getRadio(),
+ properties.getName()));
+ }
+ Toast.makeText(HomeActivity.this, "Se han agregado todos los geofences",
+ Toast.LENGTH_SHORT).show();
+ addGeofences(geofenceList);
+ break;
+ default:
+ Toast.makeText(HomeActivity.this, "Por problemas de conexion no " +
+ "se han conseguido los predios del sistema",
+ Toast.LENGTH_SHORT).show();
+ break;
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ t.printStackTrace();
+ Log.e(LOG_TAG, t.toString());
+ }
+ });
+ }
+
+ /**
+ * This sample hard codes geofence data. A real app might dynamically create geofences based on
+ * the user's location.
+ */
+ private Geofence generateGeofence(double latitude, double longitud, float radius, String nameId) {
+ Geofence geofence = new Geofence.Builder()
+ .setRequestId(nameId)
+ .setCircularRegion(
+ latitude,
+ longitud,
+ radius
+ )
+ .setExpirationDuration(Geofence.NEVER_EXPIRE)
+ .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
+ Geofence.GEOFENCE_TRANSITION_EXIT)
+ .build();
+ return geofence;
+ }
+
+ /**
+ * Return the current state of the permissions needed.
+ */
+ private boolean checkPermissions() {
+ int permissionState = ActivityCompat.checkSelfPermission(this,
+ Manifest.permission.ACCESS_FINE_LOCATION);
+ return permissionState == PackageManager.PERMISSION_GRANTED;
+ }
+
+ private void requestPermissions() {
+ boolean shouldProvideRationale =
+ ActivityCompat.shouldShowRequestPermissionRationale(this,
+ Manifest.permission.ACCESS_FINE_LOCATION);
+ // Provide an additional rationale to the user. This would happen if the user denied the
+ // request previously, but didn't check the "Don't ask again" checkbox.
+ if (shouldProvideRationale) {
+ Log.i(LOG_TAG, "Displaying permission rationale to provide additional context.");
+ showSnackbar(R.string.permission_rationale, android.R.string.ok,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ // Request permission
+ ActivityCompat.requestPermissions(HomeActivity.this,
+ new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
+ REQUEST_PERMISSIONS_REQUEST_CODE);
+ }
+ });
+ } else {
+ Log.i(LOG_TAG, "Requesting permission");
+ // Request permission. It's possible this can be auto answered if device policy
+ // sets the permission in a given state or the user denied the permission
+ // previously and checked "Never ask again".
+ ActivityCompat.requestPermissions(HomeActivity.this,
+ new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
+ REQUEST_PERMISSIONS_REQUEST_CODE);
+ }
+ }
+
+ /**
+ * Shows a {@link Snackbar} using {@code text}.
+ *
+ * @param text The Snackbar text.
+ */
+ private void showSnackbar(final String text) {
+ View container = findViewById(android.R.id.content);
+ if (container != null) {
+ Snackbar.make(container, text, Snackbar.LENGTH_LONG).show();
+ }
+ }
+
+ /**
+ * Shows a {@link Snackbar}.
+ *
+ * @param mainTextStringId The id for the string resource for the Snackbar text.
+ * @param actionStringId The text of the action item.
+ * @param listener The listener associated with the Snackbar action.
+ */
+ private void showSnackbar(final int mainTextStringId, final int actionStringId,
+ View.OnClickListener listener) {
+ Snackbar.make(
+ findViewById(android.R.id.content),
+ getString(mainTextStringId),
+ Snackbar.LENGTH_INDEFINITE)
+ .setAction(getString(actionStringId), listener).show();
+ }
+
+ /**
+ * Adds geofences. This method should be called after the user has granted the location
+ * permission.
+ */
+ @SuppressWarnings("MissingPermission")
+ private void addGeofences(ArrayList geofenceArrayList) {
+ if (!checkPermissions()) {
+ showSnackbar(getString(R.string.insufficient_permissions));
+ return;
+ }
+ geofencingClient.addGeofences(getGeofencingRequest(geofenceArrayList), getGeofencePendingIntent());
+ }
+
+ /**
+ * Removes geofences. This method should be called after the user has granted the location
+ * permission.
+ */
+ @SuppressWarnings("MissingPermission")
+ private void removeGeofences() {
+ if (!checkPermissions()) {
+ showSnackbar(getString(R.string.insufficient_permissions));
+ return;
+ }
+ geofencingClient.removeGeofences(getGeofencePendingIntent());
+ }
+
+ /**
+ * Gets a PendingIntent to send with the request to add or remove Geofences. Location Services
+ * issues the Intent inside this PendingIntent whenever a geofence transition occurs for the
+ * current list of geofences.
+ *
+ * @return A PendingIntent for the IntentService that handles geofence transitions.
+ */
+ private PendingIntent getGeofencePendingIntent() {
+ // Reuse the PendingIntent if we already have it.
+ if (mGeofencePendingIntent != null) {
+ return mGeofencePendingIntent;
+ }
+ Intent intent = new Intent(this, GeofenceBroadcastReceiver.class);
+ // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling
+ // addGeofences() and removeGeofences().
+ mGeofencePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ return mGeofencePendingIntent;
+ }
+
+ /**
+ * Builds and returns a GeofencingRequest. Specifies the list of geofences to be monitored.
+ * Also specifies how the geofence notifications are initially triggered.
+ */
+ private GeofencingRequest getGeofencingRequest(ArrayList geofenceList) {
+ GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
+ builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
+ builder.addGeofences(geofenceList);
+ return builder.build();
+ }
+
+ private GeofencingRequest getGeofenceRequest(Spot spot) {
+ List points = spot.getGeometry().getPolygonPoints();
+ GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
+ builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
+ builder.addGeofence(generateGeofence(points.get(0).getLatitud(), points.get(0).getLongitud(),
+ 15, "ParkinSpot" + spot.getProperties().getIdFromUrl()));
+ return builder.build();
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions,
+ int[] grantResults) {
+ Log.i(LOG_TAG, "onRequestPermissionResult");
+ if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
+ if (grantResults.length <= 0) {
+ // If user interaction was interrupted, the permission request is cancelled and you
+ // receive empty arrays.
+ Log.i(LOG_TAG, "User interaction was cancelled.");
+ } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ Log.i(LOG_TAG, "Permission granted.");
+ } else {
+ showSnackbar(R.string.permission_denied_explanation, R.string.settings,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ // Build intent that displays the App settings screen.
+ Intent intent = new Intent();
+ intent.setAction(
+ Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ Uri uri = Uri.fromParts("package",
+ BuildConfig.APPLICATION_ID, null);
+ intent.setData(uri);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * Removes location updates from the FusedLocationApi.
+ */
+ private void stopLocationUpdates() {
+ mFusedLocationClient.removeLocationUpdates(mLocationCallback)
+ .addOnCompleteListener(this, new OnCompleteListener() {
+ @Override
+ public void onComplete(Task task) {
+ }
+ });
+ }
+
+ /**
+ * Requests location updates from the FusedLocationApi. Note: we don't call this unless location
+ * runtime permission has been granted.
+ */
+ private void startLocationUpdates(LocationRequest locationRequest) {
+ // Begin by checking if the device has the necessary location settings.
+ mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
+ .addOnSuccessListener(this, new OnSuccessListener() {
+ @SuppressLint("MissingPermission")
+ @Override
+ public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
+ Log.i(LOG_TAG, "All location settings are satisfied.");
+ mFusedLocationClient.requestLocationUpdates(mLocationRequest,
+ mLocationCallback, Looper.myLooper());
+ }
+ })
+ .addOnFailureListener(this, new OnFailureListener() {
+ @Override
+ public void onFailure(@NonNull Exception e) {
+ int statusCode = ((ApiException) e).getStatusCode();
+ switch (statusCode) {
+ case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
+ Log.i(LOG_TAG, "Location settings are not satisfied. Attempting to upgrade " +
+ "location settings ");
+ try {
+ ResolvableApiException rae = (ResolvableApiException) e;
+ rae.startResolutionForResult(HomeActivity.this, Constants.REQUEST_CHECK_SETTINGS);
+ } catch (IntentSender.SendIntentException sie) {
+ Log.i(LOG_TAG, "PendingIntent unable to execute request.");
+ }
+ break;
+ case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
+ String errorMessage = "Location settings are inadequate, and cannot be " +
+ "fixed here. Fix in Settings.";
+ Log.e(LOG_TAG, errorMessage);
+ Toast.makeText(HomeActivity.this, errorMessage, Toast.LENGTH_LONG).show();
+ }
+ }
+ });
+ }
+
+ /**
+ * Creates a callback for receiving location events.
+ */
+ private void createLocationCallback() {
+ mLocationCallback = new LocationCallback() {
+ @Override
+ public void onLocationResult(LocationResult locationResult) {
+ super.onLocationResult(locationResult);
+ mCurrentLocation = locationResult.getLastLocation();
+ checkForUserLocation(mCurrentLocation);
+ }
+ };
+ }
+
+ /**
+ - Is User in a spot?
+ - Is the user STILL in that spot?
+ * THEN, THE USER COULD BE:
+ * PARKING:
+ * - Is the spot free?
+ * THEN: show dialog for secure the action...
+ *FREEING A SPOT:
+ * - Is the spot occupied by the SAME user?
+ * THEN: show dialog for secure the action...**/
+ private void checkForUserLocation(Location mCurrentLocation) {
+ int spotId = isPointInsideParkingSpot(spots, mCurrentLocation);
+ if (spotId != Constants.NOT_IN_PARKINGSPOT &&
+ activityTransition != DetectedActivity.UNKNOWN) {
+ Spot spot = getSpotFromId(spots, spotId);
+ SpotProperties spotProperties = spot.getProperties();
+ if (spotProperties.getState().equals(StatesEnumerations.FREE.getEstado()) ||
+ spotProperties.getState().equals(StatesEnumerations.UNKNOWN.getEstado())) {
+ if(!dialogSendAllready){
+ confirmationOfActionDialog(spotId, true);
+ }
+ } else {
+ if(!dialogSendAllready){
+ confirmationOfActionDialog(spotId, false);
+ }
+ }
+ final Timer timer = new Timer();
+ timer.schedule(new TimerTask() {
+ public void run() {
+ dialogSendAllready = false;
+ timer.cancel();
+ }
+ }, Constants.getMinutesInMilliseconds());
+ }
+ }
+
+ private Spot getSpotFromId(List spots, int spotId) {
+ Spot result = new Spot();
+ for (Spot spot : spots) {
+ if (spot.getProperties().getIdFromUrl() == spotId) {
+ result = spot;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Show a dialog tha could be:
+ * OCCUPYING a spot OR FREEING ONE
+ * **/
+ @SuppressWarnings("MissingPermission")
+ private void confirmationOfActionDialog(final int spotIdIn, final boolean isParking) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ if (isParking) {
+ builder.setMessage(R.string.are_you_parking)
+ .setPositiveButton(R.string.button_accept, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ Utils.setNewStateOnSpot(HomeActivity.this, isParking, spotIdIn);
+// geofencingClient.addGeofences(getGeofenceRequest(spotIn),
+// getGeofencePendingIntent());
+ }
+ })
+ .setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User cancelled the dialog
+ }
+ });
+ }else{
+ builder.setMessage(R.string.are_you_vacating_a_place)
+ .setPositiveButton(R.string.button_accept, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ Utils.setNewStateOnSpot(HomeActivity.this, isParking, spotIdIn);
+// List geofencesToRemove = new ArrayList<>();
+// geofencesToRemove.add("ParkinSpot" + spotIn.getId());
+// geofencingClient.removeGeofences(geofencesToRemove);
+ }
+ })
+ .setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User cancelled the dialog
+ }
+ });
+ }
+ final AlertDialog alertDialog = builder.create();
+ alertDialog.show();
+ dialogSendAllready = true;
+
+ final Timer timer = new Timer();
+ timer.schedule(new TimerTask() {
+ public void run() {
+ alertDialog.dismiss();
+ Utils.setNewStateOnSpot(HomeActivity.this, isParking, spotIdIn);
+ timer.cancel();
+ }
+ }, 15000);
+ }
+
+ public boolean isPointInsidePolygon(Spot spot, Location location){
+ return PolyUtil.containsLocation(location.getLatitude(),location.getLongitude(),spot.toLatLngList(),
+ true);
+ }
+
+ public int isPointInsideParkingSpot(List ParkingSpot, Location location){
+ for(Spot spot : ParkingSpot){
+ if (isPointInsidePolygon(spot, location)){
+ return spot.getProperties().getIdFromUrl();
+ }
+ }
+ return Constants.NOT_IN_PARKINGSPOT;
+ }
+ /**
+ * Sets up the location request. Android has two location request settings:
+ * {@code ACCESS_COARSE_LOCATION} and {@code ACCESS_FINE_LOCATION}. These settings control
+ * the accuracy of the current location. This sample uses ACCESS_FINE_LOCATION, as defined in
+ * the AndroidManifest.xml.
+ *
+ * When the ACCESS_FINE_LOCATION setting is specified, combined with a fast update
+ * interval (5 seconds), the Fused Location Provider API returns location updates that are
+ * accurate to within a few feet.
+ *
+ * These settings are appropriate for mapping applications that show real-time location
+ * updates.
+ */
+ private void createLocationRequest(long interval, long fastestInterval) {
+ mLocationRequest = new LocationRequest();
+ mLocationRequest.setInterval(interval);
+ mLocationRequest.setFastestInterval(fastestInterval);
+ mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ }
+ /**
+ * Uses a {@link com.google.android.gms.location.LocationSettingsRequest.Builder} to build
+ * a {@link com.google.android.gms.location.LocationSettingsRequest} that is used for checking
+ * if a device has the needed location settings.
+ */
+ private void buildLocationSettingsRequest() {
+ LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
+ builder.addLocationRequest(mLocationRequest);
+ mLocationSettingsRequest = builder.build();
+ }
+ /**
+ * Registers for activity recognition updates using
+ * {@link ActivityRecognitionClient#requestActivityUpdates(long, PendingIntent)}.
+ * Registers success and failure callbacks.
+ */
+ public void requestActivityUpdates() {
+ Task task = mActivityRecognitionClient.requestActivityUpdates(
+ Constants.DETECTION_INTERVAL_IN_MILLISECONDS,
+ getActivityDetectionPendingIntent());
+
+ task.addOnSuccessListener(new OnSuccessListener() {
+ @Override
+ public void onSuccess(Void result) {
+ setUpdatesRequestedState(true);
+ }
+ });
+ task.addOnFailureListener(new OnFailureListener() {
+ @Override
+ public void onFailure(@NonNull Exception e) {
+ Log.w(LOG_TAG, getString(R.string.activity_updates_not_enabled));
+ setUpdatesRequestedState(false);
+ }
+ });
+ }
+ /**
+ * Removes activity recognition updates using
+ * {@link ActivityRecognitionClient#removeActivityUpdates(PendingIntent)}. Registers success and
+ * failure callbacks.
+ */
+ public void removeActivityUpdates() {
+ @SuppressLint("MissingPermission")
+ Task task = mActivityRecognitionClient.removeActivityUpdates(
+ getActivityDetectionPendingIntent());
+ task.addOnSuccessListener(new OnSuccessListener() {
+ @Override
+ public void onSuccess(Void result) {
+ setUpdatesRequestedState(false);
+ // Reset the display.
+ }
+ });
+
+ task.addOnFailureListener(new OnFailureListener() {
+ @Override
+ public void onFailure(@NonNull Exception e) {
+ Log.w(LOG_TAG, "Failed to enable activity recognition.");
+ Toast.makeText(HomeActivity.this,
+ getString(R.string.activity_updates_not_removed),
+ Toast.LENGTH_SHORT).show();
+ setUpdatesRequestedState(true);
+ }
+ });
+ }
+ /**
+ * Gets a PendingIntent to be sent for each activity detection.
+ */
+ private PendingIntent getActivityDetectionPendingIntent() {
+ Intent intent = new Intent(this, DetectedActivitiesService.class);
+ // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling
+ // requestActivityUpdates() and removeActivityUpdates().
+ return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+ /**
+ * Sets the boolean in SharedPreferences that tracks whether we are requesting activity
+ * updates.
+ */
+ private void setUpdatesRequestedState(boolean requesting) {
+ PreferenceManager.getDefaultSharedPreferences(this)
+ .edit()
+ .putBoolean(Constants.KEY_ACTIVITY_UPDATES_REQUESTED, requesting)
+ .apply();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Inflate the menu; this adds items to the action bar if it is present.
+ getMenuInflater().inflate(R.menu.menu_main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(
+ Constants.CLIENTE_DATA, Context.MODE_PRIVATE);
+ final SharedPreferences.Editor editor = sharedPreferences.edit();
+ int id = item.getItemId();
+ //noinspection SimplifiableIfStatement
+ if (id == R.id.menu_changepass) {
+ Intent changePassIntent = new Intent(HomeActivity.this, ChangePasswordActivity.class);
+ startActivity(changePassIntent);
+ return true;
+ }else if(id == R.id.menu_logout){
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setMessage(R.string.are_you_sure_logout)
+ .setPositiveButton(R.string.button_accept, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ editor.putString(Constants.USER_TOKEN, Constants.CLIENT_NOT_LOGIN).apply();
+ editor.commit();
+ Intent logoutIntent = new Intent(HomeActivity.this, LoginActivity.class);
+ logoutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(logoutIntent);
+ }
+ })
+ .setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User cancelled the dialog
+ }
+ });
+ // Create the AlertDialog object and return it
+ builder.create().show();
+
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/activities/InitActivity.java b/app/src/main/java/smarttraffic/smartparking/activities/InitActivity.java
new file mode 100644
index 0000000..069536c
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/activities/InitActivity.java
@@ -0,0 +1,106 @@
+package smarttraffic.smartparking.activities;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Gravity;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.Toast;
+
+
+import smarttraffic.smartparking.Constants;
+import smarttraffic.smartparking.R;
+
+/**
+ * Created by Joaquin Olivera on july 19.
+ *
+ * @author joaquin
+ */
+
+public class InitActivity extends AppCompatActivity {
+
+ private boolean withInternetConnection;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.init_layout);
+
+ final SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(
+ Constants.CLIENTE_DATA, Context.MODE_PRIVATE);
+
+ final ProgressDialog progressDialog = new ProgressDialog(InitActivity.this,
+ R.style.AppTheme_Dark_Dialog);
+ progressDialog.setIndeterminate(true);
+ progressDialog.setMessage("Inicializando aplicación...");
+ progressDialog.show();
+
+ new android.os.Handler().postDelayed(
+ new Runnable() {
+ public void run() {
+ if (isNetworkAvailable()) {
+ setWithInternetConnection(true);
+ initializeFirstActivity(sharedPreferences);
+ } else {
+ setWithInternetConnection(false);
+ showToast(getString(R.string.no_network_connection));
+ }
+ progressDialog.dismiss();
+ }
+ }, 2000);
+ }
+
+ private boolean isNetworkAvailable() {
+ ConnectivityManager connectivityManager
+ = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
+ return activeNetworkInfo != null && activeNetworkInfo.isConnected();
+ }
+
+ public void setWithInternetConnection(boolean withInternetConnection) {
+ this.withInternetConnection = withInternetConnection;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ }
+
+ private void initializeFirstActivity(SharedPreferences sharedPreferences) {
+ String userToken = sharedPreferences.getString(Constants.USER_TOKEN,
+ Constants.CLIENT_NOT_LOGIN);
+ if(userToken.equals(Constants.CLIENT_NOT_LOGIN)){
+ Intent registration = new Intent(InitActivity.this,
+ RegistryActivity.class);
+ startActivity(registration);
+ }else{
+ Intent registration = new Intent(InitActivity.this,
+ HomeActivity.class);
+ startActivity(registration);
+ }
+ finish();
+ }
+
+ private void showToast(String message) {
+ Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG);
+ toast.setGravity(Gravity.CENTER, 0, 0);
+ LinearLayout toastContentView = (LinearLayout) toast.getView();
+ ImageView imageView = new ImageView(getApplicationContext());
+ imageView.setImageResource(R.mipmap.smartparking_logo_round);
+ toastContentView.addView(imageView, 0);
+ toast.show();
+ }
+
+}
+
diff --git a/app/src/main/java/smarttraffic/smartparking/activities/LoginActivity.java b/app/src/main/java/smarttraffic/smartparking/activities/LoginActivity.java
new file mode 100644
index 0000000..01d950a
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/activities/LoginActivity.java
@@ -0,0 +1,144 @@
+package smarttraffic.smartparking.activities;
+
+import android.app.ProgressDialog;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+
+import smarttraffic.smartparking.R;
+import smarttraffic.smartparking.receivers.LoginReceiver;
+import smarttraffic.smartparking.services.LoginService;
+
+/**
+ * Created by Joaquin Olivera on july 19.
+ *
+ * @author joaquin
+ */
+
+public class LoginActivity extends AppCompatActivity {
+
+ private static final String LOG_TAG = "LoginActivity";
+
+ // binds the elements of the login_layout
+ @BindView(R.id.usernameLogin)
+ EditText usernameText;
+ @BindView(R.id.passwordLogin)
+ EditText passwordText;
+ @BindView(R.id.loginButton)
+ Button loginButton;
+ @BindView(R.id.linkSignUp)
+ TextView goSignUp;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ setContentView(R.layout.login_layout);
+ super.onCreate(savedInstanceState);
+ ButterKnife.bind(this);
+
+ loginButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if(checkCredentialsInput()){
+ makeLoginHappen();
+ // function that makes the makeLoginHappen process...
+ }
+ }
+ });
+
+ goSignUp.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(LoginActivity.this, RegistryActivity.class);
+ startActivity(intent);
+ }
+ });
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(LoginService.LOGIN_ACTION);
+ filter.addAction(LoginService.BAD_LOGIN_ACTION);
+ LoginReceiver loginReceiver = new LoginReceiver();
+ registerReceiver(loginReceiver, filter);
+
+ Intent intent = getIntent();
+ String statusRegistry = intent.getStringExtra("status_registro");
+ if(statusRegistry != null){
+ showToast(statusRegistry);
+ }
+ }
+
+ private void makeLoginHappen() {
+ Log.d(LOG_TAG, "User trying to make the login");
+
+ loginButton.setEnabled(false);
+
+ final ProgressDialog progressDialog = new ProgressDialog(LoginActivity.this,
+ R.style.AppTheme_Dark_Dialog);
+ progressDialog.setIndeterminate(true);
+ progressDialog.setMessage("Verificando...");
+ sendLoginRequest();
+ progressDialog.show();
+
+ new android.os.Handler().postDelayed(
+ new Runnable() {
+ public void run() {
+ /**Here the service get the request of Login...**/
+ loginButton.setEnabled(true);
+ progressDialog.dismiss();
+ }
+ }, 2000);
+ eraseCredentials();
+ }
+
+ private void eraseCredentials() {
+ usernameText.setText("");
+ passwordText.setText("");
+ }
+
+ private void sendLoginRequest() {
+ Intent loginIntent = new Intent(LoginActivity.this, LoginService.class);
+ loginIntent.putExtra("username", usernameText.getText().toString());
+ loginIntent.putExtra("password", passwordText.getText().toString());
+ startService(loginIntent);
+ }
+
+ @Override
+ public void onBackPressed() {
+ // disable going back...
+ moveTaskToBack(true);
+ }
+
+ // Show images in Toast prompt.
+ private void showToast(String message) {
+ Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG);
+ toast.setGravity(Gravity.CENTER, 0, 0);
+ LinearLayout toastContentView = (LinearLayout) toast.getView();
+ ImageView imageView = new ImageView(getApplicationContext());
+ imageView.setImageResource(R.mipmap.smartparking_logo_round);
+ toastContentView.addView(imageView, 0);
+ toast.show();
+ }
+
+ private boolean checkCredentialsInput(){
+ if(usernameText.getText().toString() != null){
+ return true;
+ }else{
+ showToast("El USERNAME no puede estar vacio!");
+ return false;
+ }
+ }
+
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/activities/RegistryActivity.java b/app/src/main/java/smarttraffic/smartparking/activities/RegistryActivity.java
new file mode 100644
index 0000000..ada4a6d
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/activities/RegistryActivity.java
@@ -0,0 +1,270 @@
+package smarttraffic.smartparking.activities;
+
+import android.app.DatePickerDialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
+import android.support.v7.app.AppCompatActivity;
+import android.text.method.HideReturnsTransformationMethod;
+import android.text.method.PasswordTransformationMethod;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.DatePicker;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.Calendar;
+import java.util.Random;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import smarttraffic.smartparking.R;
+import smarttraffic.smartparking.receivers.RegistrationReceiver;
+import smarttraffic.smartparking.services.RegistrationService;
+
+/**
+ * Created by Joaquin Olivera on july 19.
+ *
+ * @author joaquin
+ */
+
+public class RegistryActivity extends AppCompatActivity {
+
+ /**
+ * The user register and get a profile on the system...
+ * **/
+
+ private static final String LOG_TAG = "RegistryActivity";
+
+ private static final String CERO = "0";
+ private static final String GUION = "-";
+
+ @BindView(R.id.usernameSignUp)
+ TextView usernameInput;
+ @BindView(R.id.passwordSignUp)
+ EditText passwordInput;
+ @BindView(R.id.birthDate)
+ TextView birthDate;
+ @BindView(R.id.maleRadButton)
+ RadioButton maleRadButton;
+ @BindView(R.id.femaleRadButton)
+ RadioButton femaleRadButton;
+ @BindView(R.id.datePickerButton)
+ ImageButton datePickerButton;
+ @BindView(R.id.sexRadioGroup)
+ RadioGroup sexSelectRadioGroup;
+ @BindView(R.id.acceptTermsCheckBox)
+ CheckBox termsAndConditions;
+ @BindView(R.id.textInTermsAndCond)
+ TextView textInTermsAndCond;
+ @BindView(R.id.signUpButton)
+ Button signInButton;
+ @BindView(R.id.goToLogin)
+ Button goToLogin;
+ @BindView(R.id.passModeButton)
+ ImageButton passwordModeButton;
+ @BindView(R.id.setRandomUser)
+ ImageButton randomUser;
+
+ public final Calendar calendar = Calendar.getInstance();
+ private final int MAX_LENGTH = 10;
+ public static Random RANDOM = new Random();
+ public static final String DATA = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+ final int actuallMonth = calendar.get(Calendar.MONTH);
+ final int actuallDay = calendar.get(Calendar.DAY_OF_MONTH);
+ final int actuallYear = calendar.get(Calendar.YEAR);
+ private boolean showPasswordText = false;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.registry_layout);
+ ButterKnife.bind(this);
+
+// signInButton.setEnabled(false);
+ //TODO:make EULAActivity...
+// textInTermsAndCond.setOnClickListener(new View.OnClickListener() {
+// @Override
+// public void onClick(View v) {
+// Intent intent = new Intent(RegistryActivity.this, EulaActivity.class);
+// startActivity(intent);
+// }
+// });
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(RegistrationService.REGISTRATION_OK);
+ filter.addAction(RegistrationService.BAD_REGISTRATION);
+ RegistrationReceiver registrationReceiver = new RegistrationReceiver();
+ registerReceiver(registrationReceiver, filter);
+
+ datePickerButton.setOnClickListener(new View.OnClickListener() {
+ @RequiresApi(api = Build.VERSION_CODES.N)
+ @Override
+ public void onClick(View v) {
+ getDatePickedUp();
+ }
+ });
+ signInButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ createRegister();
+ }
+ });
+ goToLogin.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ goToLoginActivity();
+ }
+ });
+ passwordModeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Context context = getApplicationContext();
+ //TODO: if image is showText set TO don't ShowText
+ // and set password text Visual for user...
+ if(!showPasswordText){
+ passwordModeButton.setImageDrawable(
+ context.getDrawable(R.drawable.dontshowtext));
+ //Show Password:
+ passwordInput.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
+ showPasswordText = !showPasswordText;
+ }else{
+ passwordModeButton.setImageDrawable(context.getDrawable(R.drawable.showtext));
+ //Hide Password:
+ passwordInput.setTransformationMethod(PasswordTransformationMethod.getInstance());
+ showPasswordText = !showPasswordText;
+ }
+ }
+ });
+ randomUser.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ usernameInput.setText(randomString());
+ }
+ });
+ }
+
+ private void goToLoginActivity() {
+ Intent intent = new Intent(RegistryActivity.this, LoginActivity.class);
+ startActivity(intent);
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.N)
+ private void getDatePickedUp() {
+ DatePickerDialog datePickerDialog = new DatePickerDialog(this, R.style.datepicker, new DatePickerDialog.OnDateSetListener() {
+ @Override
+ public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
+ final int mesActual = month + 1;
+ String diaFormateado = (dayOfMonth < 10)? CERO + String.valueOf(dayOfMonth):String.valueOf(dayOfMonth);
+ String mesFormateado = (mesActual < 10)? CERO + String.valueOf(mesActual):String.valueOf(mesActual);
+ birthDate.setText(year + GUION + mesFormateado + GUION + diaFormateado);
+ }
+
+ }, actuallYear, actuallMonth, actuallDay);
+ datePickerDialog.show();
+ }
+
+ private void createRegister() {
+ Log.d(LOG_TAG, "User trying to registry");
+
+ signInButton.setEnabled(false);
+
+ final ProgressDialog progressDialog = new ProgressDialog(RegistryActivity.this,
+ R.style.AppTheme_Dark_Dialog);
+ progressDialog.setIndeterminate(true);
+ progressDialog.setMessage("Creando el registro...");
+
+ if(dataIsCorrectlyComplete()){
+ sendRegistrationPetition();
+ progressDialog.show();
+ new android.os.Handler().postDelayed(
+ new Runnable() {
+ public void run() {
+ /**Here the service get the request of registration...**/
+ signInButton.setEnabled(true);
+ progressDialog.dismiss();
+ }
+ }, 3000);
+ }
+ }
+
+ private boolean dataIsCorrectlyComplete() {
+ if(termsAndConditions.isChecked()){
+ if(passwordInput.getText().toString().length() > 5){
+ if(maleRadButton.isChecked() || femaleRadButton.isChecked()){
+ if(!birthDate.getText().toString().isEmpty()){
+ return true;
+ }else{
+ showToast("Favor ponga su EDAD(en años)!");
+ return false;
+ }
+ }else{
+ showToast("Es necesario elegir alguna opcion de SEXO!");
+ return false;
+ }
+ }else{
+ showToast("La CONTRASEÑA debe tener al menos 6 caracteres!");
+ return false;
+ }
+ }else{
+ showToast("Tienes que aceptar los TERMINOS y CONDICIONES!");
+ return false;
+ }
+ }
+
+ private void sendRegistrationPetition() {
+ Intent registryIntent = new Intent(RegistryActivity.this, RegistrationService.class);
+ registryIntent.putExtra("username", usernameInput.getText().toString());
+ registryIntent.putExtra("password", passwordInput.getText().toString());
+ registryIntent.putExtra("birth_date", birthDate.getText().toString());
+ if(onRadioButtonClicked() != null){
+ registryIntent.putExtra("sex", onRadioButtonClicked());
+ }
+ startService(registryIntent);
+ }
+
+ public String onRadioButtonClicked() {
+ if(femaleRadButton.isChecked()){
+ return "F";
+ }else if(maleRadButton.isChecked()){
+ return "M";
+ }else{
+ return null;
+ }
+ }
+
+ // Show images in Toast prompt.
+ private void showToast(String message) {
+ Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG);
+ toast.setGravity(Gravity.CENTER, 0, 0);
+ LinearLayout toastContentView = (LinearLayout) toast.getView();
+ ImageView imageView = new ImageView(getApplicationContext());
+ imageView.setImageResource(R.mipmap.smartparking_logo_round);
+ toastContentView.addView(imageView, 0);
+ toast.show();
+ }
+
+ private String randomString() {
+ StringBuilder sb = new StringBuilder(MAX_LENGTH);
+
+ for (int i = 0; i < MAX_LENGTH; i++) {
+ sb.append(DATA.charAt(RANDOM.nextInt(DATA.length())));
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/activities/ResetPassActivity.java b/app/src/main/java/smarttraffic/smartparking/activities/ResetPassActivity.java
new file mode 100644
index 0000000..72f232b
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/activities/ResetPassActivity.java
@@ -0,0 +1,155 @@
+package smarttraffic.smartparking.activities;
+
+import android.app.DatePickerDialog;
+import android.app.ProgressDialog;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.annotation.RequiresApi;
+import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.Button;
+import android.widget.DatePicker;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.Calendar;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import smarttraffic.smartparking.R;
+
+/**
+ * Created by Joaquin Olivera on july 19.
+ *
+ * @author joaquin
+ */
+
+public class ResetPassActivity extends AppCompatActivity {
+
+ /**
+ * Reset Password if user lost it...
+ * **/
+
+ private static final String LOG_TAG = "ResetPassActivity";
+ private static final String CERO = "0";
+ private static final String GUION = "-";
+ private static final String FAIL_RESET_MESSAGE = "Algo sucedio durante el proceso de " +
+ "recuperacion de la contraseña";
+
+ @BindView(R.id.birthDateResetPass)
+ TextView birthDate;
+ @BindView(R.id.usernameResetPass)
+ EditText username;
+ @BindView(R.id.resetPassButton)
+ Button resetPass;
+ @BindView(R.id.datePickerButtonResetPass)
+ ImageButton datePickerButton;
+ @BindView(R.id.maleResetPass)
+ RadioButton maleRadioButton;
+ @BindView(R.id.femaleResetPass)
+ RadioButton femaleRadioButton;
+
+ public final Calendar calendar = Calendar.getInstance();
+
+ final int actuallMonth = calendar.get(Calendar.MONTH);
+ final int actuallDay = calendar.get(Calendar.DAY_OF_MONTH);
+ final int actuallYear = calendar.get(Calendar.YEAR);
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.reset_password_layout);
+ ButterKnife.bind(this);
+
+ datePickerButton.setOnClickListener(new View.OnClickListener() {
+ @RequiresApi(api = Build.VERSION_CODES.N)
+ @Override
+ public void onClick(View v) {
+ getDatePickedUp();
+ }
+ });
+
+ resetPass.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ resetUsersPassword();
+ }
+ });
+
+ }
+
+ @RequiresApi(api = Build.VERSION_CODES.N)
+ private void getDatePickedUp() {
+ DatePickerDialog datePickerDialog = new DatePickerDialog(this, R.style.datepicker, new DatePickerDialog.OnDateSetListener() {
+ @Override
+ public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
+ final int mesActual = month + 1;
+ String diaFormateado = (dayOfMonth < 10)? CERO + String.valueOf(dayOfMonth):String.valueOf(dayOfMonth);
+ String mesFormateado = (mesActual < 10)? CERO + String.valueOf(mesActual):String.valueOf(mesActual);
+ birthDate.setText(year + GUION + mesFormateado + GUION + diaFormateado);
+ }
+
+ }, actuallYear, actuallMonth, actuallDay);
+ datePickerDialog.show();
+ }
+
+ private void resetUsersPassword() {
+ Log.d(LOG_TAG, "User trying to reset password!");
+
+ resetPass.setEnabled(false);
+
+ final ProgressDialog progressDialog = new ProgressDialog(ResetPassActivity.this,
+ R.style.AppTheme_Dark_Dialog);
+ progressDialog.setIndeterminate(true);
+ progressDialog.setMessage("Realizando las consultas pertinentes...");
+
+ //TODO: with data introduce, consult if user exists with those data...
+ sendResetPassRequest();
+ progressDialog.show();
+ new android.os.Handler().postDelayed(
+ new Runnable() {
+ public void run() {
+ resetPass.setEnabled(true);
+ progressDialog.dismiss();
+ }
+ }, 3000);
+ }
+
+ private void sendResetPassRequest() {
+ //TODO: request the DB if a user with data introduced exists...
+ /**
+ * @params: username, onRadioButtonClicked(), birthDate
+ * **/
+ }
+
+
+ // Show images in Toast prompt.
+ private void showToast(String message) {
+ Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG);
+ toast.setGravity(Gravity.CENTER, 0, 0);
+ LinearLayout toastContentView = (LinearLayout) toast.getView();
+ ImageView imageView = new ImageView(getApplicationContext());
+ imageView.setImageResource(R.mipmap.smartparking_logo_round);
+ toastContentView.addView(imageView, 0);
+ toast.show();
+ }
+
+ public String onRadioButtonClicked() {
+ if(femaleRadioButton.isChecked()){
+ return "F";
+ }else if(maleRadioButton.isChecked()){
+ return "M";
+ }else{
+ return null;
+ }
+ }
+
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/Credentials.java b/app/src/main/java/smarttraffic/smartparking/dataModels/Credentials.java
new file mode 100644
index 0000000..eed8e55
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/Credentials.java
@@ -0,0 +1,40 @@
+package smarttraffic.smartparking.dataModels;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class Credentials {
+
+ private String username;
+ private String password;
+
+ public Credentials() {
+ }
+
+ @Override
+ public String toString() {
+ return "Credentials{" +
+ "username='" + username + '\'' +
+ ", password='" + password + '\'' +
+ '}';
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/EventProperties.java b/app/src/main/java/smarttraffic/smartparking/dataModels/EventProperties.java
new file mode 100644
index 0000000..0688409
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/EventProperties.java
@@ -0,0 +1,50 @@
+package smarttraffic.smartparking.dataModels;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class EventProperties {
+
+ private String application;
+ private String e_type;
+ private String agent;
+
+ public EventProperties() {
+ }
+
+ @Override
+ public String toString() {
+ return "EventProperties{" +
+ "application=" + application +
+ ", e_type='" + e_type + '\'' +
+ ", agent='" + agent + '\'' +
+ '}';
+ }
+
+ public String getApplication() {
+ return application;
+ }
+
+ public void setApplication(String application) {
+ this.application = application;
+ }
+
+ public String getE_type() {
+ return e_type;
+ }
+
+ public void setE_type(String e_type) {
+ this.e_type = e_type;
+ }
+
+ public String getAgent() {
+ return agent;
+ }
+
+ public void setAgent(String agent) {
+ this.agent = agent;
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/Events.java b/app/src/main/java/smarttraffic/smartparking/dataModels/Events.java
new file mode 100644
index 0000000..dd742f3
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/Events.java
@@ -0,0 +1,52 @@
+package smarttraffic.smartparking.dataModels;
+
+import smarttraffic.smartparking.dataModels.Lots.PointGeometry;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class Events {
+
+ private String type;
+ private EventProperties properties;
+ private PointGeometry geometry;
+
+ public Events() {
+ }
+
+ @Override
+ public String toString() {
+ return "Events{" +
+ "type='" + type + '\'' +
+ ", properties=" + properties +
+ ", geometry=" + geometry +
+ '}';
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public EventProperties getProperties() {
+ return properties;
+ }
+
+ public void setProperties(EventProperties properties) {
+ this.properties = properties;
+ }
+
+ public PointGeometry getGeometry() {
+ return geometry;
+ }
+
+ public void setGeometry(PointGeometry geometry) {
+ this.geometry = geometry;
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/Lots/Lot.java b/app/src/main/java/smarttraffic/smartparking/dataModels/Lots/Lot.java
new file mode 100644
index 0000000..add3ce4
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/Lots/Lot.java
@@ -0,0 +1,50 @@
+package smarttraffic.smartparking.dataModels.Lots;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class Lot {
+
+ private String type;
+ private LotProperties properties;
+ private PointGeometry geometry;
+
+ public Lot() {
+ }
+
+ @Override
+ public String toString() {
+ return "Lot{" +
+ "type='" + type + '\'' +
+ ", properties=" + properties +
+ ", geometry=" + geometry +
+ '}';
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public LotProperties getProperties() {
+ return properties;
+ }
+
+ public void setProperties(LotProperties properties) {
+ this.properties = properties;
+ }
+
+ public PointGeometry getGeometry() {
+ return geometry;
+ }
+
+ public void setGeometry(PointGeometry geometry) {
+ this.geometry = geometry;
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/Lots/LotList.java b/app/src/main/java/smarttraffic/smartparking/dataModels/Lots/LotList.java
new file mode 100644
index 0000000..ce41257
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/Lots/LotList.java
@@ -0,0 +1,44 @@
+package smarttraffic.smartparking.dataModels.Lots;
+
+import java.util.List;
+
+import smarttraffic.smartparking.dataModels.Lots.Lot;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class LotList {
+
+ private String type;
+ private List features;
+
+ public LotList() {
+ }
+
+ @Override
+ public String toString() {
+ return "LotList{" +
+ "type='" + type + '\'' +
+ ", features=" + features +
+ '}';
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public List getFeatures() {
+ return features;
+ }
+
+ public void setFeatures(List features) {
+ this.features = features;
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/Lots/LotProperties.java b/app/src/main/java/smarttraffic/smartparking/dataModels/Lots/LotProperties.java
new file mode 100644
index 0000000..154e034
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/Lots/LotProperties.java
@@ -0,0 +1,66 @@
+package smarttraffic.smartparking.dataModels.Lots;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class LotProperties {
+
+ private String url;
+ private float radio;
+ private String name;
+ private PointGeometry center;
+
+ public LotProperties() {
+ }
+
+ @Override
+ public String toString() {
+ return "LotProperties{" +
+ "url='" + url + '\'' +
+ ", radio=" + radio +
+ ", name='" + name + '\'' +
+ ", center=" + center +
+ '}';
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public float getRadio() {
+ return radio;
+ }
+
+ public void setRadio(float radio) {
+ this.radio = radio;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public PointGeometry getCenter() {
+ return center;
+ }
+
+ public void setCenter(PointGeometry center) {
+ this.center = center;
+ }
+
+ public int getIdFromUrl() {
+ String[] parts = getUrl().split("/");
+ return Integer.parseInt(parts[parts.length - 1]);
+ }
+
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/Lots/PointGeometry.java b/app/src/main/java/smarttraffic/smartparking/dataModels/Lots/PointGeometry.java
new file mode 100644
index 0000000..87e14bd
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/Lots/PointGeometry.java
@@ -0,0 +1,76 @@
+package smarttraffic.smartparking.dataModels.Lots;
+
+import android.location.Location;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import smarttraffic.smartparking.dataModels.Point;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class PointGeometry {
+
+ private String type = "Point";
+ private List coordinates;
+
+ public PointGeometry() {
+ }
+
+ @Override
+ public String toString() {
+ return "PointGeometry{" +
+ "type='" + type + '\'' +
+ ", coordinates=" + coordinates +
+ '}';
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public List getCoordinates() {
+ return coordinates;
+ }
+
+ public void setCoordinates(List coordinates) {
+ this.coordinates = coordinates;
+ }
+
+ public Point getCenterPoint(){
+ if(getCoordinates() != null){
+ Point centerPoint = new Point(getCoordinates().get(0), getCoordinates().get(1));
+ return centerPoint;
+ }
+ return null;
+ }
+
+ public Point getPointCoordinates(){
+ if(getCoordinates() != null){
+ Point centerPoint = new Point(getCoordinates().get(1), getCoordinates().get(0));
+ return centerPoint;
+ }
+ return null;
+ }
+
+ public void setPointCoordinates(Location location){
+ List points = new ArrayList();
+ if(location != null){
+ points.add(location.getLongitude());
+ points.add(location.getLatitude());
+ }else{
+ points.add((double) 0);
+ points.add((double) 0);
+ }
+
+ setCoordinates(points);
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/NearbyLocation.java b/app/src/main/java/smarttraffic/smartparking/dataModels/NearbyLocation.java
new file mode 100644
index 0000000..85f584c
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/NearbyLocation.java
@@ -0,0 +1,44 @@
+package smarttraffic.smartparking.dataModels;
+
+import java.sql.Timestamp;
+import java.util.Date;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class NearbyLocation {
+
+ private NearbyPoint point;
+ private String previous_timestamp;
+
+ public NearbyLocation() {
+ }
+
+ @Override
+ public String toString() {
+ return "NearbyLocation{" +
+ "point=" + point +
+ ", previous_timestamp=" + previous_timestamp +
+ '}';
+ }
+
+ public NearbyPoint getPoint() {
+ return point;
+ }
+
+ public void setPoint(NearbyPoint point) {
+ this.point = point;
+ }
+
+ public String getPrevious_timestamp() {
+ return previous_timestamp;
+ }
+
+ public void setPrevious_timestamp(String previous_timestamp) {
+ this.previous_timestamp = previous_timestamp;
+ }
+}
+
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/NearbyPoint.java b/app/src/main/java/smarttraffic/smartparking/dataModels/NearbyPoint.java
new file mode 100644
index 0000000..db3a2fc
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/NearbyPoint.java
@@ -0,0 +1,40 @@
+package smarttraffic.smartparking.dataModels;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class NearbyPoint {
+
+ private double lon;
+ private double lat;
+
+ public NearbyPoint() {
+ }
+
+ @Override
+ public String toString() {
+ return "NearbyPoint{" +
+ "lon=" + lon +
+ ", lat=" + lat +
+ '}';
+ }
+
+ public double getLon() {
+ return lon;
+ }
+
+ public void setLon(double lon) {
+ this.lon = lon;
+ }
+
+ public double getLat() {
+ return lat;
+ }
+
+ public void setLat(double lat) {
+ this.lat = lat;
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/Point.java b/app/src/main/java/smarttraffic/smartparking/dataModels/Point.java
new file mode 100644
index 0000000..501b14f
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/Point.java
@@ -0,0 +1,42 @@
+package smarttraffic.smartparking.dataModels;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class Point {
+
+ private double latitud;
+ private double longitud;
+
+ public Point(double latitud, double longitud) {
+ this.latitud = latitud;
+ this.longitud = longitud;
+ }
+
+ @Override
+ public String toString() {
+ return "Point{" +
+ "latitud=" + latitud +
+ ", longitud=" + longitud +
+ '}';
+ }
+
+ public double getLatitud() {
+ return latitud;
+ }
+
+ public void setLatitud(double latitud) {
+ this.latitud = latitud;
+ }
+
+ public double getLongitud() {
+ return longitud;
+ }
+
+ public void setLongitud(double longitud) {
+ this.longitud = longitud;
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/ProfileRegistry.java b/app/src/main/java/smarttraffic/smartparking/dataModels/ProfileRegistry.java
new file mode 100644
index 0000000..fc4b90f
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/ProfileRegistry.java
@@ -0,0 +1,49 @@
+package smarttraffic.smartparking.dataModels;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class ProfileRegistry {
+
+ private String username;
+ private String password;
+ private SmartParkingProfile smartparkingprofile;
+
+ @Override
+ public String toString() {
+ return "ProfileRegistry{" +
+ "username='" + username + '\'' +
+ ", password='" + password + '\'' +
+ ", smartParkingProfile=" + smartparkingprofile +
+ '}';
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public SmartParkingProfile getSmartParkingProfile() {
+ return smartparkingprofile;
+ }
+
+ public void setSmartParkingProfile(SmartParkingProfile smartParkingProfile) {
+ this.smartparkingprofile = smartParkingProfile;
+ }
+
+}
+
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/ProfileUser.java b/app/src/main/java/smarttraffic/smartparking/dataModels/ProfileUser.java
new file mode 100644
index 0000000..63c63cb
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/ProfileUser.java
@@ -0,0 +1,50 @@
+package smarttraffic.smartparking.dataModels;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class ProfileUser {
+
+ private String url;
+ private String username;
+ private SmartParkingProfile smartparkingprofile;
+
+ public ProfileUser() {
+ }
+
+ @Override
+ public String toString() {
+ return "ProfileUser{" +
+ "url='" + url + '\'' +
+ ", username='" + username + '\'' +
+ ", smartParkingProfile=" + smartparkingprofile +
+ '}';
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public SmartParkingProfile getSmartParkingProfile() {
+ return smartparkingprofile;
+ }
+
+ public void setSmartParkingProfile(SmartParkingProfile smartParkingProfile) {
+ this.smartparkingprofile = smartParkingProfile;
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/SmartParkingProfile.java b/app/src/main/java/smarttraffic/smartparking/dataModels/SmartParkingProfile.java
new file mode 100644
index 0000000..2afbef7
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/SmartParkingProfile.java
@@ -0,0 +1,41 @@
+package smarttraffic.smartparking.dataModels;
+
+/**
+ * Created by Joaquin Olivera on july 19.
+ *
+ * @author joaquin
+ */
+
+public class SmartParkingProfile {
+
+ private String birth_date;
+ private String sex;
+
+ public SmartParkingProfile() {
+ }
+
+ @Override
+ public String toString() {
+ return "SmartParkingProfile{" +
+ "birth_date='" + birth_date + '\'' +
+ ", sex='" + sex + '\'' +
+ '}';
+ }
+
+ public String getBirth_date() {
+ return birth_date;
+ }
+
+ public void setBirth_date(String birth_date) {
+ this.birth_date = birth_date;
+ }
+
+ public String getSex() {
+ return sex;
+ }
+
+ public void setSex(String sex) {
+ this.sex = sex;
+ }
+
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/Spots/PolygonGeometry.java b/app/src/main/java/smarttraffic/smartparking/dataModels/Spots/PolygonGeometry.java
new file mode 100644
index 0000000..22403d2
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/Spots/PolygonGeometry.java
@@ -0,0 +1,46 @@
+package smarttraffic.smartparking.dataModels.Spots;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import smarttraffic.smartparking.dataModels.Point;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class PolygonGeometry {
+
+ private String type;
+ private List>> coordinates;
+
+ public List>> getCoordinates() {
+ return coordinates;
+ }
+
+ public void setCoordinates(List>> coordinates) {
+ this.coordinates = coordinates;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public List getPolygonPoints(){
+ List result = new ArrayList<>();
+ List> cordenadas = getCoordinates().get(0);
+ if(cordenadas != null){
+ for(List point : cordenadas){
+ Point newPoint = new Point(point.get(1), point.get(0));
+ result.add(newPoint);
+ }
+ }
+ return result;
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/Spots/Spot.java b/app/src/main/java/smarttraffic/smartparking/dataModels/Spots/Spot.java
new file mode 100644
index 0000000..e8bedb9
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/Spots/Spot.java
@@ -0,0 +1,68 @@
+package smarttraffic.smartparking.dataModels.Spots;
+
+import com.google.android.gms.maps.model.LatLng;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import smarttraffic.smartparking.dataModels.Point;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class Spot {
+
+ private String type;
+ private SpotProperties properties;
+ private PolygonGeometry geometry;
+
+ public Spot() {
+ }
+
+ @Override
+ public String toString() {
+ return "Spot{" +
+ "type='" + type + '\'' +
+ ", properties=" + properties +
+ ", geometry=" + geometry +
+ '}';
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public SpotProperties getProperties() {
+ return properties;
+ }
+
+ public void setProperties(SpotProperties properties) {
+ this.properties = properties;
+ }
+
+ public PolygonGeometry getGeometry() {
+ return geometry;
+ }
+
+ public void setGeometry(PolygonGeometry geometry) {
+ this.geometry = geometry;
+ }
+
+ public List toLatLngList(){
+ List listOfSpots = getGeometry().getPolygonPoints();
+ List resultList = new ArrayList();
+ if(listOfSpots != null){
+ for(Point point : listOfSpots){
+ resultList.add(new LatLng(point.getLatitud(),point.getLongitud()));
+ }
+ }
+ return resultList;
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/Spots/SpotList.java b/app/src/main/java/smarttraffic/smartparking/dataModels/Spots/SpotList.java
new file mode 100644
index 0000000..9323796
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/Spots/SpotList.java
@@ -0,0 +1,42 @@
+package smarttraffic.smartparking.dataModels.Spots;
+
+import java.util.List;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class SpotList {
+
+ private String type;
+ private List features;
+
+ public SpotList() {
+ }
+
+ @Override
+ public String toString() {
+ return "SpotList{" +
+ "type='" + type + '\'' +
+ ", features=" + features +
+ '}';
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public List getFeatures() {
+ return features;
+ }
+
+ public void setFeatures(List features) {
+ this.features = features;
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/Spots/SpotProperties.java b/app/src/main/java/smarttraffic/smartparking/dataModels/Spots/SpotProperties.java
new file mode 100644
index 0000000..7660f10
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/Spots/SpotProperties.java
@@ -0,0 +1,60 @@
+package smarttraffic.smartparking.dataModels.Spots;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class SpotProperties {
+
+ private String url;
+ private String state;
+ private String lot;
+
+ public SpotProperties() {
+ }
+
+ @Override
+ public String toString() {
+ return "SpotProperties{" +
+ "url='" + url + '\'' +
+ ", state='" + state + '\'' +
+ ", lot='" + lot + '\'' +
+ '}';
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getLot() {
+ return lot;
+ }
+
+ public void setLot(String lot) {
+ this.lot = lot;
+ }
+
+ public int getIdFromUrl() {
+ String[] parts = this.url.split("/");
+ return Integer.parseInt(parts[parts.length - 1]);
+ }
+
+ public int getLotId() {
+ String[] parts = this.lot.split("/");
+ return Integer.parseInt(parts[parts.length - 1]);
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/dataModels/UserToken.java b/app/src/main/java/smarttraffic/smartparking/dataModels/UserToken.java
new file mode 100644
index 0000000..a8893fd
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/dataModels/UserToken.java
@@ -0,0 +1,45 @@
+package smarttraffic.smartparking.dataModels;
+
+/**
+ * Created by Joaquin on 09/2019.
+ *
+ * smarttraffic.smartparking.dataModels
+ */
+
+public class UserToken {
+
+ private String token;
+ private String url;
+
+ public UserToken() {
+ }
+
+ @Override
+ public String toString() {
+ return "UserToken{" +
+ "token='" + token + '\'' +
+ ", url='" + url + '\'' +
+ '}';
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public int getIdFromUrl() {
+ String[] parts = this.url.split("/");
+ return Integer.parseInt(parts[parts.length - 1]);
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/receivers/GeofenceBroadcastReceiver.java b/app/src/main/java/smarttraffic/smartparking/receivers/GeofenceBroadcastReceiver.java
new file mode 100644
index 0000000..f1e7909
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/receivers/GeofenceBroadcastReceiver.java
@@ -0,0 +1,15 @@
+package smarttraffic.smartparking.receivers;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import smarttraffic.smartparking.services.GeofenceTransitionsJobIntentService;
+
+public class GeofenceBroadcastReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // Enqueues a JobIntentService passing the context and intent as parameters
+ GeofenceTransitionsJobIntentService.enqueueWork(context, intent);
+ }
+ }
diff --git a/app/src/main/java/smarttraffic/smartparking/receivers/LoginReceiver.java b/app/src/main/java/smarttraffic/smartparking/receivers/LoginReceiver.java
new file mode 100644
index 0000000..5a06507
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/receivers/LoginReceiver.java
@@ -0,0 +1,94 @@
+package smarttraffic.smartparking.receivers;
+
+import android.annotation.SuppressLint;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.view.Gravity;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import butterknife.BindView;
+import smarttraffic.smartparking.R;
+import smarttraffic.smartparking.activities.HomeActivity;
+import smarttraffic.smartparking.services.LoginService;
+
+/**
+ * Created by Joaquin Olivera on july 19.
+ *
+ * @author joaquin
+ */
+
+public class LoginReceiver extends BroadcastReceiver {
+
+ private static final String LOG_TAG = "LoginReceiver";
+
+ private String sex;
+ private Integer age;
+ private Integer identifier;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if(intent.getAction().equals(LoginService.LOGIN_ACTION)) {
+ Intent i = new Intent(context, HomeActivity.class);
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(i);
+ }
+ else if(intent.getAction().equals(LoginService.BAD_LOGIN_ACTION)) {
+ setErrorMessage(intent.getStringExtra(LoginService.PROBLEM));
+ showToast(getErrorMessage(),context);
+ }
+ else if(intent.getAction().equals(LoginService.SERVER_PROBLEM)) {
+ setErrorMessage(intent.getStringExtra(LoginService.PROBLEM));
+ showToast(getErrorMessage(),context);
+ }
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ private String errorMessage;
+
+ public String getSexResponse() {
+ return sex;
+ }
+
+ public void setSexResponse(String sexResponse) {
+ this.sex = sexResponse;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public Integer getIdentifier() {
+ return identifier;
+ }
+
+ public void setIdentifier(Integer identifier) {
+ this.identifier = identifier;
+ }
+
+ // Show images in Toast prompt.
+ @SuppressLint("ResourceAsColor")
+ private void showToast(String message, Context context) {
+ Toast toast = Toast.makeText(context, message, Toast.LENGTH_LONG);
+ toast.setGravity(Gravity.CENTER, 0, 0);
+ LinearLayout toastContentView = (LinearLayout) toast.getView();
+ ImageView imageView = new ImageView(context);
+ imageView.setImageResource(R.mipmap.smartparking_logo_round);
+ toastContentView.addView(imageView, 0);
+ toast.show();
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/receivers/RegistrationReceiver.java b/app/src/main/java/smarttraffic/smartparking/receivers/RegistrationReceiver.java
new file mode 100644
index 0000000..f629176
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/receivers/RegistrationReceiver.java
@@ -0,0 +1,60 @@
+package smarttraffic.smartparking.receivers;
+
+import android.annotation.SuppressLint;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.view.Gravity;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.Toast;
+
+import smarttraffic.smartparking.R;
+import smarttraffic.smartparking.activities.LoginActivity;
+import smarttraffic.smartparking.services.RegistrationService;
+
+/**
+ * Created by Joaquin Olivera on july 19.
+ *
+ * @author joaquin
+ */
+
+public class RegistrationReceiver extends BroadcastReceiver {
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ private String errorMessage;
+ private static final String LOG_TAG = "RegistrationReceiver";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ if(intent.getAction().equals(RegistrationService.REGISTRATION_OK)) {
+ showToast(RegistrationService.REGISTRATION_OK, context);
+ Intent i = new Intent(context, LoginActivity.class);
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(i);
+ }
+ else if(intent.getAction().equals(RegistrationService.BAD_REGISTRATION)) {
+ setErrorMessage(intent.getStringExtra(RegistrationService.PROBLEM));
+ showToast(getErrorMessage(),context);
+ }
+ }
+ // Show images in Toast prompt.
+ @SuppressLint("ResourceAsColor")
+ private void showToast(String message, Context context) {
+ Toast toast = Toast.makeText(context, message, Toast.LENGTH_LONG);
+ toast.setGravity(Gravity.CENTER, 0, 0);
+ LinearLayout toastContentView = (LinearLayout) toast.getView();
+ ImageView imageView = new ImageView(context);
+ imageView.setImageResource(R.mipmap.smartparking_logo_round);
+ toastContentView.addView(imageView, 0);
+ toast.show();
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/services/DetectedActivitiesService.java b/app/src/main/java/smarttraffic/smartparking/services/DetectedActivitiesService.java
new file mode 100644
index 0000000..c5276f2
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/services/DetectedActivitiesService.java
@@ -0,0 +1,61 @@
+package smarttraffic.smartparking.services;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.preference.PreferenceManager;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.google.android.gms.location.ActivityRecognitionResult;
+import com.google.android.gms.location.DetectedActivity;
+
+import java.util.ArrayList;
+
+import smarttraffic.smartparking.Constants;
+import smarttraffic.smartparking.Utils;
+import smarttraffic.smartparking.activities.HomeActivity;
+
+public class DetectedActivitiesService extends IntentService {
+
+ private static final String LOG_TAG = "DetectedActivities";
+
+ public DetectedActivitiesService() {
+ super("DetectedActivitiesService");
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
+
+ // Get the list of the probable activities associated with the current state of the
+ // device. Each activity is associated with a confidence level, which is an int between
+ // 0 and 100.
+
+ ArrayList detectedActivities = (ArrayList) result.getProbableActivities();
+
+ PreferenceManager.getDefaultSharedPreferences(this)
+ .edit()
+ .putString(Constants.KEY_DETECTED_ACTIVITIES,
+ Utils.detectedActivitiesToJson(detectedActivities))
+ .apply();
+
+ // Log each activity.
+ Log.i(LOG_TAG, Utils.getActivityString(
+ getApplicationContext(),
+ result.getMostProbableActivity().getType()) + " " + result.getMostProbableActivity().getConfidence() + "%");
+ broadcastActivityTransition(result);
+ }
+
+ private void broadcastActivityTransition(ActivityRecognitionResult result) {
+ Intent intent = new Intent(Constants.BROADCAST_TRANSITION_ACTIVITY_INTENT);
+ intent.putExtra(Constants.ACTIVITY_TYPE_TRANSITION, result.getMostProbableActivity().getType());
+ intent.putExtra(Constants.ACTIVITY_CONFIDENCE_TRANSITION, result.getMostProbableActivity().getConfidence());
+ LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/services/GeofenceTransitionsJobIntentService.java b/app/src/main/java/smarttraffic/smartparking/services/GeofenceTransitionsJobIntentService.java
new file mode 100644
index 0000000..bf467f7
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/services/GeofenceTransitionsJobIntentService.java
@@ -0,0 +1,217 @@
+package smarttraffic.smartparking.services;
+
+import android.annotation.SuppressLint;
+import android.app.ActivityManager;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.TaskStackBuilder;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.location.Location;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.v4.app.JobIntentService;
+import android.support.v4.app.NotificationCompat;
+import android.support.v4.content.LocalBroadcastManager;
+import android.support.v7.app.AlertDialog;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.google.android.gms.location.ActivityRecognitionResult;
+import com.google.android.gms.location.Geofence;
+import com.google.android.gms.location.GeofencingEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import smarttraffic.smartparking.Constants;
+import smarttraffic.smartparking.GeofenceErrorMessages;
+import smarttraffic.smartparking.R;
+import smarttraffic.smartparking.activities.HomeActivity;
+
+
+public class GeofenceTransitionsJobIntentService extends JobIntentService {
+
+ private static final int JOB_ID = 573;
+
+ private static final String LOG_TAG = "GeofenceJobService";
+
+ private static final String CHANNEL_ID = "channel_01";
+
+ public static final String TRANSITION = "TRANSITION";
+ public static final String GEOFENCE_TRIGGED = "GEOFENCE_TRIGGED";
+ private static final String HAS_TRANSITION = "HAS_TRANSITION";
+
+
+ /**
+ * Convenience method for enqueuing work in to this service.
+ */
+ public static void enqueueWork(Context context, Intent intent) {
+ enqueueWork(context, GeofenceTransitionsJobIntentService.class, JOB_ID, intent);
+ }
+
+ /**
+ * Handles incoming intents.
+ * @param intent sent by Location Services. This Intent is provided to Location
+ * Services (inside a PendingIntent) when addGeofences() is called.
+ */
+ @SuppressLint("StringFormatInvalid")
+ @Override
+ protected void onHandleWork(Intent intent) {
+ GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
+ if (geofencingEvent.hasError()) {
+ String errorMessage = GeofenceErrorMessages.getErrorString(this,
+ geofencingEvent.getErrorCode());
+ Log.e(LOG_TAG, errorMessage);
+ return;
+ }
+ // Get the transition type.
+ int geofenceTransition = geofencingEvent.getGeofenceTransition();
+ // Test that the reported transition was of interest.
+ if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
+ geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT ||
+ geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL) {
+ // Get the geofences that were triggered. A single event can trigger multiple geofences.
+ List triggeringGeofences = geofencingEvent.getTriggeringGeofences();
+ // Get the transition details as a String.
+ String geofenceTransitionDetails = getGeofenceTransitionDetails(geofenceTransition,
+ triggeringGeofences);
+ // Send notification and log the transition details.
+ broadcastGeofenceTransition(triggeringGeofences, geofenceTransition);
+ sendNotification(geofenceTransitionDetails, triggeringGeofences, geofenceTransition);
+ Log.i(LOG_TAG, geofenceTransitionDetails);
+ } else {
+ // Log the error.
+ Log.e(LOG_TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition));
+ }
+ }
+
+
+ /**
+ * Gets transition details and returns them as a formatted string.
+ *
+ * @param geofenceTransition The ID of the geofence transition.
+ * @param triggeringGeofences The geofence(s) triggered.
+ * @return The transition details formatted as String.
+ */
+ private String getGeofenceTransitionDetails(
+ int geofenceTransition,
+ List triggeringGeofences) {
+
+ String geofenceTransitionString = getTransitionString(geofenceTransition);
+
+ // Get the Ids of each geofence that was triggered.
+ ArrayList triggeringGeofencesIdsList = new ArrayList<>();
+ for (Geofence geofence : triggeringGeofences) {
+ triggeringGeofencesIdsList.add(geofence.getRequestId());
+ }
+ String triggeringGeofencesIdsString = TextUtils.join(", ", triggeringGeofencesIdsList);
+
+ return geofenceTransitionString + ": " + triggeringGeofencesIdsString;
+ }
+
+ /**
+ * Posts a notification in the notification bar when a transition is detected.
+ * If the user clicks the notification, control goes to the MainActivity.
+ */
+ private void sendNotification(String notificationDetails, List geofenceList, int transition) {
+ ArrayList fencesTriggersIdList = new ArrayList<>();
+ // Get an instance of the Notification manager
+ NotificationManager mNotificationManager =
+ (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+
+ createNotificationChannel();
+
+ // Create an explicit intent for an Activity in your app
+ Intent notificationIntent = new Intent(getApplicationContext(), HomeActivity.class);
+ for(Geofence geofence : geofenceList){
+ fencesTriggersIdList.add(geofence.getRequestId());
+ }
+ notificationIntent.putExtra(HAS_TRANSITION, true);
+ notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
+ .setSmallIcon(R.drawable.notifications_smart_parking)
+ .setLargeIcon(BitmapFactory.decodeResource(getResources(),
+ R.drawable.notify_smart_parking))
+ .setTimeoutAfter(Constants.getMinutesInMilliseconds() * 5)
+ .setColor(Color.GREEN)
+ .setContentTitle(notificationDetails)
+ .setContentText(getString(R.string.geofence_transition_notification_text))
+ .setPriority(NotificationCompat.PRIORITY_HIGH)
+ .setAutoCancel(true);
+
+ if(transition == Geofence.GEOFENCE_TRANSITION_ENTER){
+ PendingIntent pendingIntent = PendingIntent.getActivity(this,
+ 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ builder.addAction(R.drawable.notifications_smart_parking, "Ir a la aplicación",
+ pendingIntent);
+ }
+ // Set the Channel ID for Android O.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ builder.setChannelId(CHANNEL_ID); // Channel ID
+ }
+
+ // Issue the notification
+ mNotificationManager.notify(0, builder.build());
+ }
+
+ /**
+ * Maps geofence transition types to their human-readable equivalents.
+ *
+ * @param transitionType A transition type constant defined in Geofence
+ * @return A String indicating the type of transition
+ */
+ private String getTransitionString(int transitionType) {
+ switch (transitionType) {
+ case Geofence.GEOFENCE_TRANSITION_ENTER:
+ return getString(R.string.geofence_transition_entered);
+ case Geofence.GEOFENCE_TRANSITION_EXIT:
+ return getString(R.string.geofence_transition_exited);
+ case Geofence.GEOFENCE_TRANSITION_DWELL:
+ return getString(R.string.geofence_transition_dwell);
+ default:
+ return getString(R.string.unknown_geofence_transition);
+ }
+ }
+
+ private void createNotificationChannel() {
+ // Create the NotificationChannel, but only on API 26+ because
+ // the NotificationChannel class is new and not in the support library
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ CharSequence name = getString(R.string.channel_name);
+ String description = getString(R.string.channel_description);
+ int importance = NotificationManager.IMPORTANCE_HIGH;
+ NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
+ channel.setDescription(description);
+ // Register the channel with the system; you can't change the importance
+ // or other notification behaviors after this
+ NotificationManager notificationManager = getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(channel);
+ }
+ }
+
+
+ private void broadcastGeofenceTransition(List triggeringGeofences,
+ int geofenceTransition) {
+ ArrayList fencesTriggered = new ArrayList<>();
+ if(triggeringGeofences != null){
+ for(Geofence geofence : triggeringGeofences){
+ fencesTriggered.add(geofence.getRequestId());
+ }
+ }
+ Intent intent = new Intent(Constants.getBroadcastGeofenceTriggerIntent());
+ intent.putStringArrayListExtra(GEOFENCE_TRIGGED, fencesTriggered);
+ intent.putExtra(TRANSITION, geofenceTransition);
+ LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
+ }
+
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/services/LoginService.java b/app/src/main/java/smarttraffic/smartparking/services/LoginService.java
new file mode 100644
index 0000000..37365e7
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/services/LoginService.java
@@ -0,0 +1,118 @@
+package smarttraffic.smartparking.services;
+
+import android.app.IntentService;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.OkHttpClient;
+
+import okhttp3.ResponseBody;
+import retrofit2.Call;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+import smarttraffic.smartparking.Constants;
+import smarttraffic.smartparking.SmartParkingAPI;
+import smarttraffic.smartparking.dataModels.Credentials;
+import smarttraffic.smartparking.dataModels.UserToken;
+import smarttraffic.smartparking.receivers.LoginReceiver;
+import smarttraffic.smartparking.Interceptors.AddSmartParkingTokenInterceptor;
+
+/**
+ * Created by Joaquin Olivera on july 19.
+ *
+ * @author joaquin
+ */
+
+public class LoginService extends IntentService {
+
+ public static final String PROBLEM = "Ha fallado el proceso de ingreso!";
+ public static final String CANNOT_LOGIN = "No se logro hacer inicio. Revisar credenciales!";
+ public static final String CANNOT_CONNECT_SERVER = "No se pudo conectar con el servidor, favor revisar conexion!";
+ public static final String ULI = "User Login Information";
+ public static final String IULI = "IDENTIFICADOR USUARIO LOGGED IN";
+
+ /**
+ * Creates an IntentService. Invoked by your subclass's constructor.
+ *
+ */
+
+ public LoginService() {
+ super("LoginService");
+ }
+
+ public static final String LOGIN_ACTION = "Login exitoso!";
+ public static final String BAD_LOGIN_ACTION = "Credenciales incorrectas";
+ public static final String SERVER_PROBLEM = "Existe un error con la comunicacion con el servidor!";
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ Credentials userCredentials = new Credentials();
+ userCredentials.setUsername(intent.getStringExtra("username"));
+ userCredentials.setPassword(intent.getStringExtra("password"));
+ Gson gson = new GsonBuilder()
+ .setLenient()
+ .create();
+
+ final OkHttpClient okHttpClient = new OkHttpClient.Builder()
+ .connectTimeout(5, TimeUnit.SECONDS)
+ .writeTimeout(20, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .addInterceptor(new AddSmartParkingTokenInterceptor())
+ .build();
+
+ SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences(
+ Constants.CLIENTE_DATA, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+
+ Retrofit retrofit = new Retrofit.Builder()
+ .client(okHttpClient)
+ .baseUrl(Constants.BASE_URL)
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .build();
+
+ SmartParkingAPI smartParkingAPI = retrofit.create(SmartParkingAPI.class);
+ Call call = smartParkingAPI.getUserToken(userCredentials);
+ Intent loginIntent = new Intent("loginIntent");
+ loginIntent.setClass(this, LoginReceiver.class);
+
+ try{
+ Response result = call.execute();
+ if (result.code() == 200){
+ loginIntent.setAction(LOGIN_ACTION);
+ editor.putString(Constants.USER_TOKEN, result.body().getToken()).apply();
+ editor.putString(Constants.USER_PASSWORD,
+ intent.getStringExtra("password")).apply();
+ editor.putInt(Constants.USER_ID, result.body().getIdFromUrl()).apply();
+ editor.putString(Constants.USER_URL, result.body().getUrl()).apply();
+ editor.commit();
+ }else if (result.code() == 400){
+ ResponseBody error = result.errorBody();
+ loginIntent.putExtra(PROBLEM, "No se puede iniciar sesión " +
+ "con las credenciales proporcionadas");
+ loginIntent.setAction(BAD_LOGIN_ACTION);
+ }
+ else {
+ loginIntent.putExtra(PROBLEM, result.errorBody().string());
+ loginIntent.setAction(SERVER_PROBLEM);
+ }
+ } catch (IOException e) {
+ loginIntent.putExtra(PROBLEM, CANNOT_CONNECT_SERVER);
+ loginIntent.setAction(BAD_LOGIN_ACTION);
+ e.printStackTrace();
+ }
+ sendBroadcast(loginIntent);
+ }
+
+ private int getIdFromUrl(String url) {
+ String[] parts = url.split("/");
+ return Integer.parseInt(parts[parts.length - 1]);
+ }
+}
diff --git a/app/src/main/java/smarttraffic/smartparking/services/RegistrationService.java b/app/src/main/java/smarttraffic/smartparking/services/RegistrationService.java
new file mode 100644
index 0000000..d669d6c
--- /dev/null
+++ b/app/src/main/java/smarttraffic/smartparking/services/RegistrationService.java
@@ -0,0 +1,99 @@
+package smarttraffic.smartparking.services;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.Headers;
+import okhttp3.OkHttpClient;
+import retrofit2.Call;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+import smarttraffic.smartparking.Constants;
+import smarttraffic.smartparking.SmartParkingAPI;
+import smarttraffic.smartparking.dataModels.ProfileRegistry;
+import smarttraffic.smartparking.dataModels.ProfileUser;
+import smarttraffic.smartparking.dataModels.SmartParkingProfile;
+import smarttraffic.smartparking.receivers.RegistrationReceiver;
+import smarttraffic.smartparking.Interceptors.AddSmartParkingTokenInterceptor;
+
+/**
+ * Created by Joaquin Olivera on july 19.
+ *
+ * @author joaquin
+ */
+
+public class RegistrationService extends IntentService {
+
+ public static final String PROBLEM = "Found some Problem in Login";
+ private static final String CANNOT_CONNECT_SERVER = "No se pudo conectar con el servidor," +
+ " favor revisar conexion!";
+
+ public static final String REGISTRATION_OK = "Registro correcto";
+ public static final String BAD_REGISTRATION = "Registro no realizado";
+
+ public RegistrationService() {
+ super("RegistrationService");
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ ProfileRegistry profileRegistry = new ProfileRegistry();
+ profileRegistry.setSmartParkingProfile(new SmartParkingProfile());
+ Bundle extras = intent.getExtras();
+ setRegistrationExtras(extras, profileRegistry);
+
+ Gson gson = new GsonBuilder()
+ .setLenient()
+ .create();
+
+ final OkHttpClient okHttpClient = new OkHttpClient.Builder()
+ .connectTimeout(5, TimeUnit.SECONDS)
+ .writeTimeout(20, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ //add the token header "Authorization"
+ .addInterceptor(new AddSmartParkingTokenInterceptor())
+ .build();
+
+ Retrofit retrofit = new Retrofit.Builder()
+ .client(okHttpClient)
+ .baseUrl(Constants.BASE_URL)
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .build();
+
+ SmartParkingAPI smartParkingAPI = retrofit.create(SmartParkingAPI.class);
+ Call call = smartParkingAPI.signUpUser(profileRegistry);
+ Intent registrationIntent = new Intent("registrationIntent");
+ registrationIntent.setClass(this, RegistrationReceiver.class);
+
+ try {
+ Response result = call.execute();
+ Headers headers = result.headers();
+ if(result.code() == 201){
+ registrationIntent.setAction(REGISTRATION_OK);
+ }else{
+ registrationIntent.putExtra("exists", "Profile already exists");
+ registrationIntent.setAction(BAD_REGISTRATION);
+ }
+ } catch (IOException e) {
+ registrationIntent.putExtra(PROBLEM, CANNOT_CONNECT_SERVER);
+ registrationIntent.setAction(BAD_REGISTRATION);
+ e.printStackTrace();
+ }
+ sendBroadcast(registrationIntent);
+ }
+
+ private void setRegistrationExtras(Bundle extras, ProfileRegistry profileRegistry){
+ profileRegistry.setUsername(extras.getString("username"));
+ profileRegistry.setPassword(extras.getString("password"));
+ profileRegistry.getSmartParkingProfile().setBirth_date(extras.getString("birth_date"));
+ profileRegistry.getSmartParkingProfile().setSex(extras.getString("sex"));
+ }
+}
diff --git a/app/src/main/res/drawable-anydpi-v24/notifications_smart_parking.xml b/app/src/main/res/drawable-anydpi-v24/notifications_smart_parking.xml
new file mode 100644
index 0000000..8394d3f
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi-v24/notifications_smart_parking.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable-anydpi-v24/notify_smart_parking.xml b/app/src/main/res/drawable-anydpi-v24/notify_smart_parking.xml
new file mode 100644
index 0000000..fb3b315
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi-v24/notify_smart_parking.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/about.xml b/app/src/main/res/drawable-anydpi/about.xml
new file mode 100644
index 0000000..3b40a01
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/about.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/to_location.xml b/app/src/main/res/drawable-anydpi/to_location.xml
new file mode 100644
index 0000000..a6fee61
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/to_location.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable-hdpi/about.png b/app/src/main/res/drawable-hdpi/about.png
new file mode 100644
index 0000000..83d4646
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/about.png differ
diff --git a/app/src/main/res/drawable-hdpi/about_menu.png b/app/src/main/res/drawable-hdpi/about_menu.png
new file mode 100644
index 0000000..98fbc39
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/about_menu.png differ
diff --git a/app/src/main/res/drawable-hdpi/changepass_menu.png b/app/src/main/res/drawable-hdpi/changepass_menu.png
new file mode 100644
index 0000000..dba681e
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/changepass_menu.png differ
diff --git a/app/src/main/res/drawable-hdpi/datepicker.png b/app/src/main/res/drawable-hdpi/datepicker.png
new file mode 100644
index 0000000..13c29a4
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/datepicker.png differ
diff --git a/app/src/main/res/drawable-hdpi/dontshowtext.png b/app/src/main/res/drawable-hdpi/dontshowtext.png
new file mode 100644
index 0000000..00efbf5
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/dontshowtext.png differ
diff --git a/app/src/main/res/drawable-hdpi/hamenuitem.png b/app/src/main/res/drawable-hdpi/hamenuitem.png
new file mode 100644
index 0000000..72a5dcb
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/hamenuitem.png differ
diff --git a/app/src/main/res/drawable-hdpi/homemenu.png b/app/src/main/res/drawable-hdpi/homemenu.png
new file mode 100644
index 0000000..afb4496
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/homemenu.png differ
diff --git a/app/src/main/res/drawable-hdpi/logout_menu.png b/app/src/main/res/drawable-hdpi/logout_menu.png
new file mode 100644
index 0000000..d6ce68f
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/logout_menu.png differ
diff --git a/app/src/main/res/drawable-hdpi/marker_icon.png b/app/src/main/res/drawable-hdpi/marker_icon.png
new file mode 100644
index 0000000..505bcc9
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/marker_icon.png differ
diff --git a/app/src/main/res/drawable-hdpi/notifications_smart_parking.png b/app/src/main/res/drawable-hdpi/notifications_smart_parking.png
new file mode 100644
index 0000000..11e5a6f
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/notifications_smart_parking.png differ
diff --git a/app/src/main/res/drawable-hdpi/notify_smart_parking.png b/app/src/main/res/drawable-hdpi/notify_smart_parking.png
new file mode 100644
index 0000000..3947a49
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/notify_smart_parking.png differ
diff --git a/app/src/main/res/drawable-hdpi/settings_menu.png b/app/src/main/res/drawable-hdpi/settings_menu.png
new file mode 100644
index 0000000..f24bb80
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/settings_menu.png differ
diff --git a/app/src/main/res/drawable-hdpi/showtext.png b/app/src/main/res/drawable-hdpi/showtext.png
new file mode 100644
index 0000000..6e8d3bc
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/showtext.png differ
diff --git a/app/src/main/res/drawable-hdpi/to_location.png b/app/src/main/res/drawable-hdpi/to_location.png
new file mode 100644
index 0000000..08806c3
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/to_location.png differ
diff --git a/app/src/main/res/drawable-mdpi/about.png b/app/src/main/res/drawable-mdpi/about.png
new file mode 100644
index 0000000..079c1d1
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/about.png differ
diff --git a/app/src/main/res/drawable-mdpi/about_menu.png b/app/src/main/res/drawable-mdpi/about_menu.png
new file mode 100644
index 0000000..a334e20
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/about_menu.png differ
diff --git a/app/src/main/res/drawable-mdpi/changepass_menu.png b/app/src/main/res/drawable-mdpi/changepass_menu.png
new file mode 100644
index 0000000..8162d39
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/changepass_menu.png differ
diff --git a/app/src/main/res/drawable-mdpi/datepicker.png b/app/src/main/res/drawable-mdpi/datepicker.png
new file mode 100644
index 0000000..acf7972
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/datepicker.png differ
diff --git a/app/src/main/res/drawable-mdpi/dontshowtext.png b/app/src/main/res/drawable-mdpi/dontshowtext.png
new file mode 100644
index 0000000..5ae4947
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/dontshowtext.png differ
diff --git a/app/src/main/res/drawable-mdpi/hamenuitem.png b/app/src/main/res/drawable-mdpi/hamenuitem.png
new file mode 100644
index 0000000..201dfd4
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/hamenuitem.png differ
diff --git a/app/src/main/res/drawable-mdpi/homemenu.png b/app/src/main/res/drawable-mdpi/homemenu.png
new file mode 100644
index 0000000..4990752
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/homemenu.png differ
diff --git a/app/src/main/res/drawable-mdpi/logout_menu.png b/app/src/main/res/drawable-mdpi/logout_menu.png
new file mode 100644
index 0000000..75ed534
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/logout_menu.png differ
diff --git a/app/src/main/res/drawable-mdpi/marker_icon.png b/app/src/main/res/drawable-mdpi/marker_icon.png
new file mode 100644
index 0000000..ce65ee4
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/marker_icon.png differ
diff --git a/app/src/main/res/drawable-mdpi/notifications_smart_parking.png b/app/src/main/res/drawable-mdpi/notifications_smart_parking.png
new file mode 100644
index 0000000..17a747a
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/notifications_smart_parking.png differ
diff --git a/app/src/main/res/drawable-mdpi/notify_smart_parking.png b/app/src/main/res/drawable-mdpi/notify_smart_parking.png
new file mode 100644
index 0000000..f2a2626
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/notify_smart_parking.png differ
diff --git a/app/src/main/res/drawable-mdpi/settings_menu.png b/app/src/main/res/drawable-mdpi/settings_menu.png
new file mode 100644
index 0000000..67e38f7
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/settings_menu.png differ
diff --git a/app/src/main/res/drawable-mdpi/showtext.png b/app/src/main/res/drawable-mdpi/showtext.png
new file mode 100644
index 0000000..80dcdf6
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/showtext.png differ
diff --git a/app/src/main/res/drawable-mdpi/to_location.png b/app/src/main/res/drawable-mdpi/to_location.png
new file mode 100644
index 0000000..be741d6
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/to_location.png differ
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-xhdpi/about.png b/app/src/main/res/drawable-xhdpi/about.png
new file mode 100644
index 0000000..1833880
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/about.png differ
diff --git a/app/src/main/res/drawable-xhdpi/about_menu.png b/app/src/main/res/drawable-xhdpi/about_menu.png
new file mode 100644
index 0000000..36003f2
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/about_menu.png differ
diff --git a/app/src/main/res/drawable-xhdpi/changepass_menu.png b/app/src/main/res/drawable-xhdpi/changepass_menu.png
new file mode 100644
index 0000000..358aafb
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/changepass_menu.png differ
diff --git a/app/src/main/res/drawable-xhdpi/datepicker.png b/app/src/main/res/drawable-xhdpi/datepicker.png
new file mode 100644
index 0000000..7db54b7
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/datepicker.png differ
diff --git a/app/src/main/res/drawable-xhdpi/dontshowtext.png b/app/src/main/res/drawable-xhdpi/dontshowtext.png
new file mode 100644
index 0000000..d1c4fcb
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/dontshowtext.png differ
diff --git a/app/src/main/res/drawable-xhdpi/hamenuitem.png b/app/src/main/res/drawable-xhdpi/hamenuitem.png
new file mode 100644
index 0000000..5921bde
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/hamenuitem.png differ
diff --git a/app/src/main/res/drawable-xhdpi/homemenu.png b/app/src/main/res/drawable-xhdpi/homemenu.png
new file mode 100644
index 0000000..77ac564
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/homemenu.png differ
diff --git a/app/src/main/res/drawable-xhdpi/logout_menu.png b/app/src/main/res/drawable-xhdpi/logout_menu.png
new file mode 100644
index 0000000..f11c8b0
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/logout_menu.png differ
diff --git a/app/src/main/res/drawable-xhdpi/marker_icon.png b/app/src/main/res/drawable-xhdpi/marker_icon.png
new file mode 100644
index 0000000..2423931
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/marker_icon.png differ
diff --git a/app/src/main/res/drawable-xhdpi/notifications_smart_parking.png b/app/src/main/res/drawable-xhdpi/notifications_smart_parking.png
new file mode 100644
index 0000000..8c3d0e1
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/notifications_smart_parking.png differ
diff --git a/app/src/main/res/drawable-xhdpi/notify_smart_parking.png b/app/src/main/res/drawable-xhdpi/notify_smart_parking.png
new file mode 100644
index 0000000..4d5a45b
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/notify_smart_parking.png differ
diff --git a/app/src/main/res/drawable-xhdpi/settings_menu.png b/app/src/main/res/drawable-xhdpi/settings_menu.png
new file mode 100644
index 0000000..56de03c
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/settings_menu.png differ
diff --git a/app/src/main/res/drawable-xhdpi/showtext.png b/app/src/main/res/drawable-xhdpi/showtext.png
new file mode 100644
index 0000000..6e93d1d
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/showtext.png differ
diff --git a/app/src/main/res/drawable-xhdpi/to_location.png b/app/src/main/res/drawable-xhdpi/to_location.png
new file mode 100644
index 0000000..b0d51f3
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/to_location.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/about.png b/app/src/main/res/drawable-xxhdpi/about.png
new file mode 100644
index 0000000..c48b5ce
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/about.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/about_menu.png b/app/src/main/res/drawable-xxhdpi/about_menu.png
new file mode 100644
index 0000000..dd885f2
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/about_menu.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/changepass_menu.png b/app/src/main/res/drawable-xxhdpi/changepass_menu.png
new file mode 100644
index 0000000..4a41ad1
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/changepass_menu.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/datepicker.png b/app/src/main/res/drawable-xxhdpi/datepicker.png
new file mode 100644
index 0000000..f11282a
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/datepicker.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/dontshowtext.png b/app/src/main/res/drawable-xxhdpi/dontshowtext.png
new file mode 100644
index 0000000..c9889c4
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/dontshowtext.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/hamenuitem.png b/app/src/main/res/drawable-xxhdpi/hamenuitem.png
new file mode 100644
index 0000000..7b872cd
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/hamenuitem.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/homemenu.png b/app/src/main/res/drawable-xxhdpi/homemenu.png
new file mode 100644
index 0000000..7196157
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/homemenu.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/logout_menu.png b/app/src/main/res/drawable-xxhdpi/logout_menu.png
new file mode 100644
index 0000000..aca1f16
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/logout_menu.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/marker_icon.png b/app/src/main/res/drawable-xxhdpi/marker_icon.png
new file mode 100644
index 0000000..4f307d5
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/marker_icon.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/notifications_smart_parking.png b/app/src/main/res/drawable-xxhdpi/notifications_smart_parking.png
new file mode 100644
index 0000000..820ab51
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/notifications_smart_parking.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/notify_smart_parking.png b/app/src/main/res/drawable-xxhdpi/notify_smart_parking.png
new file mode 100644
index 0000000..ae910d1
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/notify_smart_parking.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/settings_menu.png b/app/src/main/res/drawable-xxhdpi/settings_menu.png
new file mode 100644
index 0000000..54528af
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/settings_menu.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/showtext.png b/app/src/main/res/drawable-xxhdpi/showtext.png
new file mode 100644
index 0000000..50caf0a
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/showtext.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/to_location.png b/app/src/main/res/drawable-xxhdpi/to_location.png
new file mode 100644
index 0000000..eb1187c
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/to_location.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/about_menu.png b/app/src/main/res/drawable-xxxhdpi/about_menu.png
new file mode 100644
index 0000000..abf528f
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/about_menu.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/changepass_menu.png b/app/src/main/res/drawable-xxxhdpi/changepass_menu.png
new file mode 100644
index 0000000..6b70127
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/changepass_menu.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/datepicker.png b/app/src/main/res/drawable-xxxhdpi/datepicker.png
new file mode 100644
index 0000000..82d0556
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/datepicker.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/dontshowtext.png b/app/src/main/res/drawable-xxxhdpi/dontshowtext.png
new file mode 100644
index 0000000..0bf4ca2
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/dontshowtext.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/hamenuitem.png b/app/src/main/res/drawable-xxxhdpi/hamenuitem.png
new file mode 100644
index 0000000..00f217b
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/hamenuitem.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/homemenu.png b/app/src/main/res/drawable-xxxhdpi/homemenu.png
new file mode 100644
index 0000000..335ee6b
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/homemenu.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/logout_menu.png b/app/src/main/res/drawable-xxxhdpi/logout_menu.png
new file mode 100644
index 0000000..a1efc55
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/logout_menu.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/marker_icon.png b/app/src/main/res/drawable-xxxhdpi/marker_icon.png
new file mode 100644
index 0000000..6dc8dad
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/marker_icon.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/notifications_smart_parking.png b/app/src/main/res/drawable-xxxhdpi/notifications_smart_parking.png
new file mode 100644
index 0000000..ed3affb
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/notifications_smart_parking.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/settings_menu.png b/app/src/main/res/drawable-xxxhdpi/settings_menu.png
new file mode 100644
index 0000000..e1115a6
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/settings_menu.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/showtext.png b/app/src/main/res/drawable-xxxhdpi/showtext.png
new file mode 100644
index 0000000..9363a5f
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/showtext.png differ
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/drawable/roundbutton.xml b/app/src/main/res/drawable/roundbutton.xml
new file mode 100644
index 0000000..fa17730
--- /dev/null
+++ b/app/src/main/res/drawable/roundbutton.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/about_layout.xml b/app/src/main/res/layout/about_layout.xml
new file mode 100644
index 0000000..4c91fa4
--- /dev/null
+++ b/app/src/main/res/layout/about_layout.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/change_password_layout.xml b/app/src/main/res/layout/change_password_layout.xml
new file mode 100644
index 0000000..a78ffe7
--- /dev/null
+++ b/app/src/main/res/layout/change_password_layout.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/eula_layout.xml b/app/src/main/res/layout/eula_layout.xml
new file mode 100644
index 0000000..56cd4df
--- /dev/null
+++ b/app/src/main/res/layout/eula_layout.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/home_layout.xml b/app/src/main/res/layout/home_layout.xml
new file mode 100644
index 0000000..fa21cfc
--- /dev/null
+++ b/app/src/main/res/layout/home_layout.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/init_layout.xml b/app/src/main/res/layout/init_layout.xml
new file mode 100644
index 0000000..2aa35fc
--- /dev/null
+++ b/app/src/main/res/layout/init_layout.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/login_layout.xml b/app/src/main/res/layout/login_layout.xml
new file mode 100644
index 0000000..7a44671
--- /dev/null
+++ b/app/src/main/res/layout/login_layout.xml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/map_layout.xml b/app/src/main/res/layout/map_layout.xml
new file mode 100644
index 0000000..0d73438
--- /dev/null
+++ b/app/src/main/res/layout/map_layout.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/registry_layout.xml b/app/src/main/res/layout/registry_layout.xml
new file mode 100644
index 0000000..fbfe98f
--- /dev/null
+++ b/app/src/main/res/layout/registry_layout.xml
@@ -0,0 +1,207 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/reset_password_layout.xml b/app/src/main/res/layout/reset_password_layout.xml
new file mode 100644
index 0000000..5304320
--- /dev/null
+++ b/app/src/main/res/layout/reset_password_layout.xml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml
new file mode 100644
index 0000000..488ac2a
--- /dev/null
+++ b/app/src/main/res/menu/menu_main.xml
@@ -0,0 +1,16 @@
+
+
\ 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-anydpi-v26/smart_parking_logo.xml b/app/src/main/res/mipmap-anydpi-v26/smart_parking_logo.xml
new file mode 100644
index 0000000..67820c5
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/smart_parking_logo.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/smart_parking_logo_round.xml b/app/src/main/res/mipmap-anydpi-v26/smart_parking_logo_round.xml
new file mode 100644
index 0000000..67820c5
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/smart_parking_logo_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/smartparking_logo.xml b/app/src/main/res/mipmap-anydpi-v26/smartparking_logo.xml
new file mode 100644
index 0000000..036d09b
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/smartparking_logo.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/smartparking_logo_round.xml b/app/src/main/res/mipmap-anydpi-v26/smartparking_logo_round.xml
new file mode 100644
index 0000000..036d09b
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/smartparking_logo_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_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..00ecba6
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dffca36
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-hdpi/smart_parking.png b/app/src/main/res/mipmap-hdpi/smart_parking.png
new file mode 100644
index 0000000..0bdd3bb
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/smart_parking.png differ
diff --git a/app/src/main/res/mipmap-hdpi/smart_parking_logo.png b/app/src/main/res/mipmap-hdpi/smart_parking_logo.png
new file mode 100644
index 0000000..607e30f
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/smart_parking_logo.png differ
diff --git a/app/src/main/res/mipmap-hdpi/smart_parking_logo_round.png b/app/src/main/res/mipmap-hdpi/smart_parking_logo_round.png
new file mode 100644
index 0000000..4446c26
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/smart_parking_logo_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_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..8fecd74
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..dae5e08
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/smart_parking.png b/app/src/main/res/mipmap-mdpi/smart_parking.png
new file mode 100644
index 0000000..6f4c7c4
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/smart_parking.png differ
diff --git a/app/src/main/res/mipmap-mdpi/smart_parking_logo.png b/app/src/main/res/mipmap-mdpi/smart_parking_logo.png
new file mode 100644
index 0000000..c2e60c6
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/smart_parking_logo.png differ
diff --git a/app/src/main/res/mipmap-mdpi/smart_parking_logo_round.png b/app/src/main/res/mipmap-mdpi/smart_parking_logo_round.png
new file mode 100644
index 0000000..2306c18
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/smart_parking_logo_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_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..3fbe1f7
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..14ed0af
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/smart_parking.png b/app/src/main/res/mipmap-xhdpi/smart_parking.png
new file mode 100644
index 0000000..77061d6
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/smart_parking.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/smart_parking_logo.png b/app/src/main/res/mipmap-xhdpi/smart_parking_logo.png
new file mode 100644
index 0000000..155ec58
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/smart_parking_logo.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/smart_parking_logo_round.png b/app/src/main/res/mipmap-xhdpi/smart_parking_logo_round.png
new file mode 100644
index 0000000..0ce54f1
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/smart_parking_logo_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_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..c412e32
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..d8ae031
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/smart_parking.png b/app/src/main/res/mipmap-xxhdpi/smart_parking.png
new file mode 100644
index 0000000..916dd3c
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/smart_parking.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/smart_parking_logo.png b/app/src/main/res/mipmap-xxhdpi/smart_parking_logo.png
new file mode 100644
index 0000000..5ae40e6
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/smart_parking_logo.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/smart_parking_logo_round.png b/app/src/main/res/mipmap-xxhdpi/smart_parking_logo_round.png
new file mode 100644
index 0000000..c7aeae9
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/smart_parking_logo_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_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..6765a94
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..beed3cd
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/smart_parking.png b/app/src/main/res/mipmap-xxxhdpi/smart_parking.png
new file mode 100644
index 0000000..68c83e9
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/smart_parking.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/smart_parking_logo.png b/app/src/main/res/mipmap-xxxhdpi/smart_parking_logo.png
new file mode 100644
index 0000000..38d9187
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/smart_parking_logo.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/smart_parking_logo_round.png b/app/src/main/res/mipmap-xxxhdpi/smart_parking_logo_round.png
new file mode 100644
index 0000000..962b461
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/smart_parking_logo_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..fc36b56
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,20 @@
+
+
+ #008577
+ #00574B
+ #d81b60
+ #3d5afe
+ #3F51B5
+ #303F9F
+ #C5CAE9
+ #FF5252
+ #212121
+ #757575
+ #FFFFFF
+ #BDBDBD
+ #FFFFFF
+ #d3d3d3
+ #e53935
+ #b71c1c
+
+
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..2daa301
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,11 @@
+
+
+ 16dp
+ 16dp
+ 32dp
+ 10dp
+ 10dp
+ 240dp
+ 235dp
+ 0.5dp
+
\ No newline at end of file
diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..cfa9be0
--- /dev/null
+++ b/app/src/main/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #FFFFFF
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..f3a5079
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,105 @@
+
+ SmartParking
+ Sin cuenta? Regístrate!
+ Login
+ Tengo cuenta
+ Enviar
+ Welcome
+ Credenciales
+ Registrarse!
+ v1.0 Beta
+
+ Esta aplicación es uno de los casos de estudio del proyecto SmartTraffic que es cofinanciado
+ por el CONACYT a través del programa PROCIENCIA- FEEI, FONACIDE.
+ Contraseña actual
+ Nueva contraseña
+ Repita nueva contraseña
+ Guardar
+ Atras
+ Ud. no aceptó aún los términos de uso de la aplicación.
+ Por favor lea hasta el final y marque la casilla de aceptación si está de acuerdo
+ con las condiciones
+
+ http://example.com/
+
+
+ Aviso Legal de Responsabilidades
+ I Accept the terms and Conditions
+ El uso de esta aplicación es completamente voluntario por parte del usuario.
+ Los proveedores de esta aplicación se comprometen en usar los datos recolectados de los
+ usuarios de forma responsable y de manera privada.
+
+ Las contraseñas no coinciden!
+ Acepto
+ Cancelar
+ Si
+ Enviar
+ SmartParking
+ Sin conexion a Internet !
+ credenciales
+ username
+ password
+ age
+ sexo
+ identificador
+ ProfileSharedPreferencesPrivateData
+ Acepto los términos y condiciones.
+ Has olvidado la contraseña?
+
+ Name of user profile
+ Ajustes
+ Cambio de contraseña
+ Home
+ Otros...
+ Cerrar sesión
+ Acerca de SmartParking
+ f1
+ f2
+ f3
+
+ Open navigation drawer
+ Close navigation drawer
+ Cancel
+ Está seguro de querer cerrar sesión?
+ Salir de SmartParking?
+ Geofence: Tipo de transición invalida
+ Transición SmartParking
+ Entrada a estacionamiento
+ Salida de estacionamiento
+ Transición desconocida
+ Geofence: Error desconocido
+ Geofence: No disponible
+ Muchos predios registrados
+ Muchos intents pendientes
+ Geofences eliminadas
+ Geofences agregadas
+ Se necesita permiso de ubicación para la funcionar
+ Permisos insuficientes
+ Configuraciones
+ Se denegó el permiso, pero es necesario para el núcleo funcionalidad
+ Geofence: transición de permanencia
+ Empezar
+ Eliminar actualizaciones de ubicación
+ Ubicacion actualizada
+ En vehículo
+ Bicicleta
+ A pie
+ Corriendo
+ Quieto
+ Inclinación
+ Caminando
+ Actividad no identificada
+ Actualizaciones de actividad habilitadas
+ Actualizaciones de actividades NO habilitadas
+ Actualizaciones de actividades eliminadas
+ Actualizaciones de actividades NO eliminadas
+ ¿Estás estacionando el vehículo?
+ ¿Estás desocupando un lugar?
+ SmartParking Channel
+ SmartParking Notifications
+ Ir a la aplicación
+ ¿Seguro que quieres cerrar sesión?
+ Has estacionado!
+ Actividad no procesada!
+ Has liberado un lugar!
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..e24fe39
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml
new file mode 100644
index 0000000..885cc46
--- /dev/null
+++ b/app/src/main/res/xml/network_security_config.xml
@@ -0,0 +1,10 @@
+
+
+
+ 10.50.225.75
+ 192.168.100.5
+ 192.168.100.49
+ smarttraffic.com.py
+
+
+
\ No newline at end of file
diff --git a/app/src/main/smart_parking-web.png b/app/src/main/smart_parking-web.png
new file mode 100644
index 0000000..17d6989
Binary files /dev/null and b/app/src/main/smart_parking-web.png differ
diff --git a/app/src/main/smart_parking_logo-web.png b/app/src/main/smart_parking_logo-web.png
new file mode 100644
index 0000000..b09bc2c
Binary files /dev/null and b/app/src/main/smart_parking_logo-web.png differ
diff --git a/app/src/main/smartparkingLogo-web.png b/app/src/main/smartparkingLogo-web.png
new file mode 100644
index 0000000..b33c62a
Binary files /dev/null and b/app/src/main/smartparkingLogo-web.png differ
diff --git a/app/src/main/toast_smartparking-web.png b/app/src/main/toast_smartparking-web.png
new file mode 100644
index 0000000..0c9bb3b
Binary files /dev/null and b/app/src/main/toast_smartparking-web.png differ
diff --git a/app/src/test/java/smarttraffic/smartparking/ExampleUnitTest.java b/app/src/test/java/smarttraffic/smartparking/ExampleUnitTest.java
new file mode 100644
index 0000000..3d8ad47
--- /dev/null
+++ b/app/src/test/java/smarttraffic/smartparking/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package smarttraffic.smartparking;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..606827d
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,25 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.4.1'
+ // 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..82618ce
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,15 @@
+# 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
+
+
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..a24d5a4
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Jul 03 18:45:32 PYT 2019
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
diff --git a/gradlew b/gradlew
new file mode 100644
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..c2bd6e0
--- /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=C\:\\Users\\Joaquin\\AppData\\Local\\Android\\Sdk
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/smartparking.iml b/smartparking.iml
new file mode 100644
index 0000000..d054364
--- /dev/null
+++ b/smartparking.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file