diff --git a/app/build.gradle b/app/build.gradle
index 8bcfb89..d97dbd5 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -40,8 +40,10 @@ dependencies {
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation 'com.google.android.gms:play-services-location:17.1.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
testImplementation 'junit:junit:4.13.1'
+// implementation "com.android.support:support-compat:28.0.0"
// okhttp
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1d0c446..b2cdc54 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -25,6 +25,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/a1/nextlocation/MainActivity.java b/app/src/main/java/com/a1/nextlocation/MainActivity.java
index 0879161..0c39c19 100644
--- a/app/src/main/java/com/a1/nextlocation/MainActivity.java
+++ b/app/src/main/java/com/a1/nextlocation/MainActivity.java
@@ -1,6 +1,7 @@
package com.a1.nextlocation;
import android.app.Activity;
+import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
@@ -12,6 +13,7 @@ import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
+import com.a1.nextlocation.data.Data;
import com.a1.nextlocation.data.Route;
import com.a1.nextlocation.fragments.HelpPopup;
import com.a1.nextlocation.fragments.HomeFragment;
@@ -66,6 +68,8 @@ public class MainActivity extends AppCompatActivity implements Refreshable {
CouponListManager.INSTANCE.load();
RouteListManager.INSTANCE.setContext(this);
RouteListManager.INSTANCE.load();
+ Data.INSTANCE.setContext(this);
+ Data.INSTANCE.load();
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_layout, homeFragment).commit();
diff --git a/app/src/main/java/com/a1/nextlocation/data/Data.java b/app/src/main/java/com/a1/nextlocation/data/Data.java
index 6bc4bbe..77b14b2 100644
--- a/app/src/main/java/com/a1/nextlocation/data/Data.java
+++ b/app/src/main/java/com/a1/nextlocation/data/Data.java
@@ -1,5 +1,12 @@
package com.a1.nextlocation.data;
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+import java.lang.reflect.Type;
import java.util.ArrayList;
/**
@@ -11,6 +18,26 @@ public enum Data {
private int locationsVisited = 0;
private long totalTime = 0;
private double zoom = 0;
+ private SharedPreferences.Editor editor;
+ private Context context;
+ private LocationProximityListener locationProximityListener;
+
+ public void setContext(Context context) {
+ this.context = context;
+ }
+
+ public void setEditor(SharedPreferences.Editor editor) {
+ this.editor = editor;
+ }
+
+
+ public LocationProximityListener getLocationProximityListener() {
+ return locationProximityListener;
+ }
+
+ public void setLocationProximityListener(LocationProximityListener locationProximityListener) {
+ this.locationProximityListener = locationProximityListener;
+ }
private android.location.Location location;
public double getZoom() {
@@ -21,10 +48,13 @@ public enum Data {
this.zoom = zoom;
}
- private final ArrayList visitedNames = new ArrayList<>();
+ private ArrayList visitedNames = new ArrayList<>();
public void addDistance(double d) {
distanceTraveled += d;
+
+ editor.putString("distanceTraveled", String.valueOf(distanceTraveled));
+ editor.apply();
}
public long getTotalTime() {
@@ -35,7 +65,6 @@ public enum Data {
totalTime += time;
}
-
public double getDistanceTraveled() {
return distanceTraveled;
}
@@ -44,6 +73,9 @@ public enum Data {
if (!visitedNames.contains(location.getName())) {
locationsVisited++;
visitedNames.add(location.getName());
+ saveVisitedNamesList();
+ editor.putInt("locationsVisited", locationsVisited);
+ editor.apply();
}
}
@@ -51,6 +83,31 @@ public enum Data {
return locationsVisited;
}
+ @FunctionalInterface
+ public interface LocationProximityListener {
+ void onLocationVisited(Location location);
+ }
+
+ public void saveVisitedNamesList(){
+ Gson gson = new Gson();
+ String json = gson.toJson(visitedNames);
+ editor.putString("visitedNames", json);
+ editor.apply();
+ }
+
+ public ArrayList loadAndGetVisitedNamesList(){
+ String json = context.getSharedPreferences("Data", Context.MODE_PRIVATE).getString("visitedNames", "[]");
+ Type type = new TypeToken>() {}.getType();
+ visitedNames = new Gson().fromJson(json, type);
+ return visitedNames;
+ }
+
+ public void load(){
+ SharedPreferences prefs = context.getSharedPreferences("Data", Context.MODE_PRIVATE);
+ this.editor = prefs.edit();
+ Data.INSTANCE.addDistance(Double.parseDouble(prefs.getString("distanceTraveled", "0")));
+ this.locationsVisited = loadAndGetVisitedNamesList().size();
+ }
public android.location.Location getLocation() {
return location;
diff --git a/app/src/main/java/com/a1/nextlocation/data/Location.java b/app/src/main/java/com/a1/nextlocation/data/Location.java
index 86785cc..ae99308 100644
--- a/app/src/main/java/com/a1/nextlocation/data/Location.java
+++ b/app/src/main/java/com/a1/nextlocation/data/Location.java
@@ -25,6 +25,8 @@ public class Location implements Parcelable {
private String imageUrl;
private String iconUrl;
+ private boolean visited;
+
public Location(@NotNull String name, String coordinates, String description, @Nullable String imageUrl) {
this.name = name;
this.coordinates = coordinates;
@@ -171,4 +173,12 @@ public class Location implements Parcelable {
parcel.writeString(description);
parcel.writeString(imageUrl);
}
+
+ public boolean isVisited() {
+ return visited;
+ }
+
+ public void setVisited(boolean visited) {
+ this.visited = visited;
+ }
}
diff --git a/app/src/main/java/com/a1/nextlocation/data/RouteHandler.java b/app/src/main/java/com/a1/nextlocation/data/RouteHandler.java
index a6959e7..331d28e 100644
--- a/app/src/main/java/com/a1/nextlocation/data/RouteHandler.java
+++ b/app/src/main/java/com/a1/nextlocation/data/RouteHandler.java
@@ -13,6 +13,15 @@ public enum RouteHandler {
private int stepCount = 0;
private RouteFinishedListener routeFinishedListener;
private long startedTime;
+ private double currentRouteDuration;
+
+ public void setCurrentRouteDuration(double currentRouteDuration) {
+ this.currentRouteDuration = currentRouteDuration;
+ }
+
+ public double getCurrentRouteDuration() {
+ return currentRouteDuration;
+ }
private Polyline currentRouteLine;
@@ -20,6 +29,7 @@ public enum RouteHandler {
this.currentRouteLine = currentRouteLine;
}
+
public Polyline getCurrentRouteLine() {
return currentRouteLine;
}
diff --git a/app/src/main/java/com/a1/nextlocation/fragments/HomeFragment.java b/app/src/main/java/com/a1/nextlocation/fragments/HomeFragment.java
index 07021e4..082b306 100644
--- a/app/src/main/java/com/a1/nextlocation/fragments/HomeFragment.java
+++ b/app/src/main/java/com/a1/nextlocation/fragments/HomeFragment.java
@@ -2,7 +2,10 @@ package com.a1.nextlocation.fragments;
import android.Manifest;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
import android.content.Context;
+import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.location.Location;
@@ -19,6 +22,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
+import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
@@ -26,6 +30,7 @@ import androidx.fragment.app.FragmentActivity;
import com.a1.nextlocation.R;
import com.a1.nextlocation.data.Data;
import com.a1.nextlocation.data.RouteHandler;
+import com.a1.nextlocation.geofencing.GeofenceInitalizer;
import com.a1.nextlocation.json.DirectionsResult;
import com.a1.nextlocation.network.ApiHandler;
import com.a1.nextlocation.recyclerview.LocationListManager;
@@ -60,6 +65,8 @@ public class HomeFragment extends Fragment implements LocationListener {
private int color;
private Location currentLocation;
private Overlay allLocationsOverlay;
+ private GeofenceInitalizer initializer;
+ private final static String CHANNEL_ID = "next_location01";
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -71,6 +78,7 @@ public class HomeFragment extends Fragment implements LocationListener {
Manifest.permission.WRITE_EXTERNAL_STORAGE);
color = requireContext().getColor(R.color.red);
+ Data.INSTANCE.setLocationProximityListener(this::onLocationVisited);
}
@Override
@@ -132,6 +140,7 @@ public class HomeFragment extends Fragment implements LocationListener {
roadOverlay.setColor(color);
// pass the line to the route handler
+ RouteHandler.INSTANCE.setCurrentRouteDuration(directionsResult.getDuration());
RouteHandler.INSTANCE.setCurrentRouteLine(roadOverlay);
Log.d(TAG, "onDirectionsAvailable: successfully added road!");
@@ -141,6 +150,7 @@ public class HomeFragment extends Fragment implements LocationListener {
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
+ initializer = new GeofenceInitalizer(requireContext(),requireActivity());
initMap(view);
}
@@ -217,6 +227,8 @@ public class HomeFragment extends Fragment implements LocationListener {
}
+
+
/**
* displays the route that is currently being followed as a red line
*/
@@ -245,11 +257,12 @@ public class HomeFragment extends Fragment implements LocationListener {
private void addLocations() {
// get the locations of the current route or all locations
List locations = RouteHandler.INSTANCE.isFollowingRoute() ? RouteHandler.INSTANCE.getCurrentRoute().getLocations() : LocationListManager.INSTANCE.getLocationList();
+ initializer.removeGeoFences();
final ArrayList items = new ArrayList<>(locations.size());
// marker icon
Drawable marker = ContextCompat.getDrawable(requireContext(), R.drawable.ic_baseline_location_on_24);
marker.setAlpha(255);
- marker.setTint(getResources().getColor(R.color.primaryColour));
+ marker.setTint(getResources().getColor(R.color.secondaryColour));
// add all locations to the overlay itemss
for (com.a1.nextlocation.data.Location location : locations) {
@@ -299,6 +312,19 @@ public class HomeFragment extends Fragment implements LocationListener {
mapView.getOverlays().add(allLocationsOverlay);
Log.d(TAG, "addLocations: successfully added locations");
+ addGeofences(locations);
+
+ }
+
+ /**
+ * adds the geofences for the currently active locations
+ * @param locations the locations to add geofences for
+ */
+ private void addGeofences(List locations) {
+
+ Log.d(TAG, "addGeofences: adding geofences!");
+
+ initializer.init(locations);
}
/**
@@ -336,34 +362,62 @@ public class HomeFragment extends Fragment implements LocationListener {
if (currentLocation != null) {
double distance = currentLocation.distanceTo(location); // in meters
// can't walk 100 meters in a few seconds
- if (distance < 100)
+ if (distance < 100) {
Data.INSTANCE.addDistance(distance);
Data.INSTANCE.setLocation(location);
- }
- currentLocation = location;
-
-
- //new thread because we don't want the main thread to hang, this method gets called a lot
- Thread t = new Thread(() -> {
- com.a1.nextlocation.data.Location last = null;
- if (RouteHandler.INSTANCE.isFollowingRoute()) {
- List locs = RouteHandler.INSTANCE.getCurrentRoute().getLocations();
- last = locs.get(locs.size() - 1);
}
+ currentLocation = location;
- for (com.a1.nextlocation.data.Location l : LocationListManager.INSTANCE.getLocationList()) {
- // mark the location visited if we are less than 20 meters away
- if (com.a1.nextlocation.data.Location.getDistance(currentLocation.getLatitude(), currentLocation.getLongitude(), l.getLat(), l.getLong()) < 20) {
- Data.INSTANCE.visitLocation(l);
- if (l.equals(last)) stopRoute();
+
+ //new thread because we don't want the main thread to hang, this method gets called a lot
+ Thread t = new Thread(() -> {
+ com.a1.nextlocation.data.Location last = null;
+ if (RouteHandler.INSTANCE.isFollowingRoute()) {
+ List locs = RouteHandler.INSTANCE.getCurrentRoute().getLocations();
+ last = locs.get(locs.size() - 1);
}
- }
- Data.INSTANCE.setZoom(mapView.getZoomLevelDouble());
- });
+ for (com.a1.nextlocation.data.Location l : LocationListManager.INSTANCE.getLocationList()) {
+ // mark the location visited if we are less than 20 meters away
+ if (com.a1.nextlocation.data.Location.getDistance(currentLocation.getLatitude(), currentLocation.getLongitude(), l.getLat(), l.getLong()) < 20) {
+ Data.INSTANCE.visitLocation(l);
+ if (l.equals(last)) stopRoute();
+ }
+ }
- t.start();
+ Data.INSTANCE.setZoom(mapView.getZoomLevelDouble());
+ });
+ t.start();
+
+ }
+ }
+
+ public void onLocationVisited(com.a1.nextlocation.data.Location location) {
+ Data.INSTANCE.visitLocation(location);
+ showNotification(location);
+
+ }
+
+ private void showNotification(com.a1.nextlocation.data.Location location) {
+
+ NotificationManager mNotificationManager = (NotificationManager) requireActivity().getSystemService(Context.NOTIFICATION_SERVICE);
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
+ int importance = NotificationManager.IMPORTANCE_LOW;
+ NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID, "next_location", importance);
+ notificationChannel.enableLights(true);
+ notificationChannel.enableVibration(true);
+ notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
+ mNotificationManager.createNotificationChannel(notificationChannel);
+ }
+
+ NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(requireContext(),CHANNEL_ID)
+ .setSmallIcon(R.drawable.ic_launcher_foreground)
+ .setContentTitle(getString(R.string.notification_title))
+ .setContentText(getString(R.string.notification_text,location.getName()))
+ .setAutoCancel(true);
+
+ mNotificationManager.notify(0,mBuilder.build());
}
// empty override methods for the LocationListener
diff --git a/app/src/main/java/com/a1/nextlocation/fragments/StatisticFragment.java b/app/src/main/java/com/a1/nextlocation/fragments/StatisticFragment.java
index e8ab15f..854213e 100644
--- a/app/src/main/java/com/a1/nextlocation/fragments/StatisticFragment.java
+++ b/app/src/main/java/com/a1/nextlocation/fragments/StatisticFragment.java
@@ -79,7 +79,7 @@ public class StatisticFragment extends Fragment {
private void initializeDistanceTextView(View view){
distance = view.findViewById(R.id.statistics_km);
- double dist = Data.INSTANCE.getDistanceTraveled()/1000;
+ double dist = Double.parseDouble(getContext().getSharedPreferences("Data", Context.MODE_PRIVATE).getString("distanceTraveled", "0")) /1000;
if (getContext().getSharedPreferences("Settings", Context.MODE_PRIVATE).getBoolean("imperialSwitch", false))
distance.setText("" + String.format("%.1f",dist * 0.621371) + " mi");
else
diff --git a/app/src/main/java/com/a1/nextlocation/geofencing/GeoFenceBroadcastReceiver.java b/app/src/main/java/com/a1/nextlocation/geofencing/GeoFenceBroadcastReceiver.java
new file mode 100644
index 0000000..eff3ec2
--- /dev/null
+++ b/app/src/main/java/com/a1/nextlocation/geofencing/GeoFenceBroadcastReceiver.java
@@ -0,0 +1,61 @@
+package com.a1.nextlocation.geofencing;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import com.a1.nextlocation.data.Data;
+import com.a1.nextlocation.data.Location;
+import com.a1.nextlocation.recyclerview.LocationListManager;
+import com.google.android.gms.location.Geofence;
+import com.google.android.gms.location.GeofenceStatusCodes;
+import com.google.android.gms.location.GeofencingEvent;
+
+import java.util.List;
+
+/**
+ * broadcast receiver for geofence events
+ */
+public class GeoFenceBroadcastReceiver extends BroadcastReceiver {
+ private final String TAG = GeoFenceBroadcastReceiver.class.getCanonicalName();
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
+ Log.i(TAG, "onReceive: RECEIVED GEOFENCE STUFF");
+
+ if (geofencingEvent.hasError()) {
+ String errorMessage = GeofenceStatusCodes
+ .getStatusCodeString(geofencingEvent.getErrorCode());
+ Log.e(TAG, errorMessage);
+ return;
+ }
+
+ // Get the transition type.
+ int geofenceTransition = geofencingEvent.getGeofenceTransition();
+
+ switch (geofenceTransition) {
+ case Geofence.GEOFENCE_TRANSITION_ENTER:
+ List geofenceList = geofencingEvent.getTriggeringGeofences();
+ // loop through list of geofences
+ for (Geofence geofence : geofenceList) {
+ for (Location l : LocationListManager.INSTANCE.getLocationList()) {
+ if (geofence.getRequestId().equals(l.getName())) {
+ l.setVisited(true);
+ // let the homefragment know that we are close to a location
+ Data.INSTANCE.getLocationProximityListener().onLocationVisited(l);
+ Log.d(TAG, "onReceive: VISITED LOCATION " + l.getName());
+ break;
+ }
+ }
+ }
+
+ break;
+ case Geofence.GEOFENCE_TRANSITION_EXIT:
+ Log.d(TAG, "onReceive: exiting geofence...");
+ break;
+ }
+ }
+}
diff --git a/app/src/main/java/com/a1/nextlocation/geofencing/GeoFencingHelper.java b/app/src/main/java/com/a1/nextlocation/geofencing/GeoFencingHelper.java
new file mode 100644
index 0000000..01f6335
--- /dev/null
+++ b/app/src/main/java/com/a1/nextlocation/geofencing/GeoFencingHelper.java
@@ -0,0 +1,51 @@
+package com.a1.nextlocation.geofencing;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.provider.SyncStateContract;
+
+import com.google.android.gms.location.Geofence;
+import com.google.android.gms.location.GeofencingRequest;
+
+import org.osmdroid.util.GeoPoint;
+
+public class GeoFencingHelper extends ContextWrapper {
+ private PendingIntent pendingIntent;
+
+ public GeoFencingHelper(Context base) {
+ super(base);
+ }
+
+ public GeofencingRequest getGeoFencingRequest(Geofence geofence) {
+ GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
+ builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
+ builder.addGeofence(geofence);
+ return builder.build();
+
+ }
+
+ public Geofence getGeofence(String ID, GeoPoint point, float radius) {
+
+ return new Geofence.Builder()
+ .setCircularRegion(point.getLatitude(), point.getLongitude(), radius)
+ .setRequestId(ID)
+ .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
+ Geofence.GEOFENCE_TRANSITION_EXIT)
+ .setLoiteringDelay(5000)
+ .setExpirationDuration(Geofence.NEVER_EXPIRE)
+ .build();
+ }
+
+ public PendingIntent getPendingIntent() {
+ if (pendingIntent != null) {
+ return pendingIntent;
+ }
+
+ Intent intent = new Intent(this, GeoFenceBroadcastReceiver.class);
+ pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ return pendingIntent;
+ }
+}
diff --git a/app/src/main/java/com/a1/nextlocation/geofencing/GeofenceInitalizer.java b/app/src/main/java/com/a1/nextlocation/geofencing/GeofenceInitalizer.java
new file mode 100644
index 0000000..7a1af31
--- /dev/null
+++ b/app/src/main/java/com/a1/nextlocation/geofencing/GeofenceInitalizer.java
@@ -0,0 +1,109 @@
+package com.a1.nextlocation.geofencing;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import com.a1.nextlocation.data.Data;
+import com.a1.nextlocation.data.Location;
+import com.a1.nextlocation.recyclerview.LocationListManager;
+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.LocationServices;
+import com.google.android.gms.tasks.OnFailureListener;
+import com.google.android.gms.tasks.OnSuccessListener;
+
+import org.osmdroid.util.GeoPoint;
+
+import java.util.List;
+
+import static android.content.ContentValues.TAG;
+
+public class GeofenceInitalizer {
+ private final Activity activity;
+ private GeofencingClient geofencingClient;
+ private GeoFencingHelper geoFencingHelper;
+ private final Context context;
+ private final String TAG = GeofenceInitalizer.class.getCanonicalName();
+ private List locations;
+ private int BACKGROUND_LOCATION_ACCESS_REQUEST_CODE = 10002;
+
+ public GeofenceInitalizer(Context context, Activity activity) {
+ this.context = context;
+ this.activity = activity;
+ }
+
+ public void init(List locations) {
+ if (!checkFineLocationPermission()) return;
+
+ geofencingClient = LocationServices.getGeofencingClient(context);
+ geoFencingHelper = new GeoFencingHelper(context);
+ this.locations = locations;
+ if (Build.VERSION.SDK_INT >= 29) {
+ //If API is higher then 29 we need background permission
+
+ if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED) {
+ addFences();
+ } else {
+ //Permission is not granted!! Need to request it..
+ if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_BACKGROUND_LOCATION)) {
+ //We show a dialog and ask for permission
+ ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, BACKGROUND_LOCATION_ACCESS_REQUEST_CODE);
+ } else {
+ ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, BACKGROUND_LOCATION_ACCESS_REQUEST_CODE);
+
+ }
+ }
+ } else {
+ addFences();
+ }
+ }
+
+ private void addFences() {
+ for (Location location : locations) {
+ GeoPoint t = new GeoPoint(location.getLat(), location.getLong());
+ addGeofence(t, location.getName());
+ }
+ }
+
+ public void removeGeoFences() {
+ geofencingClient = LocationServices.getGeofencingClient(context);
+ geoFencingHelper = new GeoFencingHelper(context);
+
+ PendingIntent pendingIntent = geoFencingHelper.getPendingIntent();
+
+ geofencingClient.removeGeofences(pendingIntent)
+ .addOnSuccessListener(aVoid -> Log.d(TAG, "Geofence is removed... "))
+ .addOnFailureListener(e -> Log.d(TAG, e.getLocalizedMessage()));
+ if (this.locations != null) this.locations.clear();
+
+ }
+
+ private void addGeofence(GeoPoint p, String name) {
+ if (!checkFineLocationPermission()) return;
+
+ Geofence geofence = geoFencingHelper.getGeofence(name, p, 45);
+ GeofencingRequest geofencingRequest = geoFencingHelper.getGeoFencingRequest(geofence);
+ PendingIntent pendingIntent = geoFencingHelper.getPendingIntent();
+
+ geofencingClient.addGeofences(geofencingRequest, pendingIntent).addOnSuccessListener(v -> {
+ Log.i(TAG, "addGeofence: added geofence");
+ }).addOnFailureListener(v -> {
+ Log.e(TAG, "addGeofence: failure adding geofence " + v.getMessage());
+ });
+ Log.i(TAG, "addGeofence: added geofence to client");
+ }
+
+ private boolean checkFineLocationPermission() {
+ return ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
+ }
+}
diff --git a/app/src/main/res/drawable-anydpi/ic_stop_icon.xml b/app/src/main/res/drawable-anydpi/ic_stop_icon.xml
index addfeb0..8be9df4 100644
--- a/app/src/main/res/drawable-anydpi/ic_stop_icon.xml
+++ b/app/src/main/res/drawable-anydpi/ic_stop_icon.xml
@@ -6,7 +6,7 @@
android:tint="#333333"
android:alpha="0.6">
diff --git a/app/src/main/res/drawable/ic_baseline_location_on_24.xml b/app/src/main/res/drawable/ic_baseline_location_on_24.xml
index 94b2681..3874b85 100644
--- a/app/src/main/res/drawable/ic_baseline_location_on_24.xml
+++ b/app/src/main/res/drawable/ic_baseline_location_on_24.xml
@@ -5,6 +5,6 @@
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index cc1d88c..2e192cb 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -22,9 +22,9 @@
android:id="@+id/navigation_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:background="@color/white"
+ android:background="@color/primaryColour"
app:itemIconTint="@color/secondaryColour"
- app:itemTextColor="@color/primaryColour"
+ app:itemTextColor="@color/secondaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/layout/coupon_item.xml b/app/src/main/res/layout/coupon_item.xml
index 76cff35..9a9a437 100644
--- a/app/src/main/res/layout/coupon_item.xml
+++ b/app/src/main/res/layout/coupon_item.xml
@@ -13,7 +13,7 @@
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
- android:background="@color/secondaryColour"
+ android:background="@color/primaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.4"
@@ -26,7 +26,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text=""
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index c97c363..d47b45f 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -24,7 +24,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"
- android:backgroundTint="@color/secondaryColour"
+ android:backgroundTint="@color/primaryColour"
android:src="@drawable/ic_baseline_outlined_flag_24"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -37,7 +37,7 @@
android:layout_marginEnd="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/location_list_button"
- android:backgroundTint="@color/secondaryColour"
+ android:backgroundTint="@color/primaryColour"
android:src="@drawable/ic_stop_icon"/>
diff --git a/app/src/main/res/layout/fragment_location_detail.xml b/app/src/main/res/layout/fragment_location_detail.xml
index 3a68b38..5539f91 100644
--- a/app/src/main/res/layout/fragment_location_detail.xml
+++ b/app/src/main/res/layout/fragment_location_detail.xml
@@ -14,7 +14,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text=""
- android:textColor="@color/white"
+ android:textColor="@color/secondaryColour"
android:textSize="30sp"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
@@ -35,7 +35,7 @@
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="20dp"
- android:background="@color/secondaryColour"
+ android:background="@color/primaryColour"
android:text=""
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -45,8 +45,8 @@
android:id="@+id/detail_location_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="@color/secondaryColour"
android:layout_marginHorizontal="20dp"
+ android:background="@color/primaryColour"
android:text=""
/>
diff --git a/app/src/main/res/layout/fragment_route.xml b/app/src/main/res/layout/fragment_route.xml
index 3904b49..e445af1 100644
--- a/app/src/main/res/layout/fragment_route.xml
+++ b/app/src/main/res/layout/fragment_route.xml
@@ -19,6 +19,7 @@
+ app:layout_constraintBottom_toTopOf="@id/total_distance">
+
@@ -48,7 +48,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/language"
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk"
@@ -59,7 +59,7 @@
android:id="@+id/Balk"
android:layout_width="1dp"
android:layout_height="match_parent"
- android:background="@color/black"
+ android:background="@color/secondaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -84,7 +84,7 @@
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
- android:background="@color/secondaryColour"
+ android:background="@color/primaryColour"
app:layout_constraintBottom_toTopOf="@id/Box3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -96,7 +96,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/imperial_system"
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk2"
@@ -107,7 +107,7 @@
android:id="@+id/Balk2"
android:layout_width="1dp"
android:layout_height="match_parent"
- android:background="@color/black"
+ android:background="@color/buttonColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -131,7 +131,7 @@
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
- android:background="@color/secondaryColour"
+ android:background="@color/primaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -142,7 +142,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/_65_mode"
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk3"
diff --git a/app/src/main/res/layout/fragment_statistic.xml b/app/src/main/res/layout/fragment_statistic.xml
index 5172702..8662884 100644
--- a/app/src/main/res/layout/fragment_statistic.xml
+++ b/app/src/main/res/layout/fragment_statistic.xml
@@ -14,7 +14,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/statistics"
- android:textColor="@color/white"
+ android:textColor="@color/secondaryColour"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -25,7 +25,7 @@
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
- android:background="@color/secondaryColour"
+ android:background="@color/primaryColour"
app:layout_constraintBottom_toTopOf="@id/Box2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -37,7 +37,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/total_distance"
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk"
@@ -48,7 +48,7 @@
android:id="@+id/Balk"
android:layout_width="1dp"
android:layout_height="match_parent"
- android:background="@color/black"
+ android:background="@color/secondaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -59,7 +59,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@@ -74,7 +74,7 @@
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
- android:background="@color/secondaryColour"
+ android:background="@color/primaryColour"
app:layout_constraintBottom_toTopOf="@id/Box3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -86,7 +86,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/visited_locations"
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk2"
@@ -97,7 +97,7 @@
android:id="@+id/Balk2"
android:layout_width="1dp"
android:layout_height="match_parent"
- android:background="@color/black"
+ android:background="@color/secondaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -108,7 +108,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@@ -123,7 +123,7 @@
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
- android:background="@color/secondaryColour"
+ android:background="@color/primaryColour"
app:layout_constraintBottom_toTopOf="@id/Box4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -133,7 +133,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/total_time"
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk3"
@@ -144,7 +144,7 @@
android:id="@+id/Balk3"
android:layout_width="1dp"
android:layout_height="match_parent"
- android:background="@color/black"
+ android:background="@color/secondaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -155,7 +155,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@@ -170,7 +170,7 @@
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_marginHorizontal="20dp"
- android:background="@color/secondaryColour"
+ android:background="@color/primaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.85"
@@ -182,7 +182,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/coupons_collected"
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/Balk4"
@@ -193,7 +193,7 @@
android:id="@+id/Balk4"
android:layout_width="1dp"
android:layout_height="match_parent"
- android:background="@color/black"
+ android:background="@color/secondaryColour"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
@@ -204,7 +204,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/layout/help_popup.xml b/app/src/main/res/layout/help_popup.xml
index be39f71..fda4ba9 100644
--- a/app/src/main/res/layout/help_popup.xml
+++ b/app/src/main/res/layout/help_popup.xml
@@ -16,9 +16,9 @@
android:layout_width="300dp"
android:layout_height="50dp"
android:text="@string/help"
- android:textColor="@color/black"
+ android:textColor="@color/secondaryColour"
android:textAlignment="center"
- android:background="@color/secondaryColour"
+ android:background="@color/primaryColour"
android:paddingVertical="10dp"/>
diff --git a/app/src/main/res/layout/location_item.xml b/app/src/main/res/layout/location_item.xml
index 9e733b9..8e537be 100644
--- a/app/src/main/res/layout/location_item.xml
+++ b/app/src/main/res/layout/location_item.xml
@@ -4,7 +4,7 @@
android:layout_width="match_parent"
android:layout_height="50dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
- android:background="@color/secondaryColour"
+ android:background="@color/primaryColour"
android:id="@+id/locationItem"
android:layout_margin="20dp">
@@ -25,6 +25,7 @@
android:layout_height="47dp"
android:layout_marginStart="5dp"
android:gravity="left"
+ android:textColor="@color/secondaryColour"
android:text=""
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
diff --git a/app/src/main/res/layout/route_item.xml b/app/src/main/res/layout/route_item.xml
index eb1e951..cc3ac5e 100644
--- a/app/src/main/res/layout/route_item.xml
+++ b/app/src/main/res/layout/route_item.xml
@@ -4,7 +4,7 @@
android:layout_width="match_parent"
android:layout_height="50dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
- android:background="@color/secondaryColour"
+ android:background="@color/primaryColour"
android:id="@+id/routeItem"
android:layout_margin="20dp">
@@ -21,6 +21,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
+ android:textColor="@color/secondaryColour"
android:text=""
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 1fd5ed6..b6e9855 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -30,4 +30,6 @@
Eind locatie
Start locatie
"Deze route bevat de volgende locaties: "
+ Je bent dicht bij een locatie!
+ Je bent bijna bij %1$s
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index a8f6080..ebfbba9 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -7,8 +7,8 @@
#FF018786
#FF000000
#FFFFFFFF
- #FF115571
- #FF31AFB4
- #FF14212D
+ #FFFFFFFF
+ #FF000000
+ #FF000000
#FF0000
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5e11aa5..fb2c733 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -25,6 +25,8 @@
Chinese
HELP
Hasn\'t been translated yet
+ You\'re close to a location!
+ You\'re almost at %1$s
This route contains the following locations:
End location
Start location