diff --git a/app/build.gradle b/app/build.gradle
index aad18fc..78feb6e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -11,7 +11,7 @@ android {
minSdkVersion 22
targetSdkVersion 27
versionCode 1
- versionName "1.0"
+ versionName "0.9.0-alpha"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
diff --git a/app/release/release/app.aab b/app/release/release/app.aab
new file mode 100644
index 0000000..1635523
Binary files /dev/null and b/app/release/release/app.aab differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bb4aa0c..54170df 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -37,7 +37,7 @@
-
-
{
String itemName = (String) item.getTitle();
@@ -80,18 +86,21 @@ public abstract class BaseActivity
if (itemName.equals(getResources().getString(R.string.navigation_item_whitelist))) {
/* launchIntent = new Intent(getApplicationContext(), WhitelistActivity.class);
startActivity(launchIntent);*/
- } else if (itemName.equals(getResources().getString(R.string.navigation_item_blacklist))) {
+ } else if (itemName.equals(getResources().getString(R.string.navigation_item_blacklist))) {
/* launchIntent = new Intent(getApplicationContext(), BlacklistActivity.class);
startActivity(launchIntent);*/
- } else if (itemName.equals(getResources().getString(R.string.navigation_item_profile))) {
+
+ } else if (itemName.equals(getResources().getString(R.string.navigation_item_profile))) {
+
/* launchIntent = new Intent(getApplicationContext(), ProfileActivity.class);
startActivity(launchIntent);*/
- } else if (itemName.equals(getResources().getString(R.string.navigation_item_settings))) {
+ } else if (itemName.equals(getResources().getString(R.string.navigation_item_settings))) {
launchIntent = new Intent(getApplicationContext(), SettingsActivity.class);
startActivity(launchIntent);
- } else if (itemName.equals(getResources().getString(R.string.navigation_item_logout))) {
- if (PrefUtils.isBackgroundLocationServiceRunning(getApplicationContext())) {
+ } else if (itemName.equals(getResources().getString(R.string.navigation_item_logout))) {
+ if(PrefUtils.isBackgroundLocationServiceRunning(getApplicationContext())) {
+
stopBackgroundLocalizationTask();
}
@@ -105,8 +114,14 @@ public abstract class BaseActivity
}
startActivity(i);
finish();
+ } else if (itemName.equals(getResources().getString(R.string.navigation_item_feedback))) {
+ feedbackUtils.showNoteDialog("FEEDBACK");
- }
+ /*showNoteDialog(BaseActivity.this, );*/
+ } else if (itemName.equals(getResources().getString(R.string.navigation_item_bug))) {
+ feedbackUtils.showNoteDialog("BUG REPORT");
+ /*showNoteDialog(BaseActivity.this, "BUG REPORT");*/
+ }
sideDrawer.closeDrawers();
@@ -266,6 +281,7 @@ public abstract class BaseActivity
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::executeSearch);
+
return true;
}
@@ -358,6 +374,8 @@ public abstract class BaseActivity
item.setChecked(true);
}
+
+
abstract int getNavigationMenuItemId();
abstract int getContentViewId();
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/activity/MapActivity.java b/app/src/main/java/com/uam/wmi/findmytutor/activity/MapActivity.java
index a2a4a08..14a4d43 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/activity/MapActivity.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/activity/MapActivity.java
@@ -9,7 +9,6 @@ import android.content.SharedPreferences;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
-import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;
@@ -21,6 +20,7 @@ import android.widget.TextView;
import android.widget.Toast;
import com.annimon.stream.Stream;
+import com.getbase.floatingactionbutton.FloatingActionButton;
import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
import com.mapbox.android.core.permissions.PermissionsListener;
import com.mapbox.android.core.permissions.PermissionsManager;
@@ -29,8 +29,6 @@ import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
-import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationComponent;
import com.mapbox.mapboxsdk.location.LocationComponentOptions;
@@ -84,7 +82,7 @@ public class MapActivity extends BaseActivity
private HashMap markerHash = new HashMap<>();
private Set previousCoordsIds = new HashSet<>();
-
+ // Camera Animation params
private int zoomParam = 17;
private int bearingParam = 180;
private int tiltParam = 30;
@@ -113,6 +111,7 @@ public class MapActivity extends BaseActivity
Bundle extras = getIntent().getExtras();
+
Mapbox.getInstance(this, getString(R.string.access_token));
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
@@ -127,17 +126,34 @@ public class MapActivity extends BaseActivity
MapActivity.this.mapboxMap = mapboxMap;
mStatusChecker.run();
enableLocationPlugin();
-
mapboxMap.setOnMarkerClickListener(marker -> {
createMarkerModal(marker.getTitle());
return true;
});
+ setToggleMapBoundsArea();
setOnMapLongClickListener();
// addStaticLayer();
}
+ private void setToggleMapBoundsArea() {
+
+ mapUtils.setMapBoundsArea(getApplicationContext(), mapboxMap, mapView, true);
+
+ FloatingActionButton toggleBoundsAreaFab = findViewById(R.id.fab_toggle_bound_area);
+ toggleBoundsAreaFab.setOnClickListener(view -> {
+ if (toggleBoundsAreaFab.getTitle().equals("Bounds OFF")) {
+ toggleBoundsAreaFab.setTitle("Bounds ON");
+ mapUtils.setMapBoundsArea(getApplicationContext(), mapboxMap, mapView, false);
+ } else {
+ toggleBoundsAreaFab.setTitle("Bounds OFF");
+ mapUtils.setMapBoundsArea(getApplicationContext(), mapboxMap, mapView, true);
+ }
+
+ });
+ }
+
private void createMarkerModal(String userId) {
disposable.add(userService.getUserById(userId)
.subscribeOn(Schedulers.io())
@@ -169,6 +185,7 @@ public class MapActivity extends BaseActivity
alertDialog.show();
}
+
private void handleError(Throwable error) {
showError(error);
}
@@ -187,6 +204,7 @@ public class MapActivity extends BaseActivity
Toast.makeText(MapActivity.this, message, Toast.LENGTH_SHORT).show();
}
+
private void setOnMapLongClickListener() {
final boolean[] cancel = {false};
@@ -305,9 +323,16 @@ public class MapActivity extends BaseActivity
@Override
public void onSuccess(List coordsList) {
+
if (coordsList.isEmpty() && droppedMarker == null) {
Timber.e("200 empty []");
mapboxMap.clear();
+ }
+
+ if (coordsList.isEmpty()) {
+ Log.e(tag, "200 empty []");
+ //mapboxMap.clear();
+
return;
}
@@ -412,6 +437,67 @@ public class MapActivity extends BaseActivity
}
+ @SuppressWarnings({"MissingPermission"})
+ private void enableLocationPlugin() {
+ Log.e(tag, "enableLocationPlugin");
+
+ // Check if permissions are enabled and if not request
+ if (PermissionsManager.areLocationPermissionsGranted(this)) {
+ Log.e(tag, "enableLocationPlugin true");
+
+
+ LocationComponentOptions options = LocationComponentOptions.builder(this)
+ .trackingGesturesManagement(false)
+ .accuracyColor(ContextCompat.getColor(this, R.color.mapboxGray))
+ .build();
+
+ // Get an instance of the component
+ locationComponent = mapboxMap.getLocationComponent();
+
+ Log.e(tag + "Last", locationComponent.getLastKnownLocation() + "");
+
+ // Activate with options
+ locationComponent.activateLocationComponent(this, options);
+
+ // Enable to make component visible + camera animation
+ // https://www.mapbox.com/android-docs/maps/overview/location-component/
+ locationComponent.setLocationComponentEnabled(true);
+
+ // Set the component's camera mode
+ locationComponent.setCameraMode(CameraMode.NONE);
+ locationComponent.setRenderMode(RenderMode.COMPASS);
+
+ // Button 4 centring
+ FloatingActionButton myLocFAB = findViewById(R.id.myLocationButton);
+ myLocFAB.setVisibility(View.VISIBLE);
+ myLocFAB.setOnClickListener(v -> {
+
+ Location lastKnownLocation = locationComponent.getLastKnownLocation();
+ if (lastKnownLocation != null) {
+ mapUtils.makeNewCamera(mapboxMap,
+ lastKnownLocation.getLatitude(),
+ lastKnownLocation.getLongitude(),
+ zoomParam,
+ bearingParam,
+ tiltParam,
+ 4000);
+ }
+
+ // Camera aniamtion
+ zoomParam = (zoomParam == 17) ? 19 : 17;
+ bearingParam += 90;
+ tiltParam = (tiltParam == 30) ? 0 : 30;
+ });
+ } else {
+ Log.e(tag, "enableLocationPlugin false");
+
+ permissionsManager = new PermissionsManager(this);
+ permissionsManager.requestLocationPermissions(this);
+ permissionsManager.onRequestPermissionsResult(0, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, new int[]{0});
+
+ }
+ }
+
// Add the mapView lifecycle to the activity's lifecycle methods
@Override
public void onResume() {
@@ -467,69 +553,6 @@ public class MapActivity extends BaseActivity
return R.id.nav_map;
}
- @SuppressWarnings({"MissingPermission"})
- private void enableLocationPlugin() {
- Log.e(tag, "enableLocationPlugin");
-
- // Check if permissions are enabled and if not request
- if (PermissionsManager.areLocationPermissionsGranted(this)) {
- Log.e(tag, "enableLocationPlugin true");
-
- FloatingActionButton myLocationButton = findViewById(R.id.myLocationButton);
- myLocationButton.setVisibility(View.VISIBLE);
-
- LocationComponentOptions options = LocationComponentOptions.builder(this)
- .trackingGesturesManagement(true)
- .accuracyColor(ContextCompat.getColor(this, R.color.mapboxGray))
- .build();
-
- // Get an instance of the component
- locationComponent = mapboxMap.getLocationComponent();
-
- //Log.e(tag + "Last", locationComponent.getLastKnownLocation() + "");
-
- // Activate with options
- locationComponent.activateLocationComponent(this, options);
- // Enable to make component visible
- locationComponent.setLocationComponentEnabled(true);
-
- // Set the component's camera mode
- locationComponent.setCameraMode(CameraMode.TRACKING);
- locationComponent.setRenderMode(RenderMode.COMPASS);
-
- // Button 4 centring
- FloatingActionButton myLocFAB = findViewById(R.id.myLocationButton);
- myLocFAB.setOnClickListener(v -> {
-
- Location lastKnownLocation = locationComponent.getLastKnownLocation();
- if (lastKnownLocation != null) {
-
- CameraPosition position = new CameraPosition.Builder()
- .target(new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude())) // Sets the new camera position
- .zoom(zoomParam) // Sets the zoom
- .bearing(bearingParam) // Rotate the camera
- .tilt(tiltParam) // Set the camera tilt
- .build(); // Creates a CameraPosition from the builder
-
- mapboxMap.animateCamera(CameraUpdateFactory
- .newCameraPosition(position), 4000);
- }
-
- // Camera aniamtion
- zoomParam = (zoomParam == 17) ? 19 : 17;
- bearingParam += 90;
- tiltParam = (tiltParam == 30) ? 0 : 30;
- });
- } else {
- Log.e(tag, "enableLocationPlugin false");
-
- permissionsManager = new PermissionsManager(this);
- permissionsManager.requestLocationPermissions(this);
- permissionsManager.onRequestPermissionsResult(0, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, new int[]{0});
-
- }
- }
-
@Override
public void onRequestPermissionsResult(int requestCode, @android.support.annotation.NonNull String[] permissions, @android.support.annotation.NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
@@ -551,6 +574,7 @@ public class MapActivity extends BaseActivity
// }
}
+
@Override
public void searchUser(String textToSearch) {
getUserFromApi(textToSearch);
@@ -597,4 +621,5 @@ public class MapActivity extends BaseActivity
marker.setIcon(icon);
}
}
+
}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/model/Feedback.java b/app/src/main/java/com/uam/wmi/findmytutor/model/Feedback.java
new file mode 100644
index 0000000..1726c75
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/model/Feedback.java
@@ -0,0 +1,47 @@
+
+package com.uam.wmi.findmytutor.model;
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+public class Feedback {
+
+ @SerializedName("isAnonymous")
+ @Expose
+ private Boolean isAnonymous;
+ @SerializedName("header")
+ @Expose
+ private String header;
+ @SerializedName("body")
+ @Expose
+ private String body;
+
+ public Feedback(boolean isAnonymous, String header, String body){
+ this.isAnonymous = isAnonymous;
+ this.header = header;
+ this.body = body;
+ }
+ public Boolean getIsAnonymous() {
+ return isAnonymous;
+ }
+
+ public void setIsAnonymous(Boolean isAnonymous) {
+ this.isAnonymous = isAnonymous;
+ }
+
+ public String getHeader() {
+ return header;
+ }
+
+ public void setHeader(String header) {
+ this.header = header;
+ }
+
+ public String getBody() {
+ return body;
+ }
+
+ public void setBody(String body) {
+ this.body = body;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/service/FeedbackService.java b/app/src/main/java/com/uam/wmi/findmytutor/service/FeedbackService.java
new file mode 100644
index 0000000..a6d166c
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/service/FeedbackService.java
@@ -0,0 +1,17 @@
+package com.uam.wmi.findmytutor.service;
+
+import com.uam.wmi.findmytutor.model.Feedback;
+import io.reactivex.Observable;
+import io.reactivex.Single;
+import retrofit2.Response;
+import retrofit2.http.Body;
+import retrofit2.http.GET;
+import retrofit2.http.POST;
+
+public interface FeedbackService {
+ @POST("api/Feedback")
+ Observable> postFeedback(@Body Feedback feedback);
+
+ @GET("api/Feedback")
+ Single getFeedback();
+}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/FeedbackUtils.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/FeedbackUtils.java
new file mode 100644
index 0000000..afb3acd
--- /dev/null
+++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/FeedbackUtils.java
@@ -0,0 +1,122 @@
+package com.uam.wmi.findmytutor.utils;
+
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.support.v7.app.AlertDialog;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.jakewharton.retrofit2.adapter.rxjava2.HttpException;
+import com.uam.wmi.findmytutor.R;
+import com.uam.wmi.findmytutor.activity.BaseActivity;
+import com.uam.wmi.findmytutor.model.Feedback;
+import com.uam.wmi.findmytutor.network.ApiClient;
+import com.uam.wmi.findmytutor.service.FeedbackService;
+
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.schedulers.Schedulers;
+import okhttp3.ResponseBody;
+import retrofit2.Response;
+
+public class FeedbackUtils {
+ private Context activityContext;
+ public FeedbackUtils(Context context){
+ activityContext = context;
+ }
+ public void showNoteDialog(String subject) {
+
+ LayoutInflater layoutInflaterAndroid = LayoutInflater.from(activityContext);
+ View view = layoutInflaterAndroid.inflate(R.layout.feedback_modal, null);
+ AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(activityContext);
+ alertDialogBuilderUserInput.setView(view).setPositiveButton("SEND",null);
+ final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
+
+ EditText modalUserInput = view.findViewById(R.id.feedback_input);
+ CheckBox modalIsAnonymous = view.findViewById(R.id.feedback_is_anonymous);
+ TextView modalTitle = view.findViewById(R.id.feedback_modal_title);
+ TextView modalSubtitle = view.findViewById(R.id.feedback_modal_subtitle);
+ modalTitle.setText(subject);
+ if( subject == "BUG REPORT"){
+ modalSubtitle.setText("Tell us what you noticed!(max 1000 characters)");
+ } else if (subject == "FEEDBACK")
+ {
+ modalSubtitle.setText("Tell us what you think!(max 1000 characters)");
+ }
+ alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
+ @Override
+ public void onShow(DialogInterface dialogInterface) {
+ Button sendButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
+ sendButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ String body = modalUserInput.getText().toString();
+ if(TextUtils.isEmpty(body)){
+ Toast.makeText(activityContext, "Please describe your insights.", Toast.LENGTH_SHORT).show();
+ modalUserInput.requestFocus();
+ }else{
+ boolean mode = modalIsAnonymous.isChecked();
+ sendFeedback(subject,body,mode);
+ alertDialog.dismiss();
+ }
+ }
+ });
+ }
+ });
+ alertDialog.show();
+ }
+
+ private void sendFeedback(String header, String body, boolean mode) {
+ String appVersion = null;
+ String metadata = null;
+ try {
+ appVersion = activityContext.getPackageManager().getPackageInfo(activityContext.getPackageName(), 0).versionName;
+ if( !mode ){
+ metadata = "\n-----------------------------\n" +
+ "User ID: " + PrefUtils.getUserId(activityContext) + "\n" +
+ "Device OS: Android\n" +
+ "Device OS version: " + Build.VERSION.RELEASE + "\n" +
+ "App Version: " + appVersion + "\n" +
+ "Device Model: " + Build.MODEL + "\n" +
+ "Device Manufacturer: " + Build.MANUFACTURER + "\n" +
+ "-----------------------------\n";
+ body = metadata + body;
+ header = header + " - " + PrefUtils.getUserFirstName(activityContext) + " " + PrefUtils.getUserLastName(activityContext);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ FeedbackService feedbackService = ApiClient.getClient(activityContext).create(FeedbackService.class);
+ Feedback userFeedback = new Feedback(mode,header,body);
+ CompositeDisposable disposable = new CompositeDisposable();
+ disposable.add(feedbackService.postFeedback(userFeedback)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(this::handleResponse, this::handleError));
+ }
+ private void handleResponse(Response resp) {
+ Toast.makeText(activityContext, "Thank you for subbmiting your feedback", Toast.LENGTH_SHORT).show();
+ }
+
+ private void handleError(Throwable error) {
+ if (error instanceof HttpException) {
+
+ ResponseBody responseBody = ((HttpException) error).response().errorBody();
+ Toast.makeText(activityContext,
+ RestApiHelper.getErrorMessage(responseBody), Toast.LENGTH_SHORT).show();
+
+ } else {
+ Toast.makeText(activityContext,
+ "Network error " + error.getMessage(), Toast.LENGTH_SHORT).show();
+ Log.d("FEEDBACK",error.getMessage());
+ }
+ }
+}
diff --git a/app/src/main/java/com/uam/wmi/findmytutor/utils/mapUtils.java b/app/src/main/java/com/uam/wmi/findmytutor/utils/mapUtils.java
index 6c7b948..6450a7b 100644
--- a/app/src/main/java/com/uam/wmi/findmytutor/utils/mapUtils.java
+++ b/app/src/main/java/com/uam/wmi/findmytutor/utils/mapUtils.java
@@ -2,16 +2,88 @@ package com.uam.wmi.findmytutor.utils;
import android.animation.TypeEvaluator;
import android.content.Context;
+
import android.content.res.AssetManager;
+import android.graphics.Color;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.FrameLayout;
+
+
+import com.mapbox.mapboxsdk.annotations.Polygon;
+import com.mapbox.mapboxsdk.annotations.PolygonOptions;
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.style.layers.FillLayer;
+import com.mapbox.mapboxsdk.style.layers.Layer;
import java.io.IOException;
import java.io.InputStream;
public class mapUtils {
+ // Boundires
+ private static final LatLngBounds WMI_BOUNDS = new LatLngBounds.Builder()
+ .include(new LatLng(52.467886048833094, 16.92912980245876))
+ .include(new LatLng(52.46548540224137, 16.925255680881094))
+ .build();
+ private static final PolygonOptions boundsArea = new PolygonOptions()
+ .add(WMI_BOUNDS.getNorthWest())
+ .add(WMI_BOUNDS.getNorthEast())
+ .add(WMI_BOUNDS.getSouthEast())
+ .add(WMI_BOUNDS.getSouthWest())
+ .alpha(0.1f)
+ .fillColor(Color.YELLOW);
+ // For adding and removing
+ private static Polygon polygon;
+ private static View crosshair;
+
+ // Map Bounds Area
+ public static void setMapBoundsArea(Context context, MapboxMap mapboxMap, MapView mapView, Boolean check) {
+
+ if (check) {
+ // Set bounds to WMI
+ mapboxMap.setLatLngBoundsForCameraTarget(WMI_BOUNDS);
+ makeNewCamera(mapboxMap, 52.466799, 16.927002, 17, 0, 0,4000);
+ mapboxMap.setMinZoomPreference(16); // TODO export to map config
+
+ // Visualise bounds area
+ // showBoundsArea
+ polygon = mapboxMap.addPolygon(boundsArea);
+ // showCrosshair
+ crosshair = new View(context);
+ crosshair.setLayoutParams(new FrameLayout.LayoutParams(15, 15, Gravity.CENTER));
+ crosshair.setBackgroundColor(Color.GREEN);
+ mapView.addView(crosshair);
+ } else {
+ mapboxMap.setLatLngBoundsForCameraTarget(null);
+ mapboxMap.setMinZoomPreference(2);
+ mapboxMap.removePolygon(polygon);
+ mapView.removeView(crosshair);
+ }
+
+
+ }
+
+ public static void makeNewCamera(MapboxMap mapboxMap, double lat, double lon, int zoomParam, int bearingParam, int tiltParam, int duration){
+ CameraPosition position = new CameraPosition.Builder()
+ .target(new LatLng(lat, lon)) // Sets the new camera position
+ .zoom(zoomParam) // Sets the zoom
+ .bearing(bearingParam) // Rotate the camera
+ .tilt(tiltParam) // Set the camera tilt
+ .build(); // Creates a CameraPosition from the builder
+
+ mapboxMap.animateCamera(CameraUpdateFactory
+ .newCameraPosition(position), duration);
+ }
+
+ // Function for marker animation
public static class LatLngEvaluator implements TypeEvaluator {
// Method is used to interpolate the marker animation.
@@ -27,6 +99,7 @@ public class mapUtils {
}
}
+ // read file to JSON
public static String loadJsonFromAsset(Context context, String filename) {
// Using this method to load in GeoJSON files from the assets folder.
try {
diff --git a/app/src/main/res/drawable/bug_icon.xml b/app/src/main/res/drawable/bug_icon.xml
new file mode 100644
index 0000000..c3458e1
--- /dev/null
+++ b/app/src/main/res/drawable/bug_icon.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_map.xml b/app/src/main/res/layout/activity_map.xml
index f1f614e..dd40aea 100644
--- a/app/src/main/res/layout/activity_map.xml
+++ b/app/src/main/res/layout/activity_map.xml
@@ -42,13 +42,11 @@
mapbox:srcCompat="@android:drawable/ic_dialog_map"
tools:layout_editor_absoluteX="0dp" />
-
+ fab:fab_title="@string/fab_title_bound_area" />
diff --git a/app/src/main/res/layout/feedback_modal.xml b/app/src/main/res/layout/feedback_modal.xml
new file mode 100644
index 0000000..c3b8aa2
--- /dev/null
+++ b/app/src/main/res/layout/feedback_modal.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml
index d9c6b19..90a85ef 100644
--- a/app/src/main/res/menu/activity_main_drawer.xml
+++ b/app/src/main/res/menu/activity_main_drawer.xml
@@ -1,6 +1,6 @@