Develop #5

Merged
SemvdH merged 62 commits from develop into main 2021-01-14 10:55:23 +00:00
8 changed files with 214 additions and 0 deletions
Showing only changes of commit e286929b77 - Show all commits

View File

@@ -40,6 +40,7 @@ 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'

View File

@@ -25,6 +25,7 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".geofencing.GeoFenceBroadcastReceiver"/>
</application>
</manifest>

View File

@@ -11,6 +11,15 @@ public enum Data {
private int locationsVisited = 0;
private long totalTime = 0;
private double zoom = 0;
private LocationProximityListener locationProximityListener;
public LocationProximityListener getLocationProximityListener() {
return locationProximityListener;
}
public void setLocationProximityListener(LocationProximityListener locationProximityListener) {
this.locationProximityListener = locationProximityListener;
}
public double getZoom() {
return zoom;
@@ -50,5 +59,10 @@ public enum Data {
return locationsVisited;
}
@FunctionalInterface
public interface LocationProximityListener {
void onLocationVisited(Location location);
}
}

View File

@@ -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;
}
}

View File

@@ -26,6 +26,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;
@@ -71,6 +72,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
@@ -217,6 +219,8 @@ public class HomeFragment extends Fragment implements LocationListener {
}
/**
* displays the route that is currently being followed as a red line
*/
@@ -299,6 +303,17 @@ 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<com.a1.nextlocation.data.Location> locations) {
GeofenceInitalizer initializer = new GeofenceInitalizer(requireContext());
initializer.init(locations);
}
/**
@@ -365,6 +380,11 @@ public class HomeFragment extends Fragment implements LocationListener {
}
public void onLocationVisited(com.a1.nextlocation.data.Location location) {
Data.INSTANCE.visitLocation(location);
}
// empty override methods for the LocationListener
@Override

View File

@@ -0,0 +1,55 @@
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.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;
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);
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<Geofence> 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
break;
}
}
}
break;
case Geofence.GEOFENCE_TRANSITION_EXIT:
Log.d(TAG, "onReceive: exiting geofence...");
break;
}
}
}

View File

@@ -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, 2607, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
}

View File

@@ -0,0 +1,62 @@
package com.a1.nextlocation.geofencing;
import android.Manifest;
import android.app.PendingIntent;
import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;
import androidx.core.app.ActivityCompat;
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 org.osmdroid.util.GeoPoint;
import java.util.List;
public class GeofenceInitalizer {
private GeofencingClient geofencingClient;
private GeoFencingHelper geoFencingHelper;
private final Context context;
private final String TAG = GeofenceInitalizer.class.getCanonicalName();
private List<Location> locations;
public GeofenceInitalizer(Context context) {
this.context = context;
}
public void init(List<Location> locations) {
geofencingClient = LocationServices.getGeofencingClient(context);
geoFencingHelper = new GeoFencingHelper(context);
this.locations = locations;
addFences();
}
private void addFences() {
for (Location location : locations) {
GeoPoint t = new GeoPoint(location.getLat(), location.getLong());
addGeofence(t, location.getName());
}
}
private void addGeofence(GeoPoint p, String name) {
Geofence geofence = geoFencingHelper.getGeofence(name, p, 30);
GeofencingRequest geofencingRequest = geoFencingHelper.getGeoFencingRequest(geofence);
PendingIntent pendingIntent = geoFencingHelper.getPendingIntent();
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
geofencingClient.addGeofences(geofencingRequest, pendingIntent).addOnSuccessListener(v -> {
Log.d(TAG, "addGeofence: added geofence");
}).addOnFailureListener(v -> {
});
}
}