diff --git a/app/build.gradle b/app/build.gradle index 24d9fa9..352dc41 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -35,6 +35,9 @@ android { // WalkersGuide server url buildConfigField 'String', 'SERVER_URL', '"https://api.walkersguide.org/"' buildConfigField 'String', 'SERVER_URL_DEV', '"https://api.test.walkersguide.org/"' + // public-transport-enabler library + buildConfigField 'String', 'PTE_LINK_MAIN_WEBSITE', '"https://github.com/schildbach/public-transport-enabler"' + buildConfigField 'String', 'PTE_LINK_PROVIDER_LIST', '"https://github.com/schildbach/public-transport-enabler/tree/master/src/de/schildbach/pte"' } signingConfigs { @@ -143,3 +146,4 @@ repositories { dirs 'libs' } } + diff --git a/app/src/main/java/org/walkersguide/android/data/object_with_id/Route.java b/app/src/main/java/org/walkersguide/android/data/object_with_id/Route.java index c6d0c85..dcf4407 100644 --- a/app/src/main/java/org/walkersguide/android/data/object_with_id/Route.java +++ b/app/src/main/java/org/walkersguide/android/data/object_with_id/Route.java @@ -153,13 +153,13 @@ public Builder setReversed(final boolean reversed) throws JSONException { public Builder setViaPoints(final Point via1, final Point via2, final Point via3) throws JSONException { if (via1 != null) { - inputData.put(KEY_VIA_POINT_1, via1); + inputData.put(KEY_VIA_POINT_1, via1.toJson()); } if (via2 != null) { - inputData.put(KEY_VIA_POINT_2, via2); + inputData.put(KEY_VIA_POINT_2, via2.toJson()); } if (via3 != null) { - inputData.put(KEY_VIA_POINT_3, via3); + inputData.put(KEY_VIA_POINT_3, via3.toJson()); } return this; } @@ -366,6 +366,10 @@ public Point getViaPoint3() { return this.viaPoint3; } + public boolean hasViaPoint() { + return getViaPoint1() != null || getViaPoint2() != null || getViaPoint3() != null; + } + /** * super class methods diff --git a/app/src/main/java/org/walkersguide/android/data/profile/AnnouncementRadius.java b/app/src/main/java/org/walkersguide/android/data/profile/AnnouncementRadius.java index 9e8bad0..1ac3c50 100644 --- a/app/src/main/java/org/walkersguide/android/data/profile/AnnouncementRadius.java +++ b/app/src/main/java/org/walkersguide/android/data/profile/AnnouncementRadius.java @@ -11,7 +11,7 @@ public class AnnouncementRadius implements Serializable { private static final long serialVersionUID = 1l; - private static final int[] values = new int[]{ 25, 50, 100, 250, 500, 1000 }; + private static final int[] values = new int[]{ 25, 50, 75, 100, 150, 200, 250, 500, 750, 1000 }; public static ArrayList values() { ArrayList announcementRadiusList = new ArrayList(); @@ -38,10 +38,18 @@ private AnnouncementRadius(int meter) throws IllegalArgumentException { this.meter = meter; } - @Override public String toString() { + public String longFormat() { return GlobalInstance.getPluralResource(R.plurals.meter, this.meter); } + public String shortFormat() { + return GlobalInstance.getPluralResource(R.plurals.meterShort, this.meter); + } + + @Override public String toString() { + return longFormat(); + } + @Override public int hashCode() { return this.meter; } diff --git a/app/src/main/java/org/walkersguide/android/sensor/DeviceSensorManager.java b/app/src/main/java/org/walkersguide/android/sensor/DeviceSensorManager.java index 7cbf41b..6a8f403 100644 --- a/app/src/main/java/org/walkersguide/android/sensor/DeviceSensorManager.java +++ b/app/src/main/java/org/walkersguide/android/sensor/DeviceSensorManager.java @@ -151,11 +151,16 @@ public BearingSensor getSelectedBearingSensor() { public void setSelectedBearingSensor(BearingSensor newBearingSensor) { if (newBearingSensor != null) { settingsManagerInstance.setSelectedBearingSensor(newBearingSensor); - LocalBroadcastManager.getInstance(GlobalInstance.getContext()).sendBroadcast(new Intent(ACTION_BEARING_SENSOR_CHANGED)); + broadcastBearingSensorChanged(); broadcastCurrentBearing(true); } } + public void broadcastBearingSensorChanged() { + LocalBroadcastManager.getInstance(GlobalInstance.getContext()) + .sendBroadcast(new Intent(ACTION_BEARING_SENSOR_CHANGED)); + } + public boolean isDeviceUpright() { return this.deviceUpright; } @@ -517,6 +522,10 @@ && getSelectedBearingSensor() == BearingSensor.SATELLITE) { * simulated bearing */ + // enable / disable simulation + public static final String ACTION_SIMULATION_STATUS_CHANGED = "bearingSimulationStatusChanged"; + public static final String EXTRA_SIMULATION_ENABLED = "bearingSimulationEnabled"; + private boolean simulationEnabled = false; public boolean getSimulationEnabled() { @@ -524,19 +533,28 @@ public boolean getSimulationEnabled() { } public void setSimulationEnabled(boolean enabled) { - this.simulationEnabled = enabled; - broadcastCurrentBearing(true); + if (getSimulationEnabled() != enabled) { + this.simulationEnabled = enabled; + broadcastSimulationStatusChanged(); + broadcastCurrentBearing(true); + } + } + + private void broadcastSimulationStatusChanged() { + Intent intent = new Intent(ACTION_SIMULATION_STATUS_CHANGED); + intent.putExtra(EXTRA_SIMULATION_ENABLED, getSimulationEnabled()); + LocalBroadcastManager.getInstance(GlobalInstance.getContext()).sendBroadcast(intent); } // change simulated bearing - public static final String ACTION_NEW_SIMULATED_BEARING = "new_simulated_bearing"; + public static final String ACTION_NEW_BEARING_VALUE_FROM_SIMULATION = "new_bearing_value_from_simulation"; public void requestSimulatedBearing() { broadcastSimulatedBearing(); } private void broadcastSimulatedBearing() { - Intent intent = new Intent(ACTION_NEW_SIMULATED_BEARING); + Intent intent = new Intent(ACTION_NEW_BEARING_VALUE_FROM_SIMULATION); intent.putExtra(EXTRA_BEARING, getSimulatedBearing()); LocalBroadcastManager.getInstance(GlobalInstance.getContext()).sendBroadcast(intent); } @@ -546,14 +564,19 @@ public Bearing getSimulatedBearing() { } public void setSimulatedBearing(Bearing newBearing) { + settingsManagerInstance.setSimulatedBearing(newBearing); + if (newBearing != null) { - settingsManagerInstance.setSimulatedBearing(newBearing); - // broadcast new simulated bearing action - broadcastSimulatedBearing(); - // broadcast new bearing action - if (this.simulationEnabled) { + if (getSimulationEnabled()) { broadcastCurrentBearing(true); + } else { + setSimulationEnabled(true); } + // broadcast new simulated bearing action + broadcastSimulatedBearing(); + + } else if (getSimulationEnabled()) { + setSimulationEnabled(false); } } diff --git a/app/src/main/java/org/walkersguide/android/sensor/PositionManager.java b/app/src/main/java/org/walkersguide/android/sensor/PositionManager.java index 3a0f26b..e836226 100644 --- a/app/src/main/java/org/walkersguide/android/sensor/PositionManager.java +++ b/app/src/main/java/org/walkersguide/android/sensor/PositionManager.java @@ -363,6 +363,8 @@ private BearingSensorAccuracyRating extractBearingSensorAccuracyRating(Location */ // enable / disable simulation + public static final String ACTION_SIMULATION_STATUS_CHANGED = "locationSimulationStatusChanged"; + public static final String EXTRA_SIMULATION_ENABLED = "locationSimulationEnabled"; private boolean simulationEnabled = false; @@ -371,8 +373,18 @@ public boolean getSimulationEnabled() { } public void setSimulationEnabled(boolean enabled) { - this.simulationEnabled = enabled; - broadcastCurrentLocation(true); + if (getSimulationEnabled() != enabled) { + this.simulationEnabled = enabled; + broadcastSimulationStatusChanged(); + broadcastCurrentLocation(true); + } + } + + private void broadcastSimulationStatusChanged() { + Timber.d("broadcastSimulationStatusChanged"); + Intent intent = new Intent(ACTION_SIMULATION_STATUS_CHANGED); + intent.putExtra(EXTRA_SIMULATION_ENABLED, getSimulationEnabled()); + LocalBroadcastManager.getInstance(GlobalInstance.getContext()).sendBroadcast(intent); } // change simulated location @@ -397,16 +409,21 @@ public Point getSimulatedLocation() { } public void setSimulatedLocation(Point newPoint) { + settingsManagerInstance.setSimulatedPoint(newPoint); + if (newPoint != null) { - settingsManagerInstance.setSimulatedPoint(newPoint); - // add to history - HistoryProfile.simulatedPoints().addObject(newPoint); - // broadcast new simulated location action - broadcastSimulatedLocation(); - // broadcast new location action - if (this.simulationEnabled) { + if (getSimulationEnabled()) { broadcastCurrentLocation(true); + } else { + setSimulationEnabled(true); } + // broadcast new simulated location action + broadcastSimulatedLocation(); + // add to history + HistoryProfile.simulatedPoints().addObject(newPoint); + + } else if (getSimulationEnabled()) { + setSimulationEnabled(false); } } diff --git a/app/src/main/java/org/walkersguide/android/server/wg/p2p/P2pRouteTask.java b/app/src/main/java/org/walkersguide/android/server/wg/p2p/P2pRouteTask.java index 56a336c..dfd6027 100644 --- a/app/src/main/java/org/walkersguide/android/server/wg/p2p/P2pRouteTask.java +++ b/app/src/main/java/org/walkersguide/android/server/wg/p2p/P2pRouteTask.java @@ -81,14 +81,8 @@ public P2pRouteTask(P2pRouteRequest request, WayClassWeightSettings wayClassWeig } // allowed way classes - JSONObject jsonWayClassTypeAndWeightMappings = new JSONObject(); - for (WayClassType type : WayClassType.values()) { - jsonWayClassTypeAndWeightMappings.put( - type.id, - wayClassWeightSettings.getWeightFor(type).weight); - } jsonServerParams.put( - "allowed_way_classes", jsonWayClassTypeAndWeightMappings); + "allowed_way_classes", this.wayClassWeightSettings.toJson()); } catch (JSONException e) { throw new WgException(WgException.RC_BAD_REQUEST); diff --git a/app/src/main/java/org/walkersguide/android/server/wg/p2p/WayClassWeightSettings.java b/app/src/main/java/org/walkersguide/android/server/wg/p2p/WayClassWeightSettings.java index 48fa054..4ef3e78 100644 --- a/app/src/main/java/org/walkersguide/android/server/wg/p2p/WayClassWeightSettings.java +++ b/app/src/main/java/org/walkersguide/android/server/wg/p2p/WayClassWeightSettings.java @@ -5,27 +5,100 @@ import org.walkersguide.android.server.wg.p2p.wayclass.WayClassWeight; import java.io.Serializable; -import java.util.HashMap; +import org.json.JSONException; +import org.json.JSONObject; +import java.util.Map; +import java.util.Locale; +import java.util.LinkedHashMap; +import java.lang.Comparable; +import org.walkersguide.android.util.GlobalInstance; public class WayClassWeightSettings implements Serializable { private static final long serialVersionUID = 1l; - public static WayClassWeightSettings getDefault() { - HashMap map = new HashMap(); - for (WayClassType type : WayClassType.values()) { - map.put(type, type.defaultWeight); + public enum Preset { + URBAN_ON_FOOT( + 1, + GlobalInstance.getStringResource(R.string.wcwsPresetUrbanOnFoot), + presetUrbanOnFoot()), + URBAN_BY_CAR( + 2, + GlobalInstance.getStringResource(R.string.wcwsPresetUrbanByCar), + presetUrbanByCar()), + HIKING( + 3, + GlobalInstance.getStringResource(R.string.wcwsPresetHiking), + presetHiking()); + + public static Preset matches(WayClassWeightSettings settings) { + for (Preset preset : values()) { + if (preset.settings.equals(settings)) { + return preset; + } + } + return null; + } + + public int id; + public String label; + public WayClassWeightSettings settings; + + private Preset(int id, String label, WayClassWeightSettings settings) { + this.id = id; + this.label = label; + this.settings = settings; + } + + @Override public String toString() { + return this.label.replace(" ", "\u00A0"); + } + + private static WayClassWeightSettings presetUrbanOnFoot() { + LinkedHashMap map = new LinkedHashMap(); + map.put(WayClassType.BIG_STREETS, WayClassWeight.SLIGHTLY_PREFER); + map.put(WayClassType.SMALL_STREETS, WayClassWeight.STRONGLY_PREFER); + map.put(WayClassType.PAVED_WAYS, WayClassWeight.NEUTRAL); + map.put(WayClassType.UNPAVED_WAYS, WayClassWeight.AVOID); + map.put(WayClassType.STEPS, WayClassWeight.SLIGHTLY_AVOID); + map.put(WayClassType.UNCLASSIFIED_WAYS, WayClassWeight.AVOID); + return new WayClassWeightSettings(map); + } + + private static WayClassWeightSettings presetUrbanByCar() { + LinkedHashMap map = new LinkedHashMap(); + map.put(WayClassType.BIG_STREETS, WayClassWeight.STRONGLY_PREFER); + map.put(WayClassType.SMALL_STREETS, WayClassWeight.NEUTRAL); + map.put(WayClassType.PAVED_WAYS, WayClassWeight.EXCLUDE); + map.put(WayClassType.UNPAVED_WAYS, WayClassWeight.EXCLUDE); + map.put(WayClassType.STEPS, WayClassWeight.EXCLUDE); + map.put(WayClassType.UNCLASSIFIED_WAYS, WayClassWeight.EXCLUDE); + return new WayClassWeightSettings(map); + } + + private static WayClassWeightSettings presetHiking() { + LinkedHashMap map = new LinkedHashMap(); + map.put(WayClassType.BIG_STREETS, WayClassWeight.EXCLUDE); + map.put(WayClassType.SMALL_STREETS, WayClassWeight.AVOID); + map.put(WayClassType.PAVED_WAYS, WayClassWeight.STRONGLY_PREFER); + map.put(WayClassType.UNPAVED_WAYS, WayClassWeight.NEUTRAL); + map.put(WayClassType.STEPS, WayClassWeight.AVOID); + map.put(WayClassType.UNCLASSIFIED_WAYS, WayClassWeight.AVOID); + return new WayClassWeightSettings(map); } - return new WayClassWeightSettings(map); } - private HashMap typeWeightMap; + private LinkedHashMap typeWeightMap; - public WayClassWeightSettings(HashMap typeWeightMap) { + public WayClassWeightSettings(LinkedHashMap typeWeightMap) { this.typeWeightMap = typeWeightMap; } + public int getNumberOfEntries() { + return this.typeWeightMap.size(); + } + public WayClassWeight getWeightFor(WayClassType type) { return this.typeWeightMap.get(type); } @@ -36,4 +109,41 @@ public void setWeightFor(WayClassType type, WayClassWeight newWeight) { } } + @Override public int hashCode() { + int result = 1; + for (Map.Entry entry : typeWeightMap.entrySet()) { + result += Double.valueOf(entry.getValue().weight).hashCode(); + } + return result; + } + + @Override public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj == null) { + return false; + } else if (! (obj instanceof WayClassWeightSettings)) { + return false; + } + WayClassWeightSettings other = (WayClassWeightSettings) obj; + if (this.typeWeightMap.size() != other.getNumberOfEntries()) { + return false; + } + for (Map.Entry entry : this.typeWeightMap.entrySet()) { + if (entry.getValue() != other.getWeightFor(entry.getKey())) { + return false; + } + } + return true; + } + + public JSONObject toJson() throws JSONException { + JSONObject jsonWayClassTypeAndWeightMappings = new JSONObject(); + for (Map.Entry entry : typeWeightMap.entrySet()) { + jsonWayClassTypeAndWeightMappings.put( + entry.getKey().name().toLowerCase(Locale.ROOT), entry.getValue().weight); + } + return jsonWayClassTypeAndWeightMappings; + } + } diff --git a/app/src/main/java/org/walkersguide/android/server/wg/p2p/wayclass/WayClassType.java b/app/src/main/java/org/walkersguide/android/server/wg/p2p/wayclass/WayClassType.java index ff5a9a0..88b972e 100644 --- a/app/src/main/java/org/walkersguide/android/server/wg/p2p/wayclass/WayClassType.java +++ b/app/src/main/java/org/walkersguide/android/server/wg/p2p/wayclass/WayClassType.java @@ -6,43 +6,22 @@ public enum WayClassType { - BIG_STREETS( - "big_streets", - GlobalInstance.getStringResource(R.string.wayClassTypeBigStreets), - WayClassWeight.SLIGHTLY_PREFER), - SMALL_STREETS( - "small_streets", - GlobalInstance.getStringResource(R.string.wayClassTypeSmallStreets), - WayClassWeight.STRONGLY_PREFER), - PAVED_WAYS( - "paved_ways", - GlobalInstance.getStringResource(R.string.wayClassTypePavedWays), - WayClassWeight.NEUTRAL), - UNPAVED_WAYS( - "unpaved_ways", - GlobalInstance.getStringResource(R.string.wayClassTypeUnpavedWays), - WayClassWeight.AVOID), - STEPS( - "steps", - GlobalInstance.getStringResource(R.string.wayClassTypeSteps), - WayClassWeight.SLIGHTLY_AVOID), - UNCLASSIFIED_WAYS( - "unclassified_ways", - GlobalInstance.getStringResource(R.string.wayClassTypeUnclassifiedWays), - WayClassWeight.AVOID); - - - public String id, name; - public WayClassWeight defaultWeight; - - private WayClassType(String id, String name, WayClassWeight defaultWeight) { - this.id = id; - this.name = name; - this.defaultWeight = defaultWeight; + BIG_STREETS(GlobalInstance.getStringResource(R.string.wayClassTypeBigStreets)), + SMALL_STREETS(GlobalInstance.getStringResource(R.string.wayClassTypeSmallStreets)), + PAVED_WAYS(GlobalInstance.getStringResource(R.string.wayClassTypePavedWays)), + UNPAVED_WAYS(GlobalInstance.getStringResource(R.string.wayClassTypeUnpavedWays)), + STEPS(GlobalInstance.getStringResource(R.string.wayClassTypeSteps)), + UNCLASSIFIED_WAYS(GlobalInstance.getStringResource(R.string.wayClassTypeUnclassifiedWays)); + + + public String label; + + private WayClassType(String label) { + this.label = label; } @Override public String toString() { - return this.name; + return this.label; } } diff --git a/app/src/main/java/org/walkersguide/android/server/wg/p2p/wayclass/WayClassWeight.java b/app/src/main/java/org/walkersguide/android/server/wg/p2p/wayclass/WayClassWeight.java index 7aaf874..0f3b985 100644 --- a/app/src/main/java/org/walkersguide/android/server/wg/p2p/wayclass/WayClassWeight.java +++ b/app/src/main/java/org/walkersguide/android/server/wg/p2p/wayclass/WayClassWeight.java @@ -25,15 +25,15 @@ public enum WayClassWeight { public double weight; - public String name; + public String label; - private WayClassWeight(double weight, String name) { + private WayClassWeight(double weight, String label) { this.weight = weight; - this.name = name; + this.label = label; } @Override public String toString() { - return this.name; + return this.label; } } diff --git a/app/src/main/java/org/walkersguide/android/ui/UiHelper.java b/app/src/main/java/org/walkersguide/android/ui/UiHelper.java index c43c0b3..efab8ac 100644 --- a/app/src/main/java/org/walkersguide/android/ui/UiHelper.java +++ b/app/src/main/java/org/walkersguide/android/ui/UiHelper.java @@ -1,5 +1,6 @@ package org.walkersguide.android.ui; +import org.walkersguide.android.BuildConfig; import androidx.core.view.AccessibilityDelegateCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; @@ -169,6 +170,14 @@ public static SpannableString urlStyle(String text) { return spanString; } + public static Spanned getPublicTransportDataSourceText() { + return fromHtml( + String.format( + GlobalInstance.getStringResource(R.string.labelPublicTransportMessage), + BuildConfig.PTE_LINK_MAIN_WEBSITE, + BuildConfig.PTE_LINK_PROVIDER_LIST)); + } + @SuppressWarnings("deprecation") public static Spanned fromHtml(String html){ if (html == null) { diff --git a/app/src/main/java/org/walkersguide/android/ui/activity/MainActivity.java b/app/src/main/java/org/walkersguide/android/ui/activity/MainActivity.java index 79272b5..6b702e8 100644 --- a/app/src/main/java/org/walkersguide/android/ui/activity/MainActivity.java +++ b/app/src/main/java/org/walkersguide/android/ui/activity/MainActivity.java @@ -1,5 +1,6 @@ package org.walkersguide.android.ui.activity; +import org.walkersguide.android.ui.dialog.WhereAmIDialog; import org.walkersguide.android.ui.dialog.create.EnterAddressDialog; import org.walkersguide.android.BuildConfig; import java.util.List; @@ -73,8 +74,6 @@ import org.walkersguide.android.ui.dialog.PlanRouteDialog; import org.walkersguide.android.ui.dialog.SendFeedbackDialog; import org.walkersguide.android.ui.dialog.SimpleMessageDialog; -import org.walkersguide.android.ui.dialog.WhereAmIDialog; -import org.walkersguide.android.ui.dialog.create.PointFromCoordinatesLinkDialog; import org.walkersguide.android.ui.dialog.create.SaveCurrentLocationDialog; import org.walkersguide.android.ui.dialog.toolbar.BearingDetailsDialog; import org.walkersguide.android.ui.dialog.toolbar.LocationDetailsDialog; @@ -103,6 +102,10 @@ import java.io.UnsupportedEncodingException; import org.walkersguide.android.data.object_with_id.point.point_with_address_data.StreetAddress; import org.walkersguide.android.server.wg.p2p.P2pRouteRequest; +import org.walkersguide.android.util.Helper; +import java.util.ArrayList; +import android.hardware.Sensor; +import android.widget.Toast; public class MainActivity extends AppCompatActivity @@ -136,8 +139,18 @@ public static void loadRoute(Context context, Route route) { context.startActivity(mainActivityIntent); } + public static void startRouteRecording(Context context) { + WalkersGuideService.startRouteRecording(); + // see openTab(...) function below + Intent mainActivityIntent = new Intent(context, MainActivity.class); + mainActivityIntent.putExtra(EXTRA_NEW_TAB, Tab.ROUTES); + mainActivityIntent.putExtra(EXTRA_NEW_SUB_TAB, RoutesTabLayoutFragment.Tab.RECORD); + context.startActivity(mainActivityIntent); + } // activity + private static String KEY_CONTROL_SIMULATION_ACCESSIBILITY_ACTION_ID_FOR_BEARING = "controlSimulationAccessibilityActionIdForBearing"; + private static String KEY_CONTROL_SIMULATION_ACCESSIBILITY_ACTION_ID_FOR_LOCATION = "controlSimulationAccessibilityActionIdForLocation"; private static String KEY_SKIP_POSITION_MANAGER_INITIALISATION_DURING_ON_RESUME = "skipPositionManagerInitialisationDuringOnResume"; private static final String KEY_LAST_URI = "lastUri"; @@ -145,6 +158,9 @@ public static void loadRoute(Context context, Route route) { private DeviceSensorManager deviceSensorManagerInstance; private PositionManager positionManagerInstance; private SettingsManager settingsManagerInstance; + + private ArrayList bearingSourceAccessibilityActionIdList = new ArrayList();; + private int controlSimulationAccessibilityActionIdForBearing, controlSimulationAccessibilityActionIdForLocation; private boolean broadcastReceiverAlreadyRegistered, skipPositionManagerInitialisationDuringOnResume; private Uri lastUri; @@ -168,6 +184,14 @@ public static void loadRoute(Context context, Route route) { positionManagerInstance = PositionManager.getInstance(); settingsManagerInstance = SettingsManager.getInstance(); broadcastReceiverAlreadyRegistered = false; + controlSimulationAccessibilityActionIdForBearing = + savedInstanceState != null + ? savedInstanceState.getInt(KEY_CONTROL_SIMULATION_ACCESSIBILITY_ACTION_ID_FOR_BEARING) + : View.NO_ID; + controlSimulationAccessibilityActionIdForLocation = + savedInstanceState != null + ? savedInstanceState.getInt(KEY_CONTROL_SIMULATION_ACCESSIBILITY_ACTION_ID_FOR_LOCATION) + : View.NO_ID; skipPositionManagerInitialisationDuringOnResume = savedInstanceState != null ? savedInstanceState.getBoolean(KEY_SKIP_POSITION_MANAGER_INITIALISATION_DURING_ON_RESUME) @@ -177,9 +201,6 @@ public static void loadRoute(Context context, Route route) { ? savedInstanceState.getParcelable(KEY_LAST_URI) : null; - getSupportFragmentManager() - .setFragmentResultListener( - PointFromCoordinatesLinkDialog.REQUEST_FROM_COORDINATES_LINK, this, this); getSupportFragmentManager() .setFragmentResultListener( ImportGpxFileDialog.REQUEST_IMPORT_OF_GPX_FILE_WAS_SUCCESSFUL, this, this); @@ -233,13 +254,13 @@ public void onClick(View view) { @Override public boolean onNavigationItemSelected(MenuItem menuItem) { drawerLayout.closeDrawers(); if (menuItem.getItemId() == R.id.menuItemPlanRoute) { - openPlanRouteDialog(); + openPlanRouteDialog(false); } else if (menuItem.getItemId() == R.id.menuItemSaveCurrentLocation) { SaveCurrentLocationDialog.addToDatabaseProfile() .show(getSupportFragmentManager(), "SaveCurrentLocationDialog"); - } else if (menuItem.getItemId() == R.id.menuItemOpenPointShareLink) { - PointFromCoordinatesLinkDialog.newInstance() - .show(getSupportFragmentManager(), "PointFromCoordinatesLinkDialog"); + } else if (menuItem.getItemId() == R.id.menuItemOpenWhereAmIDialog) { + WhereAmIDialog.newInstance() + .show(getSupportFragmentManager(), "WhereAmIDialog"); } else if (menuItem.getItemId() == R.id.menuItemCollections) { CollectionListFragment.newInstance() .show(getSupportFragmentManager(), "CollectionListFragment"); @@ -424,13 +445,6 @@ private void openTab(Intent intent) { .show(getSupportFragmentManager(), "Details"); } - } else if (requestKey.equals(PointFromCoordinatesLinkDialog.REQUEST_FROM_COORDINATES_LINK)) { - Point sharedLocation = (Point) bundle.getSerializable(PointFromCoordinatesLinkDialog.EXTRA_COORDINATES); - if (sharedLocation != null) { - ObjectDetailsTabLayoutFragment.details(sharedLocation) - .show(getSupportFragmentManager(), "Details"); - } - } else if (requestKey.equals(ImportGpxFileDialog.REQUEST_IMPORT_OF_GPX_FILE_WAS_SUCCESSFUL)) { DatabaseProfile importedGpxFileCollection = (DatabaseProfile) bundle.getSerializable(ImportGpxFileDialog.EXTRA_GPX_FILE_PROFILE); if (importedGpxFileCollection != null) { @@ -442,6 +456,8 @@ private void openTab(Intent intent) { @Override public void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); + savedInstanceState.putInt(KEY_CONTROL_SIMULATION_ACCESSIBILITY_ACTION_ID_FOR_BEARING, controlSimulationAccessibilityActionIdForBearing); + savedInstanceState.putInt(KEY_CONTROL_SIMULATION_ACCESSIBILITY_ACTION_ID_FOR_LOCATION, controlSimulationAccessibilityActionIdForLocation); savedInstanceState.putBoolean(KEY_SKIP_POSITION_MANAGER_INITIALISATION_DURING_ON_RESUME, skipPositionManagerInitialisationDuringOnResume); savedInstanceState.putParcelable(KEY_LAST_URI, lastUri); } @@ -501,6 +517,80 @@ private void updateBearingDetailsButton() { buttonBearingDetails.setContentDescription(bearingDescriptionBuilder.toString()); } + private void updateAccessibilityActionsOnBearingDetailsButton() { + // bearing source + // + // clear + for (Integer actionId : bearingSourceAccessibilityActionIdList) { + ViewCompat.removeAccessibilityAction(buttonBearingDetails, actionId); + } + bearingSourceAccessibilityActionIdList.clear(); + + if (! settingsManagerInstance.getAutoSwitchBearingSourceEnabled()) { + for (final BearingSensor sensor : BearingSensor.values()) { + if (sensor.equals(settingsManagerInstance.getSelectedBearingSensor())) { + continue; + } + + int actionId = ViewCompat.addAccessibilityAction( + this.buttonBearingDetails, + String.format( + GlobalInstance.getStringResource(R.string.accessibilityActionUseBearingSource), + sensor.toString()), + (actionView, arguments) -> { + if (sensor.equals(BearingSensor.SATELLITE) + && deviceSensorManagerInstance.getBearingValueFromSatellite() == null) { + // can't enable + Toast.makeText( + MainActivity.this, + getResources().getString(R.string.errorNoBearingFound), + Toast.LENGTH_LONG).show(); + } else { + ViewCompat.setAccessibilityLiveRegion( + buttonBearingDetails, ViewCompat.ACCESSIBILITY_LIVE_REGION_POLITE); + Helper.vibrateOnce( + Helper.VIBRATION_DURATION_SHORT, Helper.VIBRATION_INTENSITY_WEAK); + deviceSensorManagerInstance.setSelectedBearingSensor(sensor); + } + return true; + }); + if (actionId != View.NO_ID) { + bearingSourceAccessibilityActionIdList.add(actionId); + } + } + } + + // simulation status + // + // clear + if (controlSimulationAccessibilityActionIdForBearing != View.NO_ID) { + ViewCompat.removeAccessibilityAction( + this.buttonBearingDetails, controlSimulationAccessibilityActionIdForBearing); + } + + // and create action to switch status + Bearing simulatedBearing = deviceSensorManagerInstance.getSimulatedBearing(); + if (simulatedBearing != null) { + controlSimulationAccessibilityActionIdForBearing = ViewCompat.addAccessibilityAction( + this.buttonBearingDetails, + String.format( + deviceSensorManagerInstance.getSimulationEnabled() + ? GlobalInstance.getStringResource(R.string.accessibilityActionEndSimulation) + : GlobalInstance.getStringResource(R.string.accessibilityActionStartSimulationBearing), + simulatedBearing.toString()), + + (actionView, arguments) -> { + ViewCompat.setAccessibilityLiveRegion( + buttonBearingDetails, ViewCompat.ACCESSIBILITY_LIVE_REGION_POLITE); + Helper.vibrateOnce( + Helper.VIBRATION_DURATION_SHORT, Helper.VIBRATION_INTENSITY_WEAK); + deviceSensorManagerInstance.setSimulationEnabled( + ! deviceSensorManagerInstance.getSimulationEnabled()); + return true; + }); + } + } + private void updateLocationDetailsButton() { Point currentLocation = positionManagerInstance.getCurrentLocation(); StringBuilder locationDescriptionBuilder = new StringBuilder(); @@ -534,6 +624,37 @@ private void updateLocationDetailsButton() { buttonLocationDetails.setContentDescription(locationDescriptionBuilder.toString()); } + private void updateAccessibilityActionsOnLocationDetailsButton() { + // clear + if (controlSimulationAccessibilityActionIdForLocation != View.NO_ID) { + ViewCompat.removeAccessibilityAction( + this.buttonLocationDetails, controlSimulationAccessibilityActionIdForLocation); + } + + // and create action to control simulation status + Point simulatedPoint = positionManagerInstance.getSimulatedLocation(); + if (simulatedPoint != null) { + Timber.d("updateAccessibilityActionsOnLocationDetailsButton: set location action, sim enabled: %1$s", positionManagerInstance.getSimulationEnabled()); + controlSimulationAccessibilityActionIdForLocation = ViewCompat.addAccessibilityAction( + this.buttonLocationDetails, + String.format( + positionManagerInstance.getSimulationEnabled() + ? GlobalInstance.getStringResource(R.string.accessibilityActionEndSimulation) + : GlobalInstance.getStringResource(R.string.accessibilityActionStartSimulationLocation), + simulatedPoint.getName()), + + (actionView, arguments) -> { + ViewCompat.setAccessibilityLiveRegion( + buttonLocationDetails, ViewCompat.ACCESSIBILITY_LIVE_REGION_POLITE); + Helper.vibrateOnce( + Helper.VIBRATION_DURATION_SHORT, Helper.VIBRATION_INTENSITY_WEAK); + positionManagerInstance.setSimulationEnabled( + ! positionManagerInstance.getSimulationEnabled()); + return true; + }); + } + } + /** * pause and resume @@ -555,7 +676,9 @@ private void updateLocationDetailsButton() { registerBroadcastReceiver(); displayRemainsActiveSettingChanged( settingsManagerInstance.getDisplayRemainsActive()); + updateAccessibilityActionsOnBearingDetailsButton(); updateBearingDetailsButton(); + updateAccessibilityActionsOnLocationDetailsButton(); updateLocationDetailsButton(); WalkersGuideService.requestServiceState(); @@ -583,7 +706,7 @@ private void updateLocationDetailsButton() { // handle static shortcuts for (StaticShortcutAction action : globalInstance.getEnabledStaticShortcutActions()) { if (action == StaticShortcutAction.OPEN_PLAN_ROUTE_DIALOG) { - openPlanRouteDialog(); + openPlanRouteDialog(false); } else if (action == StaticShortcutAction.OPEN_SAVE_CURRENT_LOCATION_DIALOG) { SaveCurrentLocationDialog.addToDatabaseProfile() .show(getSupportFragmentManager(), "SaveCurrentLocationDialog"); @@ -609,12 +732,21 @@ private void updateLocationDetailsButton() { } private void registerBroadcastReceiver() { + Timber.d("registerBroadcastReceiver: %1$s", broadcastReceiverAlreadyRegistered); if (! broadcastReceiverAlreadyRegistered) { IntentFilter filter = new IntentFilter(); filter.addAction(WalkersGuideService.ACTION_START_SERVICE_FAILED); filter.addAction(WalkersGuideService.ACTION_SERVICE_STATE_CHANGED); - filter.addAction(PositionManager.ACTION_NEW_LOCATION); + filter.addAction(WalkersGuideService.ACTION_SHOW_ROUTE_RECORDING_ONLY_IN_FOREGROUND_MESSAGE); + // + filter.addAction(DeviceSensorManager.ACTION_BEARING_SENSOR_CHANGED); + filter.addAction(DeviceSensorManager.ACTION_SIMULATION_STATUS_CHANGED); + filter.addAction(DeviceSensorManager.ACTION_NEW_BEARING_VALUE_FROM_SIMULATION); filter.addAction(DeviceSensorManager.ACTION_NEW_BEARING); + // + filter.addAction(PositionManager.ACTION_SIMULATION_STATUS_CHANGED); + filter.addAction(PositionManager.ACTION_NEW_SIMULATED_LOCATION); + filter.addAction(PositionManager.ACTION_NEW_LOCATION); LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, filter); broadcastReceiverAlreadyRegistered = true; } @@ -677,11 +809,28 @@ private void registerBroadcastReceiver() { break; } + } else if (intent.getAction().equals(WalkersGuideService.ACTION_SHOW_ROUTE_RECORDING_ONLY_IN_FOREGROUND_MESSAGE)) { + SimpleMessageDialog.newInstance( + getResources().getString(R.string.messageNoteRouteRecordingOnlyInForeground)) + .show(getSupportFragmentManager(), "SimpleMessageDialog"); + + } else if (intent.getAction().equals(DeviceSensorManager.ACTION_BEARING_SENSOR_CHANGED) + || intent.getAction().equals(DeviceSensorManager.ACTION_SIMULATION_STATUS_CHANGED) + || intent.getAction().equals(DeviceSensorManager.ACTION_NEW_BEARING_VALUE_FROM_SIMULATION)) { + updateAccessibilityActionsOnBearingDetailsButton(); + } else if (intent.getAction().equals(PositionManager.ACTION_SIMULATION_STATUS_CHANGED) + || intent.getAction().equals(PositionManager.ACTION_NEW_SIMULATED_LOCATION)) { + updateAccessibilityActionsOnLocationDetailsButton(); + } else if (drawerLayout != null && ! drawerLayout.isOpen()) { if (intent.getAction().equals(DeviceSensorManager.ACTION_NEW_BEARING)) { updateBearingDetailsButton(); + ViewCompat.setAccessibilityLiveRegion( + buttonBearingDetails, ViewCompat.ACCESSIBILITY_LIVE_REGION_NONE); } else if (intent.getAction().equals(PositionManager.ACTION_NEW_LOCATION)) { updateLocationDetailsButton(); + ViewCompat.setAccessibilityLiveRegion( + buttonLocationDetails, ViewCompat.ACCESSIBILITY_LIVE_REGION_NONE); } } } @@ -894,7 +1043,7 @@ private Pair,Boolean> unpackAndClearTabLayoutTag() { // MainActivityController - @Override public void openPlanRouteDialog() { + @Override public void openPlanRouteDialog(boolean startRouteCalculationImmediately) { // close, if already open List fragments = getSupportFragmentManager().getFragments(); if (fragments != null) { @@ -905,7 +1054,7 @@ private Pair,Boolean> unpackAndClearTabLayoutTag() { } } // open on top - PlanRouteDialog.newInstance() + PlanRouteDialog.newInstance(startRouteCalculationImmediately) .show(getSupportFragmentManager(), "PlanRouteDialog"); } diff --git a/app/src/main/java/org/walkersguide/android/ui/activity/MainActivityController.java b/app/src/main/java/org/walkersguide/android/ui/activity/MainActivityController.java index 3d6271d..02198e4 100644 --- a/app/src/main/java/org/walkersguide/android/ui/activity/MainActivityController.java +++ b/app/src/main/java/org/walkersguide/android/ui/activity/MainActivityController.java @@ -9,7 +9,7 @@ public interface MainActivityController { public void configureToolbarTitle(String title); public void displayRemainsActiveSettingChanged(boolean remainsActive); - public void openPlanRouteDialog(); + public void openPlanRouteDialog(boolean startRouteCalculationImmediately); public FragmentManager getFragmentManagerInstance(); public void closeAllOpenDialogs(); diff --git a/app/src/main/java/org/walkersguide/android/ui/adapter/AnnouncementRadiusAdapter.java b/app/src/main/java/org/walkersguide/android/ui/adapter/AnnouncementRadiusAdapter.java new file mode 100644 index 0000000..3cea7a2 --- /dev/null +++ b/app/src/main/java/org/walkersguide/android/ui/adapter/AnnouncementRadiusAdapter.java @@ -0,0 +1,102 @@ +package org.walkersguide.android.ui.adapter; + +import org.walkersguide.android.R; +import org.walkersguide.android.ui.view.ProfileView; +import org.walkersguide.android.ui.view.ProfileView.OnProfileDefaultActionListener; + +import android.widget.LinearLayout; +import android.widget.LinearLayout.LayoutParams; + + + +import android.view.View; +import android.view.ViewGroup; + + +import java.util.ArrayList; +import android.content.Context; +import android.widget.BaseAdapter; +import org.walkersguide.android.data.Profile; +import org.walkersguide.android.data.profile.AnnouncementRadius; +import android.widget.ArrayAdapter; +import android.view.LayoutInflater; +import android.widget.CheckedTextView; +import java.lang.Class; + + +public class AnnouncementRadiusAdapter extends ArrayAdapter { + private static ArrayList announcementRadiusList = AnnouncementRadius.values(); + + private Context context; + private LayoutInflater m_inflater; + + public AnnouncementRadiusAdapter(Context context) { + super(context, R.layout.layout_single_text_view_checkbox); + this.context = context; + this.m_inflater = LayoutInflater.from(context); + } + + @Override public View getView(int position, View convertView, ViewGroup parent) { + return populateView(position, convertView, parent, false); + } + + @Override public View getDropDownView(int position, View convertView,ViewGroup parent) { + return populateView(position, convertView, parent, true); + } + + private View populateView(int position, View convertView, ViewGroup parent, boolean isDropDown) { + // load item layout + EntryHolder holder; + if (convertView == null) { + LayoutInflater m_inflater = LayoutInflater.from(context); + convertView = m_inflater.inflate(R.layout.layout_single_text_view_checkbox, parent, false); + // find view + holder = new EntryHolder(); + holder.labelRadius = (CheckedTextView) convertView.findViewById(R.id.label); + convertView.setTag(holder); + } else { + holder = (EntryHolder) convertView.getTag(); + } + + final AnnouncementRadius radius = getItem(position); + + if (isDropDown) { + holder.labelRadius.setCheckMarkDrawable(android.R.drawable.btn_radio); + holder.labelRadius.setText(radius.longFormat()); + holder.labelRadius.setContentDescription(null); + } else { + holder.labelRadius.setCheckMarkDrawable(null); + holder.labelRadius.setText(radius.shortFormat()); + holder.labelRadius.setContentDescription(radius.longFormat()); + } + + return convertView; + } + + @Override public int getCount() { + return this.announcementRadiusList.size(); + } + + @Override public AnnouncementRadius getItem(int position) { + return this.announcementRadiusList.get(position); + } + + @Override public long getItemId(int position) { + return position; + } + + public int getIndexOf(AnnouncementRadius radius) { + int index = this.announcementRadiusList.indexOf(radius); + if (index == -1) { + index = 0; + } + return index; + } + + + private class EntryHolder { + public CheckedTextView labelRadius; + } + + +} diff --git a/app/src/main/java/org/walkersguide/android/ui/dialog/InfoDialog.java b/app/src/main/java/org/walkersguide/android/ui/dialog/InfoDialog.java index b9eb60f..c5305e5 100644 --- a/app/src/main/java/org/walkersguide/android/ui/dialog/InfoDialog.java +++ b/app/src/main/java/org/walkersguide/android/ui/dialog/InfoDialog.java @@ -162,6 +162,11 @@ public void onClick(View view) { labelSelectedMapName = (TextView) view.findViewById(R.id.labelSelectedMapName); labelSelectedMapCreated= (TextView) view.findViewById(R.id.labelSelectedMapCreated); + TextView labelPublicTransportMessage = (TextView) view.findViewById(R.id.labelPublicTransportMessage); + labelPublicTransportMessage.setMovementMethod(LinkMovementMethod.getInstance()); + labelPublicTransportMessage.setText( + UiHelper.getPublicTransportDataSourceText()); + return new AlertDialog.Builder(getActivity()) .setTitle(GlobalInstance.getStringResource(R.string.infoDialogTitle)) .setView(view) diff --git a/app/src/main/java/org/walkersguide/android/ui/dialog/PlanRouteDialog.java b/app/src/main/java/org/walkersguide/android/ui/dialog/PlanRouteDialog.java index 025f631..ba4bb21 100644 --- a/app/src/main/java/org/walkersguide/android/ui/dialog/PlanRouteDialog.java +++ b/app/src/main/java/org/walkersguide/android/ui/dialog/PlanRouteDialog.java @@ -81,10 +81,24 @@ public class PlanRouteDialog extends DialogFragment implements FragmentResultLis private ObjectWithIdView layoutViaPoint1, layoutViaPoint2, layoutViaPoint3; public static PlanRouteDialog newInstance() { + return PlanRouteDialog.newInstance(false); + } + + public static PlanRouteDialog newInstance(boolean startRouteCalculationImmediately) { PlanRouteDialog dialog = new PlanRouteDialog(); + Bundle args = new Bundle(); + args.putBoolean(KEY_START_ROUTE_CALCULATION_IMMEDIATELY, startRouteCalculationImmediately); + dialog.setArguments(args); return dialog; } + + // dialog + private static final String KEY_START_ROUTE_CALCULATION_IMMEDIATELY = "startRouteCalculationImmediately"; + private static final String KEY_TRIED_TO_START_ROUTE_CALCULATION_IMMEDIATELY = "triedToStartRouteCalculationImmediately"; + + private boolean triedToStartRouteCalculationImmediately; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); serverTaskExecutorInstance = ServerTaskExecutor.getInstance(); @@ -94,9 +108,6 @@ public static PlanRouteDialog newInstance() { this.progressUpdater = new ProgressUpdater(); // fragment result listener - getChildFragmentManager() - .setFragmentResultListener( - ConfigureWayClassWeightsDialog.REQUEST_WAY_CLASS_WEIGHTS_CHANGED, this, this); getChildFragmentManager() .setFragmentResultListener( SelectMapDialog.REQUEST_SELECT_MAP, this, this); @@ -107,11 +118,7 @@ public static PlanRouteDialog newInstance() { @Override public void onFragmentResult(@NonNull String requestKey, @NonNull Bundle bundle) { Timber.d("onFragmentResult: %1$s", requestKey); - if (requestKey.equals(ConfigureWayClassWeightsDialog.REQUEST_WAY_CLASS_WEIGHTS_CHANGED)) { - settingsManagerInstance.setWayClassWeightSettings( - (WayClassWeightSettings) bundle.getSerializable(ConfigureWayClassWeightsDialog.EXTRA_WAY_CLASS_SETTINGS)); - - } else if (requestKey.equals(SelectMapDialog.REQUEST_SELECT_MAP)) { + if (requestKey.equals(SelectMapDialog.REQUEST_SELECT_MAP)) { settingsManagerInstance.setSelectedMap( (OSMMap) bundle.getSerializable(SelectMapDialog.EXTRA_MAP)); startRouteCalculation(); @@ -149,8 +156,10 @@ public static PlanRouteDialog newInstance() { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { if (savedInstanceState != null) { taskId = savedInstanceState.getLong(KEY_TASK_ID); + triedToStartRouteCalculationImmediately = savedInstanceState.getBoolean(KEY_TRIED_TO_START_ROUTE_CALCULATION_IMMEDIATELY); } else { taskId = ServerTaskExecutor.NO_TASK_ID; + triedToStartRouteCalculationImmediately = false; } // custom view @@ -306,6 +315,17 @@ public void onClick(DialogInterface dialog, int which) { filter.addAction(ServerTaskExecutor.ACTION_SERVER_TASK_FAILED); LocalBroadcastManager.getInstance(GlobalInstance.getContext()).registerReceiver(mMessageReceiver, filter); + // start calculation immediately + if (! triedToStartRouteCalculationImmediately + && getArguments().getBoolean(KEY_START_ROUTE_CALCULATION_IMMEDIATELY)) { + triedToStartRouteCalculationImmediately = true; + // cancel old running task and start calculation + if (serverTaskExecutorInstance.taskInProgress(taskId)) { + serverTaskExecutorInstance.cancelTask(taskId, true); + } + startRouteCalculation(); + } + if (serverTaskExecutorInstance.taskInProgress(taskId)) { progressHandler.postDelayed(progressUpdater, 2000); } @@ -322,6 +342,7 @@ public void onClick(DialogInterface dialog, int which) { @Override public void onSaveInstanceState(Bundle savedInstanceState) { super.onSaveInstanceState(savedInstanceState); savedInstanceState.putLong(KEY_TASK_ID, taskId); + savedInstanceState.putBoolean(KEY_TRIED_TO_START_ROUTE_CALCULATION_IMMEDIATELY, triedToStartRouteCalculationImmediately); } @Override public void onDestroy() { @@ -429,18 +450,22 @@ public void run() { private void showOptionsMenu(View view) { PopupMenu optionsMenu = new PopupMenu(getActivity(), view); optionsMenu.getMenu().add( - Menu.NONE, MENU_ITEM_SWAP, 1, GlobalInstance.getStringResource(R.string.planRouteMenuItemSwap)); + Menu.NONE, MENU_ITEM_CLEAR, 1, GlobalInstance.getStringResource(R.string.planRouteMenuItemClear)); optionsMenu.getMenu().add( - Menu.NONE, MENU_ITEM_EXCLUDED_WAYS, 1, GlobalInstance.getStringResource(R.string.planRouteMenuItemExcludedWays)); + Menu.NONE, MENU_ITEM_SWAP, 2, GlobalInstance.getStringResource(R.string.planRouteMenuItemSwap)); optionsMenu.getMenu().add( - Menu.NONE, MENU_ITEM_ROUTING_WAY_CLASSES, 1, GlobalInstance.getStringResource(R.string.planRouteMenuItemRoutingWayClasses)); + Menu.NONE, MENU_ITEM_EXCLUDED_WAYS, 3, GlobalInstance.getStringResource(R.string.planRouteMenuItemExcludedWays)); optionsMenu.getMenu().add( - Menu.NONE, MENU_ITEM_CLEAR, 2, GlobalInstance.getStringResource(R.string.planRouteMenuItemClear)); + Menu.NONE, MENU_ITEM_ROUTING_WAY_CLASSES, 4, GlobalInstance.getStringResource(R.string.planRouteMenuItemRoutingWayClasses)); optionsMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { - if (item.getItemId() == MENU_ITEM_SWAP) { + if (item.getItemId() == MENU_ITEM_CLEAR) { + settingsManagerInstance.setP2pRouteRequest(P2pRouteRequest.getDefault()); + updateUI(); + + } else if (item.getItemId() == MENU_ITEM_SWAP) { P2pRouteRequest p2pRouteRequest = settingsManagerInstance.getP2pRouteRequest(); p2pRouteRequest.swapStartAndDestinationPoints(); settingsManagerInstance.setP2pRouteRequest(p2pRouteRequest); @@ -448,17 +473,12 @@ private void showOptionsMenu(View view) { } else if (item.getItemId() == MENU_ITEM_EXCLUDED_WAYS) { ObjectListFromDatabaseFragment.newInstance(StaticProfile.excludedRoutingSegments()) - .show(getChildFragmentManager(), "ConfigureWayClassWeightsDialog"); + .show(getChildFragmentManager(), "excludedRoutingSegments"); } else if (item.getItemId() == MENU_ITEM_ROUTING_WAY_CLASSES) { - ConfigureWayClassWeightsDialog.newInstance( - settingsManagerInstance.getWayClassWeightSettings()) + ConfigureWayClassWeightsDialog.newInstance() .show(getChildFragmentManager(), "ConfigureWayClassWeightsDialog"); - } else if (item.getItemId() == MENU_ITEM_CLEAR) { - settingsManagerInstance.setP2pRouteRequest(P2pRouteRequest.getDefault()); - updateUI(); - } else { return false; } diff --git a/app/src/main/java/org/walkersguide/android/ui/dialog/SimpleMessageDialog.java b/app/src/main/java/org/walkersguide/android/ui/dialog/SimpleMessageDialog.java index d10a40a..7e03316 100644 --- a/app/src/main/java/org/walkersguide/android/ui/dialog/SimpleMessageDialog.java +++ b/app/src/main/java/org/walkersguide/android/ui/dialog/SimpleMessageDialog.java @@ -20,6 +20,7 @@ import android.content.Intent; import android.provider.Settings; import android.net.Uri; +import org.walkersguide.android.ui.UiHelper; public class SimpleMessageDialog extends DialogFragment { public static final String REQUEST_DIALOG_CLOSED = "dialogClosed"; @@ -46,10 +47,19 @@ public static SimpleMessageDialog newInstanceWithAppInfoButton(String message) { return dialog; } + public static SimpleMessageDialog newInstanceWithPublicTransportDataSourceText() { + SimpleMessageDialog dialog = new SimpleMessageDialog(); + Bundle args = new Bundle(); + args.putBoolean(KEY_PUBLIC_TRANSPORT_DATA_SOURCE_TEXT, true); + dialog.setArguments(args); + return dialog; + } + // dialog private static final String KEY_MESSAGE = "message"; private static final String KEY_SHOW_APP_INFO_BUTTON = "showAppInfoButton"; + private static final String KEY_PUBLIC_TRANSPORT_DATA_SOURCE_TEXT = "publicTransportDataSourceText"; @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final ViewGroup nullParent = null; @@ -57,7 +67,9 @@ public static SimpleMessageDialog newInstanceWithAppInfoButton(String message) { View view = inflater.inflate(R.layout.layout_single_text_view, nullParent); TextView labelSimpleMessage = (TextView) view.findViewById(R.id.label); labelSimpleMessage.setText( - getArguments().getString(KEY_MESSAGE)); + getArguments().getBoolean(KEY_PUBLIC_TRANSPORT_DATA_SOURCE_TEXT) + ? UiHelper.getPublicTransportDataSourceText() + : getArguments().getString(KEY_MESSAGE)); AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity()) .setView(view) diff --git a/app/src/main/java/org/walkersguide/android/ui/dialog/create/PointFromCoordinatesLinkDialog.java b/app/src/main/java/org/walkersguide/android/ui/dialog/create/PointFromCoordinatesLinkDialog.java index b81e4f3..828b72b 100644 --- a/app/src/main/java/org/walkersguide/android/ui/dialog/create/PointFromCoordinatesLinkDialog.java +++ b/app/src/main/java/org/walkersguide/android/ui/dialog/create/PointFromCoordinatesLinkDialog.java @@ -331,10 +331,10 @@ private void createPointAndDismissDialogOrShowErrorMessage(double latitude, doub } catch (JSONException e) {} if (extractedCoordinates != null && HistoryProfile.allPoints().addObject(extractedCoordinates)) { + dismiss(); Bundle result = new Bundle(); result.putSerializable(EXTRA_COORDINATES, extractedCoordinates); getParentFragmentManager().setFragmentResult(REQUEST_FROM_COORDINATES_LINK, result); - dismiss(); } else { showErrorMessage( getResources().getString(R.string.messageLinkContainsInvalidCoordinates)); diff --git a/app/src/main/java/org/walkersguide/android/ui/dialog/edit/ConfigureWayClassWeightsDialog.java b/app/src/main/java/org/walkersguide/android/ui/dialog/edit/ConfigureWayClassWeightsDialog.java index 80f09f1..dd93410 100644 --- a/app/src/main/java/org/walkersguide/android/ui/dialog/edit/ConfigureWayClassWeightsDialog.java +++ b/app/src/main/java/org/walkersguide/android/ui/dialog/edit/ConfigureWayClassWeightsDialog.java @@ -1,6 +1,7 @@ package org.walkersguide.android.ui.dialog.edit; import org.walkersguide.android.server.wg.p2p.WayClassWeightSettings; +import org.walkersguide.android.server.wg.p2p.WayClassWeightSettings.Preset; import org.walkersguide.android.server.wg.p2p.wayclass.WayClassType; import org.walkersguide.android.server.wg.p2p.wayclass.WayClassWeight; @@ -30,6 +31,11 @@ import org.walkersguide.android.ui.view.builder.TextViewBuilder; import android.widget.TableRow; import android.widget.AdapterView; +import androidx.appcompat.widget.PopupMenu; +import android.view.Menu; +import org.walkersguide.android.util.GlobalInstance; +import android.view.MenuItem; +import org.walkersguide.android.util.SettingsManager; public class ConfigureWayClassWeightsDialog extends DialogFragment @@ -40,11 +46,8 @@ public class ConfigureWayClassWeightsDialog extends DialogFragment // instance constructors - public static ConfigureWayClassWeightsDialog newInstance(WayClassWeightSettings wayClassWeightSettings) { + public static ConfigureWayClassWeightsDialog newInstance() { ConfigureWayClassWeightsDialog dialog = new ConfigureWayClassWeightsDialog(); - Bundle args = new Bundle(); - args.putSerializable(KEY_WAY_CLASS_SETTINGS, wayClassWeightSettings); - dialog.setArguments(args); return dialog; } @@ -56,11 +59,9 @@ public static ConfigureWayClassWeightsDialog newInstance(WayClassWeightSettings private TableLayout tableLayout; @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - if (savedInstanceState != null) { - wayClassWeightSettings = (WayClassWeightSettings) savedInstanceState.getSerializable(KEY_WAY_CLASS_SETTINGS); - } else { - wayClassWeightSettings = (WayClassWeightSettings) getArguments().getSerializable(KEY_WAY_CLASS_SETTINGS); - } + wayClassWeightSettings = savedInstanceState != null + ? (WayClassWeightSettings) savedInstanceState.getSerializable(KEY_WAY_CLASS_SETTINGS) + : SettingsManager.getInstance().getWayClassWeightSettings(); tableLayout = new TableLayout( ConfigureWayClassWeightsDialog.this.getContext()); @@ -87,7 +88,7 @@ public void onClick(DialogInterface dialog, int which) { } }) .setNeutralButton( - getResources().getString(R.string.dialogDefault), + getResources().getString(R.string.dialogPresets), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { } @@ -110,6 +111,7 @@ public void onClick(DialogInterface dialog, int which) { Button buttonPositive = dialog.getButton(AlertDialog.BUTTON_POSITIVE); buttonPositive.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + SettingsManager.getInstance().setWayClassWeightSettings(wayClassWeightSettings); Bundle result = new Bundle(); result.putSerializable(EXTRA_WAY_CLASS_SETTINGS, wayClassWeightSettings); getParentFragmentManager().setFragmentResult(REQUEST_WAY_CLASS_WEIGHTS_CHANGED, result); @@ -121,8 +123,7 @@ public void onClick(DialogInterface dialog, int which) { Button buttonNeutral = dialog.getButton(AlertDialog.BUTTON_NEUTRAL); buttonNeutral.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - wayClassWeightSettings = WayClassWeightSettings.getDefault(); - populateTableLayout(); + showPresetsMenu(view); } }); @@ -151,7 +152,7 @@ private void populateTableLayout() { spinner.setId(type.ordinal()); spinner.setLayoutParams(lpTableRowChild); spinner.setTag(type); - spinner.setPrompt(type.name); + spinner.setPrompt(type.toString()); spinner.setOnItemSelectedListener(this); ArrayList wayClassWeightList = @@ -172,7 +173,7 @@ private void populateTableLayout() { TextView label = new TextViewBuilder( ConfigureWayClassWeightsDialog.this.getContext(), - type.name, + type.toString(), lpTableRowChild) .setId(WayClassType.values().length + spinner.getId() + 1) .isLabelFor(spinner.getId()) @@ -204,4 +205,46 @@ private void populateTableLayout() { @Override public void onNothingSelected(AdapterView parent) { } + + + // presets menu + + private void showPresetsMenu(View view) { + PopupMenu optionsMenu = new PopupMenu(getActivity(), view); + + final int MENU_GROUP_PRESET = 1; + int order = 0; + for (Preset preset : Preset.values()) { + optionsMenu.getMenu().add( + MENU_GROUP_PRESET, preset.id, order++, preset.toString()); + } + optionsMenu.getMenu().setGroupCheckable(MENU_GROUP_PRESET, true, true); + + Preset matchingPreset = Preset.matches(wayClassWeightSettings); + if (matchingPreset != null) { + MenuItem matchingPresetMenuItem = optionsMenu.getMenu().findItem(matchingPreset.id); + if (matchingPresetMenuItem != null) { + matchingPresetMenuItem.setChecked(true); + } + } + + optionsMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override public boolean onMenuItemClick(MenuItem item) { + if (item.getItemId() == Preset.URBAN_ON_FOOT.id) { + wayClassWeightSettings = Preset.URBAN_ON_FOOT.settings; + } else if (item.getItemId() == Preset.URBAN_BY_CAR.id) { + wayClassWeightSettings = Preset.URBAN_BY_CAR.settings; + } else if (item.getItemId() == Preset.HIKING.id) { + wayClassWeightSettings = Preset.HIKING.settings; + } else { + return false; + } + populateTableLayout(); + return true; + } + }); + + optionsMenu.show(); + } + } diff --git a/app/src/main/java/org/walkersguide/android/ui/dialog/select/SelectMapDialog.java b/app/src/main/java/org/walkersguide/android/ui/dialog/select/SelectMapDialog.java index e3a53c8..10853b6 100644 --- a/app/src/main/java/org/walkersguide/android/ui/dialog/select/SelectMapDialog.java +++ b/app/src/main/java/org/walkersguide/android/ui/dialog/select/SelectMapDialog.java @@ -23,7 +23,6 @@ import org.walkersguide.android.server.wg.status.OSMMap; import org.walkersguide.android.server.wg.status.ServerInstance; import org.walkersguide.android.R; -import org.walkersguide.android.ui.dialog.SendFeedbackDialog; import org.walkersguide.android.ui.dialog.SimpleMessageDialog; @@ -83,17 +82,6 @@ public void onClick(DialogInterface dialog, int which) { } } ) - .setNeutralButton( - getResources().getString(R.string.dialogSomethingMissing), - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - SendFeedbackDialog.newInstance( - SendFeedbackDialog.FeedbackToken.MAP_REQUEST) - .show(getParentFragmentManager(), "SendFeedbackDialog"); - dismiss(); - } - } - ) .setNegativeButton( getResources().getString(R.string.dialogCancel), new DialogInterface.OnClickListener() { diff --git a/app/src/main/java/org/walkersguide/android/ui/dialog/select/SelectPublicTransportProviderDialog.java b/app/src/main/java/org/walkersguide/android/ui/dialog/select/SelectPublicTransportProviderDialog.java index ac2b711..60cc6c1 100644 --- a/app/src/main/java/org/walkersguide/android/ui/dialog/select/SelectPublicTransportProviderDialog.java +++ b/app/src/main/java/org/walkersguide/android/ui/dialog/select/SelectPublicTransportProviderDialog.java @@ -1,7 +1,6 @@ package org.walkersguide.android.ui.dialog.select; - - +import org.walkersguide.android.BuildConfig; import de.schildbach.pte.AbstractNetworkProvider; import androidx.appcompat.app.AlertDialog; import android.app.Dialog; @@ -31,9 +30,9 @@ import java.util.ArrayList; import android.widget.ListView; import android.widget.CheckedTextView; -import org.walkersguide.android.ui.dialog.SendFeedbackDialog; import de.schildbach.pte.NetworkId; import java.util.Locale; +import org.walkersguide.android.ui.dialog.SimpleMessageDialog; public class SelectPublicTransportProviderDialog extends DialogFragment { @@ -120,9 +119,8 @@ public void onClick(DialogInterface dialog, int which) { Button buttonNeutral = dialog.getButton(AlertDialog.BUTTON_NEUTRAL); buttonNeutral.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - SendFeedbackDialog.newInstance( - SendFeedbackDialog.FeedbackToken.PT_PROVIDER_REQUEST) - .show(getChildFragmentManager(), "SendFeedbackDialog"); + SimpleMessageDialog.newInstanceWithPublicTransportDataSourceText() + .show(getChildFragmentManager(), "SimpleMessageDialog"); } }); // negative button diff --git a/app/src/main/java/org/walkersguide/android/ui/dialog/toolbar/BearingDetailsDialog.java b/app/src/main/java/org/walkersguide/android/ui/dialog/toolbar/BearingDetailsDialog.java index 357feac..c11f0ce 100644 --- a/app/src/main/java/org/walkersguide/android/ui/dialog/toolbar/BearingDetailsDialog.java +++ b/app/src/main/java/org/walkersguide/android/ui/dialog/toolbar/BearingDetailsDialog.java @@ -88,7 +88,12 @@ public static BearingDetailsDialog newInstance() { switchAutoSwitchBearingSource.setChecked(settingsManagerInstance.getAutoSwitchBearingSourceEnabled()); switchAutoSwitchBearingSource.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton view, boolean isChecked) { - settingsManagerInstance.setAutoSwitchBearingSourceEnabled(isChecked); + if (settingsManagerInstance.getAutoSwitchBearingSourceEnabled() != isChecked) { + settingsManagerInstance.setAutoSwitchBearingSourceEnabled(isChecked); + // next is required to trigger the ACTION_BEARING_SENSOR_CHANGED broadcast + // see the function MainActivity.updateAccessibilityActionsOnBearingDetailsButton() + deviceSensorManagerInstance.broadcastBearingSensorChanged(); + } } }); @@ -234,6 +239,7 @@ private int getSimulatedBearingInDegree() { filter.addAction(DeviceSensorManager.ACTION_BEARING_SENSOR_CHANGED); filter.addAction(DeviceSensorManager.ACTION_NEW_BEARING_VALUE_FROM_COMPASS); filter.addAction(DeviceSensorManager.ACTION_NEW_BEARING_VALUE_FROM_SATELLITE); + filter.addAction(DeviceSensorManager.ACTION_SIMULATION_STATUS_CHANGED); LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mMessageReceiver, filter); // request directions deviceSensorManagerInstance.requestBearingValueFromCompass(); @@ -338,6 +344,10 @@ private void checkBearingSensorRadioButtons() { labelSatelliteDetails.setText( context.getResources().getString(R.string.errorNoBearingFound)); } + + } else if (intent.getAction().equals(DeviceSensorManager.ACTION_SIMULATION_STATUS_CHANGED)) { + buttonEnableSimulation.setChecked( + intent.getBooleanExtra(DeviceSensorManager.EXTRA_SIMULATION_ENABLED, false)); } } }; diff --git a/app/src/main/java/org/walkersguide/android/ui/dialog/toolbar/LocationDetailsDialog.java b/app/src/main/java/org/walkersguide/android/ui/dialog/toolbar/LocationDetailsDialog.java index 02e38f6..49ed5aa 100644 --- a/app/src/main/java/org/walkersguide/android/ui/dialog/toolbar/LocationDetailsDialog.java +++ b/app/src/main/java/org/walkersguide/android/ui/dialog/toolbar/LocationDetailsDialog.java @@ -144,6 +144,11 @@ public void onCheckedChanged(CompoundButton view, boolean isChecked) { .show(getChildFragmentManager(), "SelectObjectWithIdFromMultipleSourcesDialog"); } }); + layoutSimulationPoint.setOnRemoveObjectActionListener(new ObjectWithIdView.OnRemoveObjectActionListener() { + @Override public void onRemoveObjectActionClicked(ObjectWithId objectWithId) { + positionManagerInstance.setSimulatedLocation(null); + } + }); // create dialog return new AlertDialog.Builder(getActivity()) @@ -187,6 +192,7 @@ public void onClick(DialogInterface dialog, int which) { IntentFilter filter = new IntentFilter(); filter.addAction(PositionManager.ACTION_NEW_GPS_LOCATION); + filter.addAction(PositionManager.ACTION_SIMULATION_STATUS_CHANGED); LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mMessageReceiver, filter); // request location positionManagerInstance.requestGPSLocation(); @@ -224,6 +230,10 @@ private void updateSimulationPoint() { gpsLocation.formatTimestamp( GlobalInstance.getStringResource(R.string.labelGPSTime))); } + + } else if (intent.getAction().equals(PositionManager.ACTION_SIMULATION_STATUS_CHANGED)) { + buttonEnableSimulation.setChecked( + intent.getBooleanExtra(PositionManager.EXTRA_SIMULATION_ENABLED, false)); } } }; diff --git a/app/src/main/java/org/walkersguide/android/ui/fragment/SettingsFragment.java b/app/src/main/java/org/walkersguide/android/ui/fragment/SettingsFragment.java index 1d67f28..1210af3 100644 --- a/app/src/main/java/org/walkersguide/android/ui/fragment/SettingsFragment.java +++ b/app/src/main/java/org/walkersguide/android/ui/fragment/SettingsFragment.java @@ -98,6 +98,11 @@ import org.walkersguide.android.database.profile.static_profile.HistoryProfile; import androidx.fragment.app.DialogFragment; import org.walkersguide.android.sensor.PositionManager; +import org.walkersguide.android.ui.dialog.edit.ConfigureWayClassWeightsDialog; +import org.walkersguide.android.server.wg.p2p.WayClassWeightSettings; +import org.walkersguide.android.server.wg.p2p.WayClassWeightSettings.Preset; +import org.walkersguide.android.ui.fragment.object_list.extended.ObjectListFromDatabaseFragment; +import org.walkersguide.android.database.profile.StaticProfile; public class SettingsFragment extends RootFragment implements FragmentResultListener { @@ -116,7 +121,7 @@ public static SettingsFragment newInstance() { private boolean settingsImportSuccessful; private ObjectWithIdView layoutHomeAddress; - private Button buttonServerURL, buttonServerMap; + private Button buttonServerURL, buttonServerMap, buttonRoutingWayClasses; private SwitchCompat switchPreferTranslatedStrings; private Button buttonPublicTransportProvider; private Button buttonShakeIntensity; @@ -146,6 +151,9 @@ public static SettingsFragment newInstance() { getChildFragmentManager() .setFragmentResultListener( SelectMapDialog.REQUEST_SELECT_MAP, this, this); + getChildFragmentManager() + .setFragmentResultListener( + ConfigureWayClassWeightsDialog.REQUEST_WAY_CLASS_WEIGHTS_CHANGED, this, this); getChildFragmentManager() .setFragmentResultListener( SelectPublicTransportProviderDialog.REQUEST_SELECT_PT_PROVIDER, this, this); @@ -193,6 +201,9 @@ public static SettingsFragment newInstance() { (OSMMap) bundle.getSerializable(SelectMapDialog.EXTRA_MAP)); updateUI(); + } else if (requestKey.equals(ConfigureWayClassWeightsDialog.REQUEST_WAY_CLASS_WEIGHTS_CHANGED)) { + updateUI(); + } else if (requestKey.equals(SelectPublicTransportProviderDialog.REQUEST_SELECT_PT_PROVIDER)) { settingsManagerInstance.setSelectedNetworkId( (NetworkId) bundle.getSerializable(SelectPublicTransportProviderDialog.EXTRA_NETWORK_ID)); @@ -270,6 +281,22 @@ public void onClick(View view) { } }); + buttonRoutingWayClasses = (Button) view.findViewById(R.id.buttonRoutingWayClasses); + buttonRoutingWayClasses.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + ConfigureWayClassWeightsDialog.newInstance() + .show(getChildFragmentManager(), "ConfigureWayClassWeightsDialog"); + } + }); + + Button buttonExcludedWays = (Button) view.findViewById(R.id.buttonExcludedWays); + buttonExcludedWays.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + ObjectListFromDatabaseFragment.newInstance(StaticProfile.excludedRoutingSegments()) + .show(getChildFragmentManager(), "excludedRoutingSegments"); + } + }); + switchPreferTranslatedStrings = (SwitchCompat) view.findViewById(R.id.switchPreferTranslatedStrings); switchPreferTranslatedStrings.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton view, boolean isChecked) { @@ -455,6 +482,16 @@ private void updateUI() { switchPreferTranslatedStrings.setChecked(settingsManagerInstance.getPreferTranslatedStrings()); + Preset matchingWcwsPreset = Preset.matches(settingsManagerInstance.getWayClassWeightSettings()); + buttonRoutingWayClasses.setText( + String.format( + "%1$s: %2$s", + getResources().getString(R.string.planRouteMenuItemRoutingWayClasses), + matchingWcwsPreset != null + ? matchingWcwsPreset.toString() + : getResources().getString(R.string.fillingWordCustom)) + ); + // public transport provider if (settingsManagerInstance.getSelectedNetworkId() != null) { buttonPublicTransportProvider.setText( diff --git a/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/ObjectDetailsTabLayoutFragment.java b/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/ObjectDetailsTabLayoutFragment.java index a7d9f3d..aa9688e 100644 --- a/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/ObjectDetailsTabLayoutFragment.java +++ b/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/ObjectDetailsTabLayoutFragment.java @@ -1,5 +1,6 @@ package org.walkersguide.android.ui.fragment.tabs; +import androidx.core.view.MenuProvider; import org.walkersguide.android.tts.TTSWrapper; import org.walkersguide.android.database.profile.static_profile.HistoryProfile; import org.walkersguide.android.sensor.DeviceSensorManager; @@ -61,9 +62,15 @@ import android.text.TextUtils; import org.walkersguide.android.ui.UiHelper; import androidx.annotation.Nullable; +import androidx.annotation.NonNull; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import androidx.lifecycle.Lifecycle; +import org.walkersguide.android.util.SettingsManager; -public class ObjectDetailsTabLayoutFragment extends TabLayoutFragment { +public class ObjectDetailsTabLayoutFragment extends TabLayoutFragment implements MenuProvider { private static final String KEY_OBJECT = "object"; public static ObjectDetailsTabLayoutFragment details(ObjectWithId object) { @@ -110,6 +117,14 @@ private static ObjectDetailsTabLayoutFragment newInstance(ObjectWithId object, T } + private SettingsManager settingsManagerInstance; + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + settingsManagerInstance = SettingsManager.getInstance(); + } + + /** * layout */ @@ -124,6 +139,7 @@ private static ObjectDetailsTabLayoutFragment newInstance(ObjectWithId object, T @Override public View configureView(View view, Bundle savedInstanceState) { view = super.configureView(view, savedInstanceState); + requireActivity().addMenuProvider(this, getViewLifecycleOwner(), Lifecycle.State.RESUMED); // load object object = (ObjectWithId) getArguments().getSerializable(KEY_OBJECT); @@ -177,6 +193,39 @@ private static ObjectDetailsTabLayoutFragment newInstance(ObjectWithId object, T } + /** + * menu + */ + + @Override public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) { + menuInflater.inflate(R.menu.menu_toolbar_object_details_tab_layout_fragment, menu); + } + + @Override public void onPrepareMenu(@NonNull Menu menu) { + MenuItem menuItemShowPreciseBearingValues = menu.findItem(R.id.menuItemShowPreciseBearingValues); + if (menuItemShowPreciseBearingValues != null) { + menuItemShowPreciseBearingValues.setChecked( + settingsManagerInstance.getShowPreciseBearingValues()); + menuItemShowPreciseBearingValues.setVisible( + object instanceof Point); + } + } + + @Override public boolean onMenuItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.menuItemShowPreciseBearingValues) { + settingsManagerInstance.setShowPreciseBearingValues( + ! settingsManagerInstance.getShowPreciseBearingValues()); + if (object != null) { + // update distance label + PositionManager.getInstance().requestCurrentLocation(); + } + } else { + return false; + } + return true; + } + + /** * pause and resume */ @@ -275,7 +324,8 @@ private void updateDistanceAndBearingLabel() { labelDistanceAndBearing.setText( String.format( GlobalInstance.getStringResource(R.string.labelPointDistanceAndBearing), - ((Point) object).formatDistanceAndRelativeBearingFromCurrentLocation(R.plurals.meter)) + ((Point) object).formatDistanceAndRelativeBearingFromCurrentLocation( + R.plurals.meter, settingsManagerInstance.getShowPreciseBearingValues())) ); } }; diff --git a/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/OverviewTabLayoutFragment.java b/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/OverviewTabLayoutFragment.java index a40ab25..ccebe5f 100644 --- a/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/OverviewTabLayoutFragment.java +++ b/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/OverviewTabLayoutFragment.java @@ -1,6 +1,7 @@ package org.walkersguide.android.ui.fragment.tabs; import android.widget.ImageButton; +import org.walkersguide.android.ui.fragment.tabs.overview.StartFragment; import org.walkersguide.android.ui.fragment.tabs.overview.PinFragment; import org.walkersguide.android.ui.fragment.tabs.overview.TrackFragment; import org.walkersguide.android.ui.fragment.TabLayoutFragment; @@ -41,35 +42,6 @@ public static OverviewTabLayoutFragment newInstance(Enum selectedTab) { } - private ResolveCurrentAddressView layoutClosestAddress; - - @Override public int getLayoutResourceId() { - return R.layout.fragment_overview; - } - - @Override public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - layoutClosestAddress = (ResolveCurrentAddressView) view.findViewById(R.id.layoutClosestAddress); - layoutClosestAddress.requestAddressForCurrentLocation(); - - ImageButton buttonCollections = (ImageButton) view.findViewById(R.id.buttonCollections); - buttonCollections.setOnClickListener(new View.OnClickListener() { - @Override public void onClick(View v) { - mainActivityController.addFragment( - CollectionListFragment.newInstance()); - } - }); - - ImageButton buttonHistory = (ImageButton) view.findViewById(R.id.buttonHistory); - buttonHistory.setOnClickListener(new View.OnClickListener() { - @Override public void onClick(View v) { - mainActivityController.addFragment( - HistoryFragment.newInstance()); - } - }); - } - @Override public void onStart() { super.onStart(); initializeViewPagerAndTabLayout(new OverviewTabAdapter()); @@ -81,6 +53,7 @@ public static OverviewTabLayoutFragment newInstance(Enum selectedTab) { */ public enum Tab { + START(GlobalInstance.getStringResource(R.string.fragmentStartName)), PIN(GlobalInstance.getStringResource(R.string.fragmentPinName)), TRACK(GlobalInstance.getStringResource(R.string.fragmentTrackName)); @@ -102,7 +75,7 @@ public OverviewTabAdapter() { } @Override public Enum getDefaultTab() { - return Tab.PIN; + return Tab.START; } @Override public Fragment getFragment(int position) { @@ -110,6 +83,8 @@ public OverviewTabAdapter() { Timber.d("createFragment: position=%1$d, tab=%2$s", position, tab); if (tab != null) { switch (tab) { + case START: + return StartFragment.newInstance(); case PIN: return PinFragment.newInstance(); case TRACK: diff --git a/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/overview/StartFragment.java b/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/overview/StartFragment.java new file mode 100644 index 0000000..d43b4f6 --- /dev/null +++ b/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/overview/StartFragment.java @@ -0,0 +1,273 @@ +package org.walkersguide.android.ui.fragment.tabs.overview; + +import org.walkersguide.android.ui.dialog.create.PointFromCoordinatesLinkDialog; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import org.walkersguide.android.tts.TTSWrapper; +import org.walkersguide.android.util.Helper; +import org.walkersguide.android.data.profile.MutableProfile; +import org.walkersguide.android.ui.adapter.PinnedObjectsAdapter; +import org.walkersguide.android.ui.adapter.PinnedObjectsAdapter.OnAddButtonClick; +import org.walkersguide.android.database.profile.StaticProfile; +import androidx.core.view.MenuProvider; +import org.walkersguide.android.R; + +import android.os.Bundle; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import android.widget.TextView; +import android.widget.AbsListView; +import java.util.concurrent.Executors; +import org.walkersguide.android.data.ObjectWithId; +import java.util.ArrayList; +import org.walkersguide.android.database.util.AccessDatabase; +import org.walkersguide.android.database.DatabaseProfileRequest; +import android.os.Handler; +import android.os.Looper; +import org.walkersguide.android.ui.dialog.select.SelectProfileFromMultipleSourcesDialog; +import org.walkersguide.android.ui.dialog.select.SelectObjectWithIdFromMultipleSourcesDialog; +import androidx.annotation.NonNull; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; + +import androidx.fragment.app.FragmentResultListener; +import android.content.Context; +import androidx.lifecycle.Lifecycle; +import android.widget.ExpandableListView; +import android.content.BroadcastReceiver; +import org.walkersguide.android.data.Profile; +import android.widget.BaseExpandableListAdapter; +import android.content.Intent; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; +import android.content.IntentFilter; +import org.walkersguide.android.sensor.DeviceSensorManager; +import org.walkersguide.android.ui.dialog.create.SaveCurrentLocationDialog; +import android.widget.Button; +import org.walkersguide.android.ui.view.ResolveCurrentAddressView; +import org.walkersguide.android.util.GlobalInstance; +import org.walkersguide.android.ui.fragment.profile_list.CollectionListFragment; +import org.walkersguide.android.ui.fragment.HistoryFragment; +import timber.log.Timber; +import org.walkersguide.android.ui.dialog.create.EnterAddressDialog; +import org.walkersguide.android.data.object_with_id.point.point_with_address_data.StreetAddress; +import org.walkersguide.android.server.wg.p2p.P2pRouteRequest; +import org.walkersguide.android.data.object_with_id.Point; +import org.walkersguide.android.sensor.PositionManager; +import android.widget.Toast; +import org.walkersguide.android.util.SettingsManager; +import org.walkersguide.android.ui.activity.MainActivity; +import org.walkersguide.android.ui.fragment.tabs.ObjectDetailsTabLayoutFragment; + + +public class StartFragment extends BaseOverviewFragment + implements FragmentResultListener, MenuProvider, OnRefreshListener { + + public static StartFragment newInstance() { + StartFragment fragment = new StartFragment(); + return fragment; + } + + + @Override public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getChildFragmentManager() + .setFragmentResultListener( + EnterAddressDialog.REQUEST_ENTER_ADDRESS, this, this); + getChildFragmentManager() + .setFragmentResultListener( + PointFromCoordinatesLinkDialog.REQUEST_FROM_COORDINATES_LINK, this, this); + } + + @Override public void onFragmentResult(@NonNull String requestKey, @NonNull Bundle bundle) { + if (requestKey.equals(EnterAddressDialog.REQUEST_ENTER_ADDRESS)) { + prepareRequestAndCalculateRoute( + (StreetAddress) bundle.getSerializable(EnterAddressDialog.EXTRA_STREET_ADDRESS)); + } else if (requestKey.equals(PointFromCoordinatesLinkDialog.REQUEST_FROM_COORDINATES_LINK)) { + Point sharedLocation = (Point) bundle.getSerializable(PointFromCoordinatesLinkDialog.EXTRA_COORDINATES); + if (sharedLocation != null) { + mainActivityController.addFragment( + ObjectDetailsTabLayoutFragment.details(sharedLocation)); + } + } + } + + private void prepareRequestAndCalculateRoute(StreetAddress destination) { + P2pRouteRequest p2pRouteRequest = P2pRouteRequest.getDefault(); + + // start point + Point currentLocation = PositionManager.getInstance().getCurrentLocation(); + if (currentLocation != null) { + p2pRouteRequest.setStartPoint(currentLocation); + } else { + showNoLocationFoundToast(); + return; + } + + // destination point + if (destination != null) { + p2pRouteRequest.setDestinationPoint(destination); + } else { + return; + } + + SettingsManager.getInstance().setP2pRouteRequest(p2pRouteRequest); + mainActivityController.openPlanRouteDialog(true); + } + + + /** + * view creation + */ + private SwipeRefreshLayout swipeRefreshResolveCurrentAddress; + private ResolveCurrentAddressView layoutClosestAddress; + + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_start, container, false); + } + + @Override public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + requireActivity().addMenuProvider(this, getViewLifecycleOwner(), Lifecycle.State.RESUMED); + + swipeRefreshResolveCurrentAddress = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefreshResolveCurrentAddress); + swipeRefreshResolveCurrentAddress.setOnRefreshListener(this); + layoutClosestAddress = (ResolveCurrentAddressView) view.findViewById(R.id.layoutClosestAddress); + + Button buttonNavigateToAddress = (Button) view.findViewById(R.id.buttonNavigateToAddress); + buttonNavigateToAddress.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + Helper.startSpeechRecognition( + StartFragment.this, + SPEECH_INPUT_REQUEST_ENTER_ADDRESS, + GlobalInstance.getStringResource(R.string.enterAddressDialogName)); + } + }); + + Button buttonSaveCurrentLocation = (Button) view.findViewById(R.id.buttonSaveCurrentLocation); + buttonSaveCurrentLocation.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + SaveCurrentLocationDialog.addToDatabaseProfile() + .show(getChildFragmentManager(), "SaveCurrentLocationDialog"); + } + }); + + Button buttonShareLocation = (Button) view.findViewById(R.id.buttonShareLocation); + buttonShareLocation.setOnClickListener(new View.OnClickListener() { + @Override public void onClick(View v) { + Point currentLocation = PositionManager.getInstance().getCurrentLocation(); + if (currentLocation != null) { + currentLocation.startShareCoordinatesChooserActivity( + getActivity(), Point.SharingService.OSM_ORG); + } else { + showNoLocationFoundToast(); + } + } + }); + + Button buttonLoadSharedLocation = (Button) view.findViewById(R.id.buttonLoadSharedLocation); + buttonLoadSharedLocation.setOnClickListener(new View.OnClickListener() { + @Override public void onClick(View v) { + PointFromCoordinatesLinkDialog.newInstance() + .show(getChildFragmentManager(), "PointFromCoordinatesLinkDialog"); + } + }); + + Button buttonRecordRoute = (Button) view.findViewById(R.id.buttonRecordRoute); + buttonRecordRoute.setOnClickListener(new View.OnClickListener() { + @Override public void onClick(View v) { + MainActivity.startRouteRecording(getActivity()); + } + }); + + Button buttonCollections = (Button) view.findViewById(R.id.buttonCollections); + buttonCollections.setOnClickListener(new View.OnClickListener() { + @Override public void onClick(View v) { + mainActivityController.addFragment( + CollectionListFragment.newInstance()); + } + }); + + Button buttonHistory = (Button) view.findViewById(R.id.buttonHistory); + buttonHistory.setOnClickListener(new View.OnClickListener() { + @Override public void onClick(View v) { + mainActivityController.addFragment( + HistoryFragment.newInstance()); + } + }); + } + + @Override public void onPause() { + super.onPause(); + } + + @Override public void onResume() { + super.onResume(); + updateClosestAddress(); + } + + @Override public void onRefresh() { + Timber.d("onRefresh"); + updateClosestAddress(); + Helper.vibrateOnce( + Helper.VIBRATION_DURATION_SHORT, Helper.VIBRATION_INTENSITY_WEAK); + swipeRefreshResolveCurrentAddress.setRefreshing(false); + } + + public void requestUiUpdate() { + updateClosestAddress(); + } + + private void updateClosestAddress() { + layoutClosestAddress.requestAddressForCurrentLocation(); + } + + private void showNoLocationFoundToast() { + Toast.makeText( + getActivity(), + GlobalInstance.getStringResource(R.string.errorNoLocationFound), + Toast.LENGTH_LONG) + .show(); + } + + + /** + * menu + */ + + @Override public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) { + menuInflater.inflate(R.menu.menu_toolbar_start_fragment, menu); + } + + @Override public boolean onMenuItemSelected(MenuItem item) { + if (item.getItemId() == R.id.menuItemRefresh) { + updateClosestAddress(); + } else { + return false; + } + return true; + } + + + /** + * speech recognition results + */ + private final static int SPEECH_INPUT_REQUEST_ENTER_ADDRESS = 7855; + + @Override public void onActivityResult(int requestCode, int resultCode, Intent resultData) { + if (requestCode == SPEECH_INPUT_REQUEST_ENTER_ADDRESS) { + String addressString = Helper.extractSpeechRecognitionResult(resultCode, resultData); + if (addressString != null) { + Timber.d("address string: %1$s", addressString); + EnterAddressDialog.newInstance(addressString) + .show(getChildFragmentManager(), "EnterAddressDialog"); + } + } else { + super.onActivityResult(requestCode, resultCode, resultData); + } + } + +} diff --git a/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/overview/TrackFragment.java b/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/overview/TrackFragment.java index c1cfafe..83d71ae 100644 --- a/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/overview/TrackFragment.java +++ b/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/overview/TrackFragment.java @@ -1,6 +1,7 @@ package org.walkersguide.android.ui.fragment.tabs.overview; import timber.log.Timber; +import org.walkersguide.android.ui.adapter.AnnouncementRadiusAdapter; import org.walkersguide.android.data.profile.AnnouncementRadius; import android.widget.Spinner; import android.content.Intent; @@ -140,17 +141,13 @@ public static TrackFragment newInstance() { }); spinnerAnnouncementRadius = (Spinner) view.findViewById(R.id.spinnerAnnouncementRadius); - ArrayAdapter announcementRadiusAdapter = new ArrayAdapter( - TrackFragment.this.getContext(), - // layout for the collapsed state - android.R.layout.simple_list_item_1, - AnnouncementRadius.values()); - // layout for the expanded/opened state + AnnouncementRadiusAdapter announcementRadiusAdapter = new AnnouncementRadiusAdapter( + TrackFragment.this.getContext()); announcementRadiusAdapter.setDropDownViewResource(R.layout.layout_single_text_view_checkbox); spinnerAnnouncementRadius.setAdapter(announcementRadiusAdapter); // select spinnerAnnouncementRadius.setSelection( - AnnouncementRadius.values().indexOf( + announcementRadiusAdapter.getIndexOf( settingsManagerInstance.getTrackingModeAnnouncementRadius())); // must come after adapter and selection spinnerAnnouncementRadius.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { diff --git a/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/routes/NavigateFragment.java b/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/routes/NavigateFragment.java index ac6c2cf..bbf5721 100644 --- a/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/routes/NavigateFragment.java +++ b/app/src/main/java/org/walkersguide/android/ui/fragment/tabs/routes/NavigateFragment.java @@ -178,10 +178,7 @@ public static NavigateFragment newInstance(Route route, boolean showObjectWithId } @Override public boolean onMenuItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.menuItemRecalculateWithCurrentPosition - || item.getItemId() == R.id.menuItemRecalculateOriginalRoute - || item.getItemId() == R.id.menuItemRecalculateReturnRoute) { - P2pRouteRequest p2pRouteRequest = settingsManagerInstance.getP2pRouteRequest(); + if (item.getItemId() == R.id.menuItemRecalculate) { if (route == null) { Toast.makeText( getActivity(), @@ -190,41 +187,48 @@ public static NavigateFragment newInstance(Route route, boolean showObjectWithId return true; } - // start point - if (item.getItemId() == R.id.menuItemRecalculateWithCurrentPosition) { - Point currentLocation = PositionManager.getInstance().getCurrentLocation(); - if (currentLocation != null) { - p2pRouteRequest.setStartPoint(currentLocation); - } else { - Toast.makeText( - getActivity(), - GlobalInstance.getStringResource(R.string.errorNoLocationFound), - Toast.LENGTH_LONG).show(); - return true; - } - } else if (item.getItemId() == R.id.menuItemRecalculateReturnRoute) { - p2pRouteRequest.setStartPoint(route.getDestinationPoint()); - } else { - p2pRouteRequest.setStartPoint(route.getStartPoint()); + // get current location + Point currentLocation = PositionManager.getInstance().getCurrentLocation(); + if (currentLocation == null) { + Toast.makeText( + getActivity(), + GlobalInstance.getStringResource(R.string.errorNoLocationFound), + Toast.LENGTH_LONG).show(); + return true; } - // destination point - if (item.getItemId() == R.id.menuItemRecalculateReturnRoute) { - p2pRouteRequest.setDestinationPoint(route.getStartPoint()); - } else { - p2pRouteRequest.setDestinationPoint(route.getDestinationPoint()); + // create new route request + P2pRouteRequest p2pRouteRequest = P2pRouteRequest.getDefault(); + // new start but same destination point + p2pRouteRequest.setStartPoint(currentLocation); + p2pRouteRequest.setDestinationPoint(route.getDestinationPoint()); + + // set via points if not already passed by + if (route.hasViaPoint()) { + for (int i=route.getCurrentPosition()+1; + i list1, Array } + /** + * speech recognition + */ + + public static void startSpeechRecognition(AppCompatActivity activity, int requestCode, String label) { + try { + activity.startActivityForResult( + getSpeechRecognitionIntent(label), + requestCode); + } catch (ActivityNotFoundException a) { + SimpleMessageDialog.newInstance( + GlobalInstance.getStringResource(R.string.errorNoSpeechRecognition)) + .show(activity.getSupportFragmentManager(), "SimpleMessageDialog"); + } + } + + public static void startSpeechRecognition(Fragment fragment, int requestCode, String label) { + try { + fragment.startActivityForResult( + getSpeechRecognitionIntent(label), + requestCode); + } catch (ActivityNotFoundException a) { + SimpleMessageDialog.newInstance( + GlobalInstance.getStringResource(R.string.errorNoSpeechRecognition)) + .show(fragment.getChildFragmentManager(), "SimpleMessageDialog"); + } + } + + private static Intent getSpeechRecognitionIntent(String label) { + Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); + intent.putExtra( + RecognizerIntent.EXTRA_LANGUAGE_MODEL, + RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); + intent.putExtra( + RecognizerIntent.EXTRA_LANGUAGE, + Locale.getDefault()); + intent.putExtra( + RecognizerIntent.EXTRA_PROMPT, + label); + return intent; + } + + public static String extractSpeechRecognitionResult(int resultCode, Intent data) { + String searchTerm = null; + if (resultCode == AppCompatActivity.RESULT_OK) { + try { + searchTerm = data.getStringArrayListExtra( + RecognizerIntent.EXTRA_RESULTS) + .get(0); + } catch (Exception e) { + searchTerm = null; + } finally { + if (searchTerm != null + && searchTerm.length() < 3) { + searchTerm = null; + } + } + } + Timber.d("voice search result: %1$s", searchTerm); + return searchTerm; + } + + /** * vibration */ diff --git a/app/src/main/java/org/walkersguide/android/util/SettingsManager.java b/app/src/main/java/org/walkersguide/android/util/SettingsManager.java index 3c7dd5f..673f735 100644 --- a/app/src/main/java/org/walkersguide/android/util/SettingsManager.java +++ b/app/src/main/java/org/walkersguide/android/util/SettingsManager.java @@ -676,7 +676,7 @@ public WayClassWeightSettings getWayClassWeightSettings() { } } if (resetToDefaults) { - wayClassWeightSettings = WayClassWeightSettings.getDefault(); + wayClassWeightSettings = WayClassWeightSettings.Preset.URBAN_ON_FOOT.settings; } // return return wayClassWeightSettings; diff --git a/app/src/main/java/org/walkersguide/android/util/WalkersGuideService.java b/app/src/main/java/org/walkersguide/android/util/WalkersGuideService.java index 56616aa..ee6be42 100644 --- a/app/src/main/java/org/walkersguide/android/util/WalkersGuideService.java +++ b/app/src/main/java/org/walkersguide/android/util/WalkersGuideService.java @@ -379,6 +379,11 @@ public enum ServiceState { switch (routeRecordingState) { case OFF: recordedPointList.clear(); + // show warning dialog + if (settingsManagerInstance.showRouteRecordingOnlyInForegroundMessage()) { + settingsManagerInstance.setShowRouteRecordingOnlyInForegroundMessage(false); + sendShowRouteRecordingOnlyInForegroundMessageBroadCast(); + } case PAUSED: routeRecordingState = RouteRecordingState.RUNNING; sendRouteRecordingChangedBroadcast(); @@ -970,6 +975,15 @@ public static void addPointToRecordedRoute(GPS pointToAdd) { GlobalInstance.getContext().startService(intent); } + // route recording only in foreground warning + public static final String ACTION_SHOW_ROUTE_RECORDING_ONLY_IN_FOREGROUND_MESSAGE = String.format( + "%1$s.action.showRouteRecordingOnlyInForegroundMessage", BuildConfig.APPLICATION_ID); + + private void sendShowRouteRecordingOnlyInForegroundMessageBroadCast() { + Intent intent = new Intent(ACTION_SHOW_ROUTE_RECORDING_ONLY_IN_FOREGROUND_MESSAGE); + LocalBroadcastManager.getInstance(GlobalInstance.getContext()).sendBroadcast(intent); + } + // route recording changed broadcast public static final String ACTION_ROUTE_RECORDING_CHANGED = String.format( "%1$s.action.routeRecordingChanged", BuildConfig.APPLICATION_ID); diff --git a/app/src/main/res/drawable/image_collections.xml b/app/src/main/res/drawable/image_collections.xml deleted file mode 100644 index 1d885ac..0000000 --- a/app/src/main/res/drawable/image_collections.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/image_history.xml b/app/src/main/res/drawable/image_history.xml deleted file mode 100644 index 93ca20d..0000000 --- a/app/src/main/res/drawable/image_history.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/image_radius.xml b/app/src/main/res/drawable/image_radius.xml new file mode 100644 index 0000000..7798189 --- /dev/null +++ b/app/src/main/res/drawable/image_radius.xml @@ -0,0 +1,11 @@ + + + diff --git a/app/src/main/res/layout/dialog_info.xml b/app/src/main/res/layout/dialog_info.xml index ec52da8..80af1b7 100644 --- a/app/src/main/res/layout/dialog_info.xml +++ b/app/src/main/res/layout/dialog_info.xml @@ -72,7 +72,7 @@ android:focusable="true" /> - + + + + + + + + diff --git a/app/src/main/res/layout/fragment_overview.xml b/app/src/main/res/layout/fragment_overview.xml deleted file mode 100644 index 56acbe3..0000000 --- a/app/src/main/res/layout/fragment_overview.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index f634c86..744fdac 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -41,6 +41,18 @@ android:layout_height="wrap_content" android:text="@string/buttonServerMapNoSelection" /> +