From d5e9047415a55ef6830089ecd08a345973b3c457 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Sat, 30 Mar 2013 17:18:08 +0100 Subject: [PATCH] Refactor location provider and introduce gps info widget --- OsmAnd/.cproject | 4 +- OsmAnd/res/drawable-mdpi/info_gps_info.png | Bin 0 -> 1318 bytes OsmAnd/res/drawable-mdpi/widget_gps_info.png | Bin 0 -> 1302 bytes OsmAnd/res/values/strings.xml | 1 + .../access/MapAccessibilityActions.java | 2 +- .../src/net/osmand/access/NavigationInfo.java | 431 ++++--- .../net/osmand/plus/NavigationService.java | 140 +-- .../osmand/plus/OsmAndLocationProvider.java | 565 +++++++++ ...ion.java => OsmAndLocationSimulation.java} | 36 +- .../net/osmand/plus/OsmandApplication.java | 43 +- .../plus/activities/DayNightHelper.java | 60 +- .../activities/IntermediatePointsDialog.java | 23 +- .../plus/activities/LiveMonitoringHelper.java | 13 + .../plus/activities/MainMenuActivity.java | 96 ++ .../osmand/plus/activities/MapActivity.java | 1075 ++--------------- .../plus/activities/MapActivityActions.java | 84 +- .../plus/activities/MapActivityLayers.java | 2 +- .../plus/activities/SavingTrackHelper.java | 14 + .../plus/activities/SettingsActivity.java | 1 + .../activities/search/SearchActivity.java | 67 +- .../activities/search/SearchPOIActivity.java | 232 +--- .../osmand/plus/api/InternalToDoAPIImpl.java | 11 - .../audionotes/AudioVideoNotesPlugin.java | 7 +- .../osmand/plus/base/FailSafeFuntions.java | 145 +++ .../plus/base/MapViewTrackingUtilities.java | 263 ++++ .../development/OsmandDevelopmentPlugin.java | 10 +- .../osmand/plus/views/ContextMenuLayer.java | 2 +- .../osmand/plus/views/MapControlsLayer.java | 8 +- .../net/osmand/plus/views/MapInfoLayer.java | 43 +- .../osmand/plus/views/PointLocationLayer.java | 35 +- .../plus/views/PointNavigationLayer.java | 9 +- .../osmand/plus/views/RouteInfoControls.java | 50 +- 32 files changed, 1772 insertions(+), 1700 deletions(-) create mode 100644 OsmAnd/res/drawable-mdpi/info_gps_info.png create mode 100644 OsmAnd/res/drawable-mdpi/widget_gps_info.png create mode 100644 OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java rename OsmAnd/src/net/osmand/plus/{routing/RouteAnimation.java => OsmAndLocationSimulation.java} (83%) create mode 100644 OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java create mode 100644 OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java diff --git a/OsmAnd/.cproject b/OsmAnd/.cproject index 694134ac9a..5fc2b31392 100644 --- a/OsmAnd/.cproject +++ b/OsmAnd/.cproject @@ -1,5 +1,7 @@ - + + + diff --git a/OsmAnd/res/drawable-mdpi/info_gps_info.png b/OsmAnd/res/drawable-mdpi/info_gps_info.png new file mode 100644 index 0000000000000000000000000000000000000000..3e10d76bfdde08f218216f23c13ed0d4ced7c1ac GIT binary patch literal 1318 zcmV+>1=;$EP)0%H*~Hdt$eHWW(}tR&V2 zCEDu3nwa9I3m09~O1f!NYa;5RX=4+UYHU+&L98f6j0z}I5FC*a6f%ed%nS_k-EY1w zga#FRl6P@$?s?A1J#X$6ydoAs&IZ`H7E0DZ-bzRnAi80w89Hu3T_gN81fIF_#fuwe zu$9B^Jy5v<9Agj;!l(vO4Ky9Zo4}e3rhCwT5>B0lqvJ62swOc*+F|%*9JCgAcmTf2 zh0R7-1Q-E>5o|e7Tn%3~!Gm$oYN0+I@?HtnfuRI;e-6hNz%l{)cvzSP>o!8^n^2Mk z>k_~wK%Wd52jJKvh+G1%9de%s>U0L9(Kv5g430d6sUuKt0Xu*mATu*_`?hV{YCIm#6)9yv10@gM{T_~`LRupaW3h3AUY3@faev;S!07iJ3JuHFrE7k5*k>ea&jMuAZ(KzZSNq zfy)3%(}UI-ATbT{55t8Hh#eP=7Zp_=rcMlrlz`7Z>c%fHcTwHw6 z?RMwJVliT|7;Dz7NjI5H8{692E-8xg6cB5n^kdln2COfG58`3z-*D;{w3Na}8Q}O6 z&IKU60p1Tog1)@G{Lu2{%jd^pF;rDWQ55p?^HYToxm{gdH=@z#un%tc!`NzAp8$y~ zVO0xsJc8@D5|w@#<4t*x!y z6AFd?X@sLO&<4P#gSdH+H3*}F@I(*E65=0#Uw8lh{q|@y%IxcyQ6v&!WMqV`TelYN z-MjavxVSin3X#k3jTg?E!BGTdkHI$p-D$8Y4qod3kIw7${t*ZSqSGC|q{+!i{C+=W zWo4`P?b~^xlQ;yYQ<4%pbyc6EJZG4(Sy|83~8OW|zygNvG4z37!pi zyWLAI7E4iETU&!7<&zQU)PT3)U=fu52DKjeQ4cUWI(iRqIvkEHA%yP#;NftX!ootk z)oOKjc6Q#HnwlEYKr_LTNif#IK?TP30II5n`}+EBn9b$_yWPG-2q830V=hT42?m1{ z78a&kES7@S*4BDeRReyw-2;~=p#Q(u4M0j6=;`UXqN?hWjEsyNA;g^E7vPIcCR0Is zd;1wxRU;C{XL$Nq)WAtAvmgwO-efmKx{6bdQr?d`n{4GqWr ze*aBP)706lm;St&NJ>gt;dDBSGcqzt91cgm&1Op#LWtqv;i101zK;I>{yMMMTOSUG cyXMOO7w(XeJmeX(wg3PC07*qoM6N<$f`773E&u=k literal 0 HcmV?d00001 diff --git a/OsmAnd/res/drawable-mdpi/widget_gps_info.png b/OsmAnd/res/drawable-mdpi/widget_gps_info.png new file mode 100644 index 0000000000000000000000000000000000000000..934db8cbf680bdfde97ab857a5a28931fa1cf398 GIT binary patch literal 1302 zcmV+x1?l>UP) zl$DdVTU(o@n`@QxuUa{qx|S{1A2c;fkx4DD7_OeeZkUyKjF0 z4clQ{wfPU9?Y%wwe8120em$S(+4DTG7>n_kLqzhk9&(IOQV8W0u=y!Sl0dY9<1+NL zz|{fxNd@cw3Ls$ZX4v-*>@5PL1E%i7xB`j>S~Nr_!ir>A-U>rU;pLvs{t{?7n_J{9&=z-bB60iA#~ zF|cD5R3t!o4D1lF7SKtsVHcbn0QoHR>*2|NZ44}%Y3pX%hD3Pj2((-R$1PB9f_w=a z??Gz{yb8nvhG*dTE%4Vvvw-A?-3i{YcSph?pnB51|RK$Pio-X z7MSbu6iyi6d0>eSvTC8J8-mI3Iv{O>BORb@1oMIc3JVL*TPzl>rKLq{YirZGy1KO5 z+S=cR5SwNJHo%*gVB$Jxt)P^_86Z{%Pkav(hoD_RVl0$2z{nnG4Cf_6Dg#m;@A)zP=fk5Cd$+FDknXkW^{Cv0|yT5tf{FvJ9AFRcj03XT#&%H2P$na z=!f2D$c=|pt@B(^VFCL3`kF>YMwGcrFjqdG52w>fU0vN)lgZQ|Nm4GL0a`5N1VNmG zFEwy(fZ|mU-vd8{^U{S&%ChWEN=hm>8jY(%p%CGusw!Tum!hJg6qn1D)7#to3*ZWX zy#;#5;5z|^z3}Ncc$?tEaJOSv0AO@@c-T--P*5gGQdoew5M^a$X@Njsr`2lx5qO}$ z9{`zf_ywpq4W}N!R|~EHfYMR9R)vZ5&YHk++O(=-R5 zX^=VsQ5|p?n2ZPjn7ViGUV9)A*q)J*kt&1`nx+v>s;c64yD2FtS+A<~{Ol4u>N(H#av&2oV+iCG^P7iZAvbUNT6fM77l#Kc6vVzJnpnwn1ge7@g+;6IEV*`rjFq^yL5gwpi% z^z!WN>@7y4F-ejnF*rEru-R-qcDw!R*w|QeC={|qGVWq5#$$~?0dmK3ii*$0BLDyZ M07*qoM6N<$f_qk0!2kdN literal 0 HcmV?d00001 diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index dfd4648912..29a08c3776 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,7 @@ 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy --> + GPS info Arrival time checked unchecked diff --git a/OsmAnd/src/net/osmand/access/MapAccessibilityActions.java b/OsmAnd/src/net/osmand/access/MapAccessibilityActions.java index 0be17ee61a..f076334718 100644 --- a/OsmAnd/src/net/osmand/access/MapAccessibilityActions.java +++ b/OsmAnd/src/net/osmand/access/MapAccessibilityActions.java @@ -17,7 +17,7 @@ public class MapAccessibilityActions implements AccessibilityActionsProvider { @Override public boolean onClick() { if ((Build.VERSION.SDK_INT >= 14) && activity.getMyApplication().getInternalAPI().accessibilityEnabled()) { - activity.emitNavigationHint(); + activity.getMyApplication().getLocationProvider().emitNavigationHint(); return true; } return false; diff --git a/OsmAnd/src/net/osmand/access/NavigationInfo.java b/OsmAnd/src/net/osmand/access/NavigationInfo.java index ebd73556eb..2e4f3ccec5 100644 --- a/OsmAnd/src/net/osmand/access/NavigationInfo.java +++ b/OsmAnd/src/net/osmand/access/NavigationInfo.java @@ -15,258 +15,247 @@ import net.osmand.plus.access.RelativeDirectionStyle; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; -import android.os.Handler; import android.os.SystemClock; public class NavigationInfo { - private static final long MIN_NOTIFICATION_PERIOD = 10000; - private static final float FULL_CIRCLE = 360.0f; + private static final long MIN_NOTIFICATION_PERIOD = 10000; + private static final float FULL_CIRCLE = 360.0f; - private class RelativeDirection { + private class RelativeDirection { - private static final int UNKNOWN = -1; + private static final int UNKNOWN = -1; - private final int[] direction = { - R.string.front, - R.string.front_right, - R.string.right, - R.string.back_right, - R.string.back, - R.string.back_left, - R.string.left, - R.string.front_left - }; + private final int[] direction = { R.string.front, + R.string.front_right, + R.string.right, + R.string.back_right, + R.string.back, + R.string.back_left, + R.string.left, + R.string.front_left }; - private RelativeDirectionStyle style; - private int value; + private RelativeDirectionStyle style; + private int value; - public RelativeDirection() { - style = settings.DIRECTION_STYLE.get(); - clear(); - } + public RelativeDirection() { + style = settings.DIRECTION_STYLE.get(); + clear(); + } - // The argument must be not null as well as the currentLocation - // and currentLocation must have bearing. - public RelativeDirection(final Location point) { - style = settings.DIRECTION_STYLE.get(); - value = directionTo(point, currentLocation.getBearing()); - } + // The argument must be not null as well as the currentLocation + // and currentLocation must have bearing. + public RelativeDirection(final Location point) { + style = settings.DIRECTION_STYLE.get(); + value = directionTo(point, currentLocation.getBearing()); + } - // The first argument must be not null as well as the currentLocation. - public RelativeDirection(final Location point, float heading) { - style = settings.DIRECTION_STYLE.get(); - value = directionTo(point, heading); - } + // The first argument must be not null as well as the currentLocation. + public RelativeDirection(final Location point, float heading) { + style = settings.DIRECTION_STYLE.get(); + value = directionTo(point, heading); + } - public void clear() { - value = UNKNOWN; - } + public void clear() { + value = UNKNOWN; + } - // The first argument must be not null as well as the currentLocation. - public boolean update(final Location point, float heading) { - boolean result = false; - final RelativeDirectionStyle newStyle = settings.DIRECTION_STYLE.get(); - if (style != newStyle) { - style = newStyle; - result = true; - } - final int newValue = directionTo(point, heading); - if (value != newValue) { - value = newValue; - result = true; - } - return result; - } + // The first argument must be not null as well as the currentLocation. + public boolean update(final Location point, float heading) { + boolean result = false; + final RelativeDirectionStyle newStyle = settings.DIRECTION_STYLE.get(); + if (style != newStyle) { + style = newStyle; + result = true; + } + final int newValue = directionTo(point, heading); + if (value != newValue) { + value = newValue; + result = true; + } + return result; + } - // The argument must be not null as well as the currentLocation - // and currentLocation must have bearing. - public boolean update(final Location point) { - return update(point, currentLocation.getBearing()); - } + // The argument must be not null as well as the currentLocation + // and currentLocation must have bearing. + public boolean update(final Location point) { + return update(point, currentLocation.getBearing()); + } - public String getString() { - if (value < 0) // unknown direction - return null; - if (style == RelativeDirectionStyle.CLOCKWISE) { - String result = NavigationInfo.this.getString(R.string.towards); - result += " " + String.valueOf((value != 0) ? value : 12); //$NON-NLS-1$ - result += " " + NavigationInfo.this.getString(R.string.oclock); //$NON-NLS-1$ - return result; - } else { - return NavigationInfo.this.getString(direction[value]); - } - } + public String getString() { + if (value < 0) // unknown direction + return null; + if (style == RelativeDirectionStyle.CLOCKWISE) { + String result = NavigationInfo.this.getString(R.string.towards); + result += " " + String.valueOf((value != 0) ? value : 12); //$NON-NLS-1$ + result += " " + NavigationInfo.this.getString(R.string.oclock); //$NON-NLS-1$ + return result; + } else { + return NavigationInfo.this.getString(direction[value]); + } + } - // The first argument must be not null as well as the currentLocation. - private int directionTo(final Location point, float heading) { - final float bearing = currentLocation.bearingTo(point) - heading; - final int nSectors = (style == RelativeDirectionStyle.CLOCKWISE) ? 12 : direction.length; - int sector = Math.round(Math.abs(bearing) * (float)nSectors / FULL_CIRCLE) % nSectors; - if ((bearing < 0) && (sector != 0)) - sector = nSectors - sector; - return sector; - } + // The first argument must be not null as well as the currentLocation. + private int directionTo(final Location point, float heading) { + final float bearing = currentLocation.bearingTo(point) - heading; + final int nSectors = (style == RelativeDirectionStyle.CLOCKWISE) ? 12 : direction.length; + int sector = Math.round(Math.abs(bearing) * (float) nSectors / FULL_CIRCLE) % nSectors; + if ((bearing < 0) && (sector != 0)) + sector = nSectors - sector; + return sector; + } - } + } + private final int[] cardinal = { R.string.north, + R.string.north_north_east, + R.string.north_east, + R.string.east_north_east, + R.string.east, + R.string.east_south_east, + R.string.south_east, + R.string.south_south_east, + R.string.south, + R.string.south_south_west, + R.string.south_west, + R.string.west_south_west, + R.string.west, + R.string.west_north_west, + R.string.north_west, + R.string.north_north_west }; - private final int[] cardinal = { - R.string.north, - R.string.north_north_east, - R.string.north_east, - R.string.east_north_east, - R.string.east, - R.string.east_south_east, - R.string.south_east, - R.string.south_south_east, - R.string.south, - R.string.south_south_west, - R.string.south_west, - R.string.west_south_west, - R.string.west, - R.string.west_north_west, - R.string.north_west, - R.string.north_north_west - }; - - private Handler uiHandler = new Handler(); - private final ClientContext context; - private final OsmandSettings settings; - private Location currentLocation; - private RelativeDirection lastDirection; - private long lastNotificationTime; - private volatile boolean autoAnnounce; + private final ClientContext context; + private final OsmandSettings settings; + private Location currentLocation; + private RelativeDirection lastDirection; + private long lastNotificationTime; + private volatile boolean autoAnnounce; private OsmandApplication app; + public NavigationInfo(OsmandApplication app) { + this.app = app; + this.context = app; + settings = this.context.getSettings(); + currentLocation = null; + lastDirection = new RelativeDirection(); + lastNotificationTime = SystemClock.uptimeMillis(); + autoAnnounce = false; + } - public NavigationInfo(final Context context) { - this.app =((OsmandApplication) context.getApplicationContext()); - this.context = app; - settings = this.context.getSettings(); - currentLocation = null; - lastDirection = new RelativeDirection(); - lastNotificationTime = SystemClock.uptimeMillis(); - autoAnnounce = false; - } + private String getString(int id) { + return context.getString(id); + } + // The argument must be not null as well as the currentLocation + private String distanceString(final Location point) { + return OsmAndFormatter.getFormattedDistance(currentLocation.distanceTo(point), context); + } - private String getString(int id) { - return context.getString(id); - } + // The argument must be not null as well as the currentLocation + private String absoluteDirectionString(float bearing) { + int direction = Math.round(Math.abs(bearing) * (float) cardinal.length / FULL_CIRCLE) % cardinal.length; + if ((bearing < 0) && (direction != 0)) + direction = cardinal.length - direction; + return getString(cardinal[direction]); + } - // The argument must be not null as well as the currentLocation - private String distanceString(final Location point) { - return OsmAndFormatter.getFormattedDistance(currentLocation.distanceTo(point), context); - } + // Get distance and direction string for specified point + public synchronized String getDirectionString(final Location point, Float heading) { + if ((currentLocation != null) && (point != null)) { + RelativeDirection direction = null; + String result = distanceString(point); + result += " "; //$NON-NLS-1$ + if (currentLocation.hasBearing()) + direction = new RelativeDirection(point); + else if (heading != null) + direction = new RelativeDirection(point, heading); + if (direction != null) { + // relative direction + result += direction.getString(); + } else { + // absolute direction + result += getString(R.string.towards) + " "; //$NON-NLS-1$ + result += absoluteDirectionString(currentLocation.bearingTo(point)); + } + return result; + } + return null; + } - // The argument must be not null as well as the currentLocation - private String absoluteDirectionString(float bearing) { - int direction = Math.round(Math.abs(bearing) * (float)cardinal.length / FULL_CIRCLE) % cardinal.length; - if ((bearing < 0) && (direction != 0)) - direction = cardinal.length - direction; - return getString(cardinal[direction]); - } + public synchronized String getDirectionString(final LatLon point, Float heading) { + if (point != null) { + Location destination = new Location("map"); //$NON-NLS-1$ + destination.setLatitude(point.getLatitude()); + destination.setLongitude(point.getLongitude()); + return getDirectionString(destination, heading); + } + return null; + } + // Get current travelling speed and direction + public synchronized String getSpeedString() { + if ((currentLocation != null) && currentLocation.hasSpeed()) { + String result = OsmAndFormatter.getFormattedSpeed(currentLocation.getSpeed(), context); + if (currentLocation.hasBearing()) + result += " " + absoluteDirectionString(currentLocation.getBearing()); //$NON-NLS-1$ + return result; + } + return null; + } - // Get distance and direction string for specified point - public synchronized String getDirectionString(final Location point, Float heading) { - if ((currentLocation != null) && (point != null)) { - RelativeDirection direction = null; - String result = distanceString(point); - result += " "; //$NON-NLS-1$ - if (currentLocation.hasBearing()) - direction = new RelativeDirection(point); - else if (heading != null) - direction = new RelativeDirection(point, heading); - if (direction != null) { - // relative direction - result += direction.getString(); - } else { - // absolute direction - result += getString(R.string.towards) + " "; //$NON-NLS-1$ - result += absoluteDirectionString(currentLocation.bearingTo(point)); - } - return result; - } - return null; - } + // Get positioning accuracy and provider information if available + public synchronized String getAccuracyString() { + String result = null; + if (currentLocation != null) { + String provider = currentLocation.getProvider(); + if (currentLocation.hasAccuracy()) + result = getString(R.string.accuracy) + " " + OsmAndFormatter.getFormattedDistance(currentLocation.getAccuracy(), context); //$NON-NLS-1$ + if (result != null) + result += " (" + provider + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + else + result = provider; + } + return result; + } - public synchronized String getDirectionString(final LatLon point, Float heading) { - if (point != null) { - Location destination = new Location("map"); //$NON-NLS-1$ - destination.setLatitude(point.getLatitude()); - destination.setLongitude(point.getLongitude()); - return getDirectionString(destination, heading); - } - return null; - } + // Get altitude information string + public synchronized String getAltitudeString() { + if ((currentLocation != null) && currentLocation.hasAltitude()) + return getString(R.string.altitude) + + " " + OsmAndFormatter.getFormattedDistance((float) currentLocation.getAltitude(), context); //$NON-NLS-1$ + return null; + } - // Get current travelling speed and direction - public synchronized String getSpeedString() { - if ((currentLocation != null) && currentLocation.hasSpeed()) { - String result = OsmAndFormatter.getFormattedSpeed(currentLocation.getSpeed(), context); - if (currentLocation.hasBearing()) - result += " " + absoluteDirectionString(currentLocation.getBearing()); //$NON-NLS-1$ - return result; - } - return null; - } + public synchronized void setLocation(Location location) { + currentLocation = location; + if (autoAnnounce && context.getInternalAPI().accessibilityEnabled()) { + final LatLon point = app.getTargetPointsHelper().getPointToNavigate(); + if (point != null) { + if ((currentLocation != null) && currentLocation.hasBearing()) { + final long now = SystemClock.uptimeMillis(); + if ((now - lastNotificationTime) >= MIN_NOTIFICATION_PERIOD) { + Location destination = new Location("map"); //$NON-NLS-1$ + destination.setLatitude(point.getLatitude()); + destination.setLongitude(point.getLongitude()); + if (lastDirection.update(destination)) { + final String notification = distanceString(destination) + " " + lastDirection.getString(); //$NON-NLS-1$ + lastNotificationTime = now; + app.runInUIThread(new Runnable() { + @Override + public void run() { + context.showToastMessage(notification); + } + }); + } + } + } else { + lastDirection.clear(); + } + } + } + } - // Get positioning accuracy and provider information if available - public synchronized String getAccuracyString() { - String result = null; - if (currentLocation != null) { - String provider = currentLocation.getProvider(); - if (currentLocation.hasAccuracy()) - result = getString(R.string.accuracy) + " " + OsmAndFormatter.getFormattedDistance(currentLocation.getAccuracy(), context); //$NON-NLS-1$ - if (result != null) - result += " (" + provider + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - else - result = provider; - } - return result; - } - - // Get altitude information string - public synchronized String getAltitudeString() { - if ((currentLocation != null) && currentLocation.hasAltitude()) - return getString(R.string.altitude) + " " + OsmAndFormatter.getFormattedDistance((float)currentLocation.getAltitude(), context); //$NON-NLS-1$ - return null; - } - - - public synchronized void setLocation(Location location) { - currentLocation = location; - if (autoAnnounce && context.getInternalAPI().accessibilityEnabled()) { - final LatLon point = app.getTargetPointsHelper().getPointToNavigate(); - if (point != null) { - if ((currentLocation != null) && currentLocation.hasBearing()) { - final long now = SystemClock.uptimeMillis(); - if ((now - lastNotificationTime) >= MIN_NOTIFICATION_PERIOD) { - Location destination = new Location("map"); //$NON-NLS-1$ - destination.setLatitude(point.getLatitude()); - destination.setLongitude(point.getLongitude()); - if (lastDirection.update(destination)) { - final String notification = distanceString(destination) + " " + lastDirection.getString(); //$NON-NLS-1$ - lastNotificationTime = now; - uiHandler.post(new Runnable(){ - @Override - public void run() { - context.showToastMessage(notification); - } - }); - } - } - } else { - lastDirection.clear(); - } - } - } - } - - - // Show all available info + // Show all available info public void show(final LatLon point, Float heading, Context ctx) { final List attributes = new ArrayList(); String item; diff --git a/OsmAnd/src/net/osmand/plus/NavigationService.java b/OsmAnd/src/net/osmand/plus/NavigationService.java index 8ed0952b2e..f4e4e29b50 100644 --- a/OsmAnd/src/net/osmand/plus/NavigationService.java +++ b/OsmAnd/src/net/osmand/plus/NavigationService.java @@ -1,12 +1,11 @@ package net.osmand.plus; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + import net.osmand.PlatformUtil; import net.osmand.access.AccessibleToast; -import net.osmand.plus.activities.LiveMonitoringHelper; -import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.activities.SavingTrackHelper; -import net.osmand.plus.routing.RoutingHelper; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; @@ -23,16 +22,12 @@ import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; -import android.os.Message; import android.os.PowerManager; import android.os.PowerManager.WakeLock; import android.os.SystemClock; import android.util.Log; import android.widget.Toast; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - public class NavigationService extends Service implements LocationListener { public static class NavigationServiceBinder extends Binder { @@ -42,8 +37,6 @@ public class NavigationService extends Service implements LocationListener { private final static int NOTIFICATION_SERVICE_ID = 5; public final static String OSMAND_STOP_SERVICE_ACTION = "OSMAND_STOP_SERVICE_ACTION"; //$NON-NLS-1$ public final static String NAVIGATION_START_SERVICE_PARAM = "NAVIGATION_START_SERVICE_PARAM"; - private static final int LOST_LOCATION_MSG_ID = 10; - private static final long LOST_LOCATION_CHECK_DELAY = 20000; private NavigationServiceBinder binder = new NavigationServiceBinder(); @@ -52,8 +45,6 @@ public class NavigationService extends Service implements LocationListener { private String serviceOffProvider; private int serviceError; - private SavingTrackHelper savingTrackHelper; - private RoutingHelper routingHelper; private OsmandSettings settings; private Handler handler; @@ -61,12 +52,12 @@ public class NavigationService extends Service implements LocationListener { private static WakeLock lockStatic; private PendingIntent pendingIntent; private BroadcastReceiver broadcastReceiver; - private LiveMonitoringHelper liveMonitoringHelper; private boolean startedForNavigation; private static Method mStartForeground; private static Method mStopForeground; private static Method mSetForeground; + private OsmAndLocationProvider locationProvider; private void checkForegroundAPI() { // check new API @@ -125,7 +116,8 @@ public class NavigationService extends Service implements LocationListener { @Override public int onStartCommand(Intent intent, int flags, int startId) { handler = new Handler(); - ClientContext cl = ((OsmandApplication) getApplication()); + OsmandApplication app = (OsmandApplication) getApplication(); + ClientContext cl = app; settings = cl.getSettings(); startedForNavigation = intent.getBooleanExtra(NAVIGATION_START_SERVICE_PARAM, false); @@ -145,11 +137,8 @@ public class NavigationService extends Service implements LocationListener { serviceError = Math.min(serviceError, serviceOffInterval); - savingTrackHelper = ((OsmandApplication) getApplication()).getSavingTrackHelper(); - liveMonitoringHelper = ((OsmandApplication) getApplication()).getLiveMonitoringHelper(); - - routingHelper = ((OsmandApplication)getApplication()).getRoutingHelper(); - ((OsmandApplication)getApplication()).setNavigationService(this); + locationProvider = app.getLocationProvider(); + app.setNavigationService(this); // requesting if(isContinuous()){ @@ -168,47 +157,50 @@ public class NavigationService extends Service implements LocationListener { } // registering icon at top level - // Leave icon visible even for navigation for proper testing + // Leave icon visible even for navigation for proper display // if (!startedForNavigation) { - broadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - NavigationService.this.stopSelf(); - } - - }; - registerReceiver(broadcastReceiver, new IntentFilter(OSMAND_STOP_SERVICE_ACTION)); - Intent notificationIntent = new Intent(OSMAND_STOP_SERVICE_ACTION); - Notification notification = new Notification(R.drawable.bgs_icon, "", //$NON-NLS-1$ - System.currentTimeMillis()); - notification.flags = Notification.FLAG_NO_CLEAR; - notification.setLatestEventInfo(this, Version.getAppName(cl), getString(R.string.service_stop_background_service), - PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT)); - NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - if (mStartForeground != null) { - Log.d(PlatformUtil.TAG, "invoke startForeground"); - try { - mStartForeground.invoke(this, NOTIFICATION_SERVICE_ID, notification); - } catch (InvocationTargetException e) { - Log.d(PlatformUtil.TAG, "invoke startForeground failed"); - } catch (IllegalAccessException e) { - Log.d(PlatformUtil.TAG, "invoke startForeground failed"); - } - } - else { - Log.d(PlatformUtil.TAG, "invoke setForeground"); - mNotificationManager.notify(NOTIFICATION_SERVICE_ID, notification); - try { - mSetForeground.invoke(this, Boolean.TRUE); - } catch (InvocationTargetException e) { - Log.d(PlatformUtil.TAG, "invoke setForeground failed"); - } catch (IllegalAccessException e) { - Log.d(PlatformUtil.TAG, "invoke setForeground failed"); - } - } + showNotificationInStatusBar(cl); // } return START_REDELIVER_INTENT; } + + private void showNotificationInStatusBar(ClientContext cl) { + broadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + NavigationService.this.stopSelf(); + } + + }; + registerReceiver(broadcastReceiver, new IntentFilter(OSMAND_STOP_SERVICE_ACTION)); + Intent notificationIntent = new Intent(OSMAND_STOP_SERVICE_ACTION); + Notification notification = new Notification(R.drawable.bgs_icon, "", //$NON-NLS-1$ + System.currentTimeMillis()); + notification.flags = Notification.FLAG_NO_CLEAR; + notification.setLatestEventInfo(this, Version.getAppName(cl), getString(R.string.service_stop_background_service), + PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT)); + NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + if (mStartForeground != null) { + Log.d(PlatformUtil.TAG, "invoke startForeground"); + try { + mStartForeground.invoke(this, NOTIFICATION_SERVICE_ID, notification); + } catch (InvocationTargetException e) { + Log.d(PlatformUtil.TAG, "invoke startForeground failed"); + } catch (IllegalAccessException e) { + Log.d(PlatformUtil.TAG, "invoke startForeground failed"); + } + } else { + Log.d(PlatformUtil.TAG, "invoke setForeground"); + mNotificationManager.notify(NOTIFICATION_SERVICE_ID, notification); + try { + mSetForeground.invoke(this, Boolean.TRUE); + } catch (InvocationTargetException e) { + Log.d(PlatformUtil.TAG, "invoke setForeground failed"); + } catch (IllegalAccessException e) { + Log.d(PlatformUtil.TAG, "invoke setForeground failed"); + } + } + } @Override public void onCreate() { @@ -241,6 +233,10 @@ public class NavigationService extends Service implements LocationListener { AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); alarmManager.cancel(pendingIntent); // remove notification + removeNotification(); + } + + private void removeNotification() { NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); mNotificationManager.cancel(NOTIFICATION_SERVICE_ID); if (broadcastReceiver != null) { @@ -270,12 +266,10 @@ public class NavigationService extends Service implements LocationListener { } } - - @Override public void onLocationChanged(Location l) { if(l != null && !settings.MAP_ACTIVITY_ENABLED.get()){ - net.osmand.Location location = MapActivity.convertLocation(l,(OsmandApplication) getApplication()); + net.osmand.Location location = OsmAndLocationProvider.convertLocation(l,(OsmandApplication) getApplication()); if(!isContinuous()){ // unregister listener and wait next time LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); @@ -284,34 +278,8 @@ public class NavigationService extends Service implements LocationListener { if (lock.isHeld()) { lock.release(); } - } else { - // if continuous notify about lost location - if (routingHelper.isFollowingMode() && routingHelper.getLeftDistance() > 0) { - Message msg = Message.obtain(handler, new Runnable() { - @Override - public void run() { - if (routingHelper.getLeftDistance() > 0 && !settings.MAP_ACTIVITY_ENABLED.get() && - !handler.hasMessages(LOST_LOCATION_MSG_ID)) { - routingHelper.getVoiceRouter().gpsLocationLost(); - } - } - }); - msg.what = LOST_LOCATION_MSG_ID; - handler.removeMessages(LOST_LOCATION_MSG_ID); - handler.sendMessageDelayed(msg, LOST_LOCATION_CHECK_DELAY); - } - } - // use because there is a bug on some devices with location.getTime() - long locationTime = System.currentTimeMillis(); - savingTrackHelper.insertData(location.getLatitude(), location.getLongitude(), location.getAltitude(), - location.getSpeed(), location.getAccuracy(), locationTime, settings); - if(liveMonitoringHelper.isLiveMonitoringEnabled()) { - liveMonitoringHelper.insertData(location.getLatitude(), location.getLongitude(), location.getAltitude(), - location.getSpeed(), location.getAccuracy(), locationTime, settings); - } - if(routingHelper.isFollowingMode()){ - routingHelper.setCurrentLocation(location, false); } + locationProvider.setLocationFromService(location, isContinuous()); } } diff --git a/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java new file mode 100644 index 0000000000..ce0c3406f9 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationProvider.java @@ -0,0 +1,565 @@ +package net.osmand.plus; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import net.osmand.GeoidAltitudeCorrection; +import net.osmand.PlatformUtil; +import net.osmand.access.NavigationInfo; +import net.osmand.binary.RouteDataObject; +import net.osmand.data.LatLon; +import net.osmand.plus.routing.RoutingHelper; +import net.osmand.util.MapUtils; +import android.content.Context; +import android.hardware.GeomagneticField; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.location.GpsSatellite; +import android.location.GpsStatus.Listener; +import android.location.GpsStatus; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; + +public class OsmAndLocationProvider implements SensorEventListener { + + public interface OsmAndLocationListener { + void updateLocation(net.osmand.Location location); + } + + public interface OsmAndCompassListener { + void updateCompassValue(float value); + } + + private static final int INTERVAL_TO_CLEAR_SET_LOCATION = 30 * 1000; + private static final boolean USE_MAGNETIC_FIELD_SENSOR = true; + private static final int LOST_LOCATION_MSG_ID = 10; + private static final long LOST_LOCATION_CHECK_DELAY = 18000; + + private static final float ACCURACY_FOR_GPX_AND_ROUTING = 50; + + private static final int GPS_TIMEOUT_REQUEST = 0; + private static final int GPS_DIST_REQUEST = 0; + private static final int NOT_SWITCH_TO_NETWORK_WHEN_GPS_LOST_MS = 12000; + + private long lastTimeGPSLocationFixed = 0; + + private boolean sensorRegistered = false; + private float[] mGravs; + private float[] mGeoMags; + private float previousCorrectionValue = 360; + private Float heading = null; + + // Current screen orientation + private int currentScreenOrientation; + + private OsmandApplication app; + private OsmandSettings settings; + + private NavigationInfo navigationInfo; + private CurrentPositionHelper currentPositionHelper; + private OsmAndLocationSimulation locationSimulation; + + private net.osmand.Location location = null; + + private GPSInfo gpsInfo = new GPSInfo(); + + private List locationListeners = new ArrayList(); + private List compassListeners = new ArrayList(); + private Listener gpsStatusListener; + + + + public OsmAndLocationProvider(OsmandApplication app) { + this.app = app; + navigationInfo = new NavigationInfo(app); + settings = app.getSettings(); + currentPositionHelper = new CurrentPositionHelper(app); + locationSimulation = new OsmAndLocationSimulation(app, this); + } + + public void resumeAllUpdates() { + final LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE); + service.addGpsStatusListener(getGpsStatusListener(service)); + try { + service.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, gpsListener); + } catch (IllegalArgumentException e) { + Log.d(PlatformUtil.TAG, "GPS location provider not available"); //$NON-NLS-1$ + } + // try to always ask for network provide : it is faster way to find location + try { + service.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, networkListener); + } catch (IllegalArgumentException e) { + Log.d(PlatformUtil.TAG, "Network location provider not available"); //$NON-NLS-1$ + } + } + + private Listener getGpsStatusListener(final LocationManager service) { + gpsStatusListener = new Listener() { + private GpsStatus gpsStatus; + @Override + public void onGpsStatusChanged(int event) { + gpsStatus = service.getGpsStatus(gpsStatus); + updateGPSInfo(gpsStatus); + updateLocation(location); + } + }; + return gpsStatusListener; + } + + private void updateGPSInfo(GpsStatus s) { + boolean fixed = false; + int n = 0; + int u = 0; + if (s != null) { + Iterator iterator = s.getSatellites().iterator(); + while (iterator.hasNext()) { + GpsSatellite g = iterator.next(); + n++; + if (g.usedInFix()) { + u++; + fixed = true; + } + } + } + gpsInfo.fixed = fixed; + gpsInfo.foundSatellites = n; + gpsInfo.usedSatellites = u; + } + + public GPSInfo getGPSInfo(){ + return gpsInfo; + } + + public void updateScreenOrientation(int orientation) { + currentScreenOrientation = orientation; + } + + public void addLocationListener(OsmAndLocationListener listener){ + if(!locationListeners.contains(listener)) { + locationListeners.add(listener); + } + } + + public void removeLocationListener(OsmAndLocationListener listener){ + locationListeners.remove(listener); + } + + public void addCompassListener(OsmAndCompassListener listener){ + if(!compassListeners.contains(listener)) { + compassListeners.add(listener); + } + } + + public void removeCompassListener(OsmAndCompassListener listener){ + compassListeners.remove(listener); + } + + public net.osmand.Location getFirstTimeRunDefaultLocation() { + LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE); + List providers = new ArrayList(service.getProviders(true)); + // note, passive provider is from API_LEVEL 8 but it is a constant, we can check for it. + // constant should not be changed in future + int passiveFirst = providers.indexOf("passive"); // LocationManager.PASSIVE_PROVIDER + // put passive provider to first place + if (passiveFirst > -1) { + providers.add(0, providers.remove(passiveFirst)); + } + // find location + for (String provider : providers) { + net.osmand.Location location = convertLocation(service.getLastKnownLocation(provider), app); + if (location != null) { + return location; + } + } + return null; + } + + public void registerOrUnregisterCompassListener(boolean register) { + if (sensorRegistered && !register) { + Log.d(PlatformUtil.TAG, "Disable sensor"); //$NON-NLS-1$ + ((SensorManager) app.getSystemService(Context.SENSOR_SERVICE)).unregisterListener(this); + sensorRegistered = false; + heading = null; + } else if (!sensorRegistered && register) { + Log.d(PlatformUtil.TAG, "Enable sensor"); //$NON-NLS-1$ + SensorManager sensorMgr = (SensorManager) app.getSystemService(Context.SENSOR_SERVICE); + if (USE_MAGNETIC_FIELD_SENSOR) { + Sensor s = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + if (s == null || !sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI)) { + Log.e(PlatformUtil.TAG, "Sensor accelerometer could not be enabled"); + } + s = sensorMgr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); + if (s == null || !sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI)) { + Log.e(PlatformUtil.TAG, "Sensor magnetic field could not be enabled"); + } + } else { + Sensor s = sensorMgr.getDefaultSensor(Sensor.TYPE_ORIENTATION); + if (s == null || !sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI)) { + Log.e(PlatformUtil.TAG, "Sensor orientation could not be enabled"); + } + } + sensorRegistered = true; + } + } + + // location not null! + private void updateSpeedEmulator(net.osmand.Location location) { + // For network/gps it's bad way (not accurate). It's widely used for testing purposes + // possibly keep using only for emulator case + if (location != null) { + if (location.distanceTo(location) > 3) { + float d = location.distanceTo(location); + long time = location.getTime() - location.getTime(); + float speed; + if (time == 0) { + speed = 0; + } else { + speed = ((float) d * 1000) / time; + } + // Be aware only for emulator ! code is incorrect in case of airplane + if (speed > 100) { + speed = 100; + } + location.setSpeed(speed); + } + } + } + + public static boolean isPointAccurateForRouting(net.osmand.Location loc) { + return loc != null && (!loc.hasAccuracy() || loc.getAccuracy() < ACCURACY_FOR_GPX_AND_ROUTING * 3 / 2); + } + + private boolean isRunningOnEmulator() { + if (Build.DEVICE.equals("generic")) { //$NON-NLS-1$ + return true; + } + return false; + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) { + } + + @Override + public void onSensorChanged(SensorEvent event) { + // Attention : sensor produces a lot of events & can hang the system + float val = 0; + switch (event.sensor.getType()) { + case Sensor.TYPE_ACCELEROMETER: + if (mGravs == null) { + mGravs = new float[3]; + } + System.arraycopy(event.values, 0, mGravs, 0, 3); + break; + case Sensor.TYPE_MAGNETIC_FIELD: + if (mGeoMags == null) { + mGeoMags = new float[3]; + } + System.arraycopy(event.values, 0, mGeoMags, 0, 3); + break; + case Sensor.TYPE_ORIENTATION: + val = event.values[0]; + if (mGravs != null && mGeoMags != null) { + return; + } + break; + default: + return; + } + if (mGravs != null && mGeoMags != null) { + float[] mRotationM = new float[9]; + boolean success = SensorManager.getRotationMatrix(mRotationM, null, mGravs, mGeoMags); + if (!success) { + return; + } + float[] orientation = SensorManager.getOrientation(mRotationM, new float[3]); + val = (float) Math.toDegrees(orientation[0]); + } + + if (currentScreenOrientation == 1) { + val += 90; + } else if (currentScreenOrientation == 2) { + val += 180; + } else if (currentScreenOrientation == 3) { + val -= 90; + } + val = MapUtils.unifyRotationTo360(val); + if (previousCorrectionValue == 360 && getLastKnownLocation() != null) { + net.osmand.Location l = getLastKnownLocation(); + GeomagneticField gf = new GeomagneticField((float) l.getLatitude(), (float) l.getLongitude(), (float) l.getAltitude(), + System.currentTimeMillis()); + previousCorrectionValue = gf.getDeclination(); + } + if (previousCorrectionValue != 360) { + val += previousCorrectionValue; + } + + heading = val; + updateCompassValue(val); + + } + + private void updateCompassValue(float val) { + for(OsmAndCompassListener c : compassListeners){ + c.updateCompassValue(val); + } + } + + private void updateLocation(net.osmand.Location loc ) { + for(OsmAndLocationListener l : locationListeners){ + l.updateLocation(loc); + } + } + + + + private LocationListener gpsListener = new LocationListener() { + @Override + public void onLocationChanged(Location location) { + if (location != null) { + lastTimeGPSLocationFixed = location.getTime(); + } + if(!locationSimulation.isRouteAnimating()) { + setLocation(convertLocation(location, app)); + } + } + + @Override + public void onProviderDisabled(String provider) { + } + + @Override + public void onProviderEnabled(String provider) { + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + } + }; + + private boolean useOnlyGPS() { + if(app.getRoutingHelper().isFollowingMode()) { + return true; + } + if((System.currentTimeMillis() - lastTimeGPSLocationFixed) < NOT_SWITCH_TO_NETWORK_WHEN_GPS_LOST_MS) { + return true; + } + if(isRunningOnEmulator()) { + return true; + } + return false; + } + + // Working with location listeners + private LocationListener networkListener = new LocationListener() { + + @Override + public void onLocationChanged(Location location) { + // double check about use only gps + // that strange situation but it could happen? + if (!useOnlyGPS() && !locationSimulation.isRouteAnimating()) { + setLocation(convertLocation(location, app)); + } + } + + @Override + public void onProviderDisabled(String provider) { + } + + @Override + public void onProviderEnabled(String provider) { + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + } + + }; + + private void stopLocationRequests() { + LocationManager service = (LocationManager) app.getSystemService(Context.LOCATION_SERVICE); + service.removeGpsStatusListener(gpsStatusListener); + service.removeUpdates(gpsListener); + service.removeUpdates(networkListener); + } + + public void pauseAllUpdates() { + stopLocationRequests(); + SensorManager sensorMgr = (SensorManager) app.getSystemService(Context.SENSOR_SERVICE); + sensorMgr.unregisterListener(this); + sensorRegistered = false; + } + + public static net.osmand.Location convertLocation(Location l, OsmandApplication app) { + if (l == null) { + return null; + } + net.osmand.Location r = new net.osmand.Location(l.getProvider()); + r.setLatitude(l.getLatitude()); + r.setLongitude(l.getLongitude()); + r.setTime(l.getTime()); + if (l.hasAccuracy()) { + r.setAccuracy(l.getAccuracy()); + } + if (l.hasSpeed()) { + r.setSpeed(l.getSpeed()); + } + if (l.hasAltitude()) { + r.setAltitude(l.getAltitude()); + } + if (l.hasBearing()) { + r.setBearing(l.getBearing()); + } + if (l.hasAltitude() && app != null) { + double alt = l.getAltitude(); + final GeoidAltitudeCorrection geo = app.getResourceManager().getGeoidAltitudeCorrection(); + if (geo != null) { + alt -= geo.getGeoidHeight(l.getLatitude(), l.getLongitude()); + r.setAltitude(alt); + } + } + return r; + } + + + private void scheduleCheckIfGpsLost(net.osmand.Location location) { + final RoutingHelper routingHelper = app.getRoutingHelper(); + if (location != null) { + final long fixTime = location.getTime(); + app.runMessageInUIThreadAndCancelPrevious(LOST_LOCATION_MSG_ID, new Runnable() { + + @Override + public void run() { + net.osmand.Location lastKnown = getLastKnownLocation(); + if (lastKnown != null && lastKnown.getTime() > fixTime) { + // false positive case, still strange how we got here with removeMessages + return; + } + if (routingHelper.isFollowingMode() && routingHelper.getLeftDistance() > 0) { + routingHelper.getVoiceRouter().gpsLocationLost(); + } + setLocation(null); + } + }, LOST_LOCATION_CHECK_DELAY); + } + } + public void setLocationFromService(net.osmand.Location location, boolean continuous) { + // if continuous notify about lost location + if (continuous) { + scheduleCheckIfGpsLost(location); + } + app.getSavingTrackHelper().updateLocation(location); + app.getLiveMonitoringHelper().updateLocation(location); + // 2. accessibility routing + navigationInfo.setLocation(location); + + app.getRoutingHelper().updateLocation(location); + } + + public void setLocationFromSimulation(net.osmand.Location location) { + setLocation(location); + } + + private void setLocation(net.osmand.Location location) { + if(location == null){ + updateGPSInfo(null); + } + enhanceLocation(location); + scheduleCheckIfGpsLost(location); + final RoutingHelper routingHelper = app.getRoutingHelper(); + // 1. Logging services + if (location != null) { + app.getSavingTrackHelper().updateLocation(location); + app.getLiveMonitoringHelper().updateLocation(location); + } + // 2. accessibility routing + navigationInfo.setLocation(location); + + // 3. routing + net.osmand.Location updatedLocation = location; + if (routingHelper.isFollowingMode()) { + if (location == null || isPointAccurateForRouting(location)) { + // Update routing position and get location for sticking mode + updatedLocation = routingHelper.setCurrentLocation(location, settings.SNAP_TO_ROAD.get()); + } + } + this.location = updatedLocation; + + // Update information + updateLocation(location); + } + + private void enhanceLocation(net.osmand.Location location) { + if (location != null && isRunningOnEmulator()) { + // only for emulator + updateSpeedEmulator(location); + } + } + + public void checkIfLastKnownLocationIsValid() { + net.osmand.Location loc = getLastKnownLocation(); + if (loc != null && (System.currentTimeMillis() - loc.getTime()) > INTERVAL_TO_CLEAR_SET_LOCATION) { + setLocation(null); + } + } + + public NavigationInfo getNavigationInfo() { + return navigationInfo; + } + + public String getNavigationHint(LatLon point) { + String hint = navigationInfo.getDirectionString(point, getHeading()); + if (hint == null) + hint = app.getString(R.string.no_info); + return hint; + } + + public void emitNavigationHint() { + final LatLon point = app.getTargetPointsHelper().getPointToNavigate(); + if (point != null) { + if (app.getRoutingHelper().isRouteCalculated()) { + app.getRoutingHelper().getVoiceRouter().announceCurrentDirection(getLastKnownLocation()); + } else { + app.showToastMessage(getNavigationHint(point)); + } + } else { + app.showToastMessage(R.string.mark_final_location_first); + } + } + + public RouteDataObject getLastKnownRouteSegment() { + return currentPositionHelper.getLastKnownRouteSegment(getLastKnownLocation()); + } + + public net.osmand.Location getLastKnownLocation() { + return location; + } + + public Float getHeading() { + return heading; + } + + public void showNavigationInfo(LatLon pointToNavigate, Context uiActivity) { + getNavigationInfo().show(pointToNavigate, getHeading(), uiActivity); + + } + + public OsmAndLocationSimulation getLocationSimulation() { + return locationSimulation; + } + + + public static class GPSInfo { + public int foundSatellites = 0; + public int usedSatellites = 0; + public boolean fixed = false; + } + +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteAnimation.java b/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java similarity index 83% rename from OsmAnd/src/net/osmand/plus/routing/RouteAnimation.java rename to OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java index 641ef4c34a..49d280d2b7 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteAnimation.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndLocationSimulation.java @@ -1,4 +1,4 @@ -package net.osmand.plus.routing; +package net.osmand.plus; import java.util.ArrayList; @@ -7,9 +7,10 @@ import java.util.List; import net.osmand.CallbackWithObject; import net.osmand.Location; import net.osmand.plus.GPXUtilities; -import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.routing.RouteProvider; +import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RouteProvider.GPXRouteParams; import android.app.AlertDialog; import android.app.AlertDialog.Builder; @@ -18,16 +19,22 @@ import android.view.View; import android.widget.SeekBar; import android.widget.TextView; -public class RouteAnimation { +public class OsmAndLocationSimulation { private Thread routeAnimation; + private OsmAndLocationProvider provider; + private OsmandApplication app; + + public OsmAndLocationSimulation(OsmandApplication app, OsmAndLocationProvider provider){ + this.app = app; + this.provider = provider; + } public boolean isRouteAnimating() { return routeAnimation != null; } - public void startStopRouteAnimation(final RoutingHelper routingHelper, - final MapActivity ma) { + public void startStopRouteAnimation(final MapActivity ma) { if (!isRouteAnimating()) { Builder builder = new AlertDialog.Builder(ma); builder.setTitle(R.string.animate_routing_using_gpx); @@ -45,9 +52,9 @@ public class RouteAnimation { @Override public boolean processResult(GPXUtilities.GPXFile result) { - GPXRouteParams prms = new RouteProvider.GPXRouteParams(result, false, ((OsmandApplication) ma.getApplication()).getSettings()); - ma.stopLocationRequests(); - startAnimationThread(routingHelper, ma, prms.points, true, speedup.getProgress() + 1); + GPXRouteParams prms = new RouteProvider.GPXRouteParams(result, false, + app.getSettings()); + startAnimationThread(app.getRoutingHelper(), ma, prms.getPoints(), true, speedup.getProgress() + 1); return true; } }); @@ -58,19 +65,18 @@ public class RouteAnimation { @Override public void onClick(DialogInterface dialog, int which) { - ma.stopLocationRequests(); - startAnimationThread(routingHelper, ma, new ArrayList(routingHelper.getCurrentRoute()), false, 1); - + startAnimationThread(app.getRoutingHelper(), ma, + new ArrayList(app.getRoutingHelper().getCurrentRoute()), false, 1); } }); builder.show(); } else { stop(); - ma.startLocationRequests(); } } - private void startAnimationThread(final RoutingHelper routingHelper, final MapActivity ma, final List directions, final boolean useLocationTime, final float coeff) { + private void startAnimationThread(final RoutingHelper routingHelper, + final MapActivity ma, final List directions, final boolean useLocationTime, final float coeff) { final float time = 1.5f; routeAnimation = new Thread() { @Override @@ -113,7 +119,7 @@ public class RouteAnimation { ma.runOnUiThread(new Runnable() { @Override public void run() { - ma.setLocation(toset); + provider.setLocationFromSimulation(toset); } }); try { @@ -123,7 +129,7 @@ public class RouteAnimation { } prev = current; } - RouteAnimation.this.stop(); + OsmAndLocationSimulation.this.stop(); } }; diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java index 449136a5b0..1c144c4f36 100644 --- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java +++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Locale; import net.osmand.IndexConstants; +import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.access.AccessibleToast; import net.osmand.data.FavouritePoint; @@ -50,6 +51,7 @@ import android.content.pm.PackageInfo; import android.content.res.Configuration; import android.os.Build; import android.os.Handler; +import android.os.Message; import android.text.format.DateFormat; import android.widget.Toast; @@ -71,6 +73,7 @@ public class OsmandApplication extends Application implements ClientContext { NavigationService navigationService; RendererRegistry rendererRegistry; BidForFixHelper bidforfix; + OsmAndLocationProvider locationProvider; // start variables private ProgressDialogImplementation startDialog; @@ -100,18 +103,22 @@ public class OsmandApplication extends Application implements ClientContext { internalOsmAndAPI = new net.osmand.plus.api.InternalOsmAndAPIImpl(this); sqliteAPI = new SQLiteAPIImpl(this); - + // settings used everywhere so they need to be created first osmandSettings = createOsmandSettingsInstance(); + // always update application mode to default + osmandSettings.APPLICATION_MODE.set(osmandSettings.DEFAULT_APPLICATION_MODE.get()); + routingHelper = new RoutingHelper(this, player); manager = new ResourceManager(this); daynightHelper = new DayNightHelper(this); + locationProvider = new OsmAndLocationProvider(this); bidforfix = new BidForFixHelper("osmand.net", getString(R.string.default_buttons_support), getString(R.string.default_buttons_cancel)); savingTrackHelper = new SavingTrackHelper(this); liveMonitoringHelper = new LiveMonitoringHelper(this); uiHandler = new Handler(); rendererRegistry = new RendererRegistry(); - targetPointsHelper = new TargetPointsHelper(osmandSettings, routingHelper); + targetPointsHelper = new TargetPointsHelper(this); checkPrefferedLocale(); startApplication(); if (LOG.isDebugEnabled()) { @@ -150,6 +157,10 @@ public class OsmandApplication extends Application implements ClientContext { protected OsmandSettings createOsmandSettingsInstance() { return new OsmandSettings(this); } + + public OsmAndLocationProvider getLocationProvider() { + return locationProvider; + } /** * Application settings @@ -491,7 +502,6 @@ public class OsmandApplication extends Application implements ClientContext { startDialog.startTask(getString(R.string.saving_gpx_tracks), -1); warnings.addAll(savingTrackHelper.saveDataToGpx()); } - savingTrackHelper.close(); // restore backuped favorites to normal file final File appDir = getAppPath(null); @@ -612,6 +622,11 @@ public class OsmandApplication extends Application implements ClientContext { public TargetPointsHelper getTargetPointsHelper() { return targetPointsHelper; } + + @Override + public void showShortToastMessage(int msgId, Object... args) { + AccessibleToast.makeText(this, getString(msgId, args), Toast.LENGTH_SHORT).show(); + } @Override public void showToastMessage(int msgId, Object... args) { @@ -657,7 +672,22 @@ public class OsmandApplication extends Application implements ClientContext { public void runInUIThread(Runnable run, long delay) { uiHandler.postDelayed(run, delay); } - + + public void runMessageInUIThreadAndCancelPrevious(final int messageId, final Runnable run, long delay) { + Message msg = Message.obtain(uiHandler, new Runnable() { + + @Override + public void run() { + if(!uiHandler.hasMessages(messageId)) { + run.run(); + } + } + }); + msg.what = messageId; + uiHandler.removeMessages(messageId); + uiHandler.sendMessageDelayed(msg, delay); + } + @Override public File getAppPath(String path) { if(path == null) { @@ -666,4 +696,9 @@ public class OsmandApplication extends Application implements ClientContext { return new File(getSettings().getExternalStorageDirectory(), IndexConstants.APP_DIR + path); } + @Override + public Location getLastKnownLocation() { + return locationProvider.getLastKnownLocation(); + } + } diff --git a/OsmAnd/src/net/osmand/plus/activities/DayNightHelper.java b/OsmAnd/src/net/osmand/plus/activities/DayNightHelper.java index 67ef91bef8..caba39b031 100644 --- a/OsmAnd/src/net/osmand/plus/activities/DayNightHelper.java +++ b/OsmAnd/src/net/osmand/plus/activities/DayNightHelper.java @@ -1,12 +1,14 @@ package net.osmand.plus.activities; -import java.util.ArrayList; + import java.util.Date; import java.util.List; import java.util.TimeZone; +import net.osmand.Location; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandSettings.CommonPreference; import net.osmand.plus.OsmandSettings.DayNightMode; import net.osmand.util.SunriseSunset; @@ -17,7 +19,6 @@ import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; -import android.location.Location; import android.location.LocationManager; /** @@ -42,34 +43,26 @@ public class DayNightHelper implements SensorEventListener { private final OsmandApplication osmandApplication; + private CommonPreference pref; + public DayNightHelper(OsmandApplication osmandApplication) { this.osmandApplication = osmandApplication; - setDayNightMode(osmandApplication.getSettings().DAYNIGHT_MODE.get()); + pref = osmandApplication.getSettings().DAYNIGHT_MODE; } - DayNightMode dayNightMode = DayNightMode.AUTO; private DayNightHelper listener; private float lux = SensorManager.LIGHT_SUNLIGHT; private long lastAutoCall = 0; private Boolean lastAutoValue = null; - public void setDayNightMode(DayNightMode mode) { - if (this.dayNightMode != mode) { - this.dayNightMode = mode; - osmandApplication.getResourceManager().getRenderer().clearCache(); - unregisterServiceListener(); - if(dayNightMode.isSensor()){ - registerServiceListener(); - } - } - } /** * @return null if could not be determined (in case of error) * @return true if day is supposed to be */ public Boolean getDayNightRenderer() { + DayNightMode dayNightMode = pref.get(); if (dayNightMode.isDay()) { return Boolean.TRUE; } else if (dayNightMode.isNight()) { @@ -118,31 +111,14 @@ public class DayNightHelper implements SensorEventListener { } private Location getLocation() { - Location lastKnownLocation = null; - LocationManager locationProvider = (LocationManager) osmandApplication.getSystemService(Context.LOCATION_SERVICE); - List providers = new ArrayList(locationProvider.getProviders(true)); - //note, passive provider is from API_LEVEL 8 but it is a constant, we can check for it. - // constant should not be changed in future - int passiveFirst = providers.indexOf("passive"); //LocationManager.PASSIVE_PROVIDER - //put passive provider to first place - if (passiveFirst > -1) { - providers.add(0,providers.remove(passiveFirst)); - } - //find location - for (String provider : providers) { - lastKnownLocation = locationProvider.getLastKnownLocation(provider); - if (lastKnownLocation != null) { - break; - } + Location lastKnownLocation = osmandApplication.getLocationProvider().getLastKnownLocation(); + if(lastKnownLocation == null) { + lastKnownLocation = osmandApplication.getLocationProvider().getFirstTimeRunDefaultLocation(); } return lastKnownLocation; } - public void onMapPause() { - unregisterServiceListener(); - } - - private void unregisterServiceListener() { + public void stopSensorIfNeeded() { if (listener != null) { SensorManager mSensorManager = (SensorManager) osmandApplication .getSystemService(Context.SENSOR_SERVICE); @@ -152,22 +128,20 @@ public class DayNightHelper implements SensorEventListener { } } - public void onMapResume() { - registerServiceListener(); - } - - private void registerServiceListener() { + public void startSensorIfNeeded() { + DayNightMode dayNightMode = pref.get(); if (listener == null && dayNightMode.isSensor()) { SensorManager mSensorManager = (SensorManager) osmandApplication.getSystemService(Context.SENSOR_SERVICE); Sensor mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); List list = mSensorManager.getSensorList(Sensor.TYPE_LIGHT); log.info("Light sensors:" + list.size()); //$NON-NLS-1$ - mSensorManager.registerListener(this, mLight, - SensorManager.SENSOR_DELAY_NORMAL); + mSensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL); listener = this; + } else if (listener != null && !dayNightMode.isSensor()) { + stopSensorIfNeeded(); } } - + @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // nothing to do here diff --git a/OsmAnd/src/net/osmand/plus/activities/IntermediatePointsDialog.java b/OsmAnd/src/net/osmand/plus/activities/IntermediatePointsDialog.java index 892c220c21..0c8682ee80 100644 --- a/OsmAnd/src/net/osmand/plus/activities/IntermediatePointsDialog.java +++ b/OsmAnd/src/net/osmand/plus/activities/IntermediatePointsDialog.java @@ -130,9 +130,9 @@ public class IntermediatePointsDialog { @Override public void onClick(DialogInterface dialog, int which) { if(changeOrder) { - commitChangePointsOrder(app, activity, intermediates, names); + commitChangePointsOrder(app, intermediates, names); } else { - commitPointsRemoval(app, activity, checkedIntermediates); + commitPointsRemoval(app, checkedIntermediates); } } @@ -148,7 +148,7 @@ public class IntermediatePointsDialog { builder.show(); } - private static void commitPointsRemoval(OsmandApplication app, final Activity mapActivity, final boolean[] checkedIntermediates) { + private static void commitPointsRemoval(OsmandApplication app, final boolean[] checkedIntermediates) { int cnt = 0; for (int i = checkedIntermediates.length - 1; i >= 0; i--) { if (!checkedIntermediates[i]) { @@ -158,25 +158,26 @@ public class IntermediatePointsDialog { if (cnt > 0) { boolean changeDestinationFlag =!checkedIntermediates [checkedIntermediates.length - 1]; if(cnt == checkedIntermediates.length){ //there is no alternative destination if all points are to be removed? - app.getTargetPointsHelper().removeAllWayPoints((MapActivity) (mapActivity instanceof MapActivity?mapActivity : null), true); + app.getTargetPointsHelper().removeAllWayPoints(true); }else{ for (int i = checkedIntermediates.length - 2; i >= 0; i--) { //skip the destination until a retained waypoint is found if (checkedIntermediates[i] && changeDestinationFlag) { //Find a valid replacement for the destination - app.getTargetPointsHelper().makeWayPointDestination((MapActivity) (mapActivity instanceof MapActivity?mapActivity : null), cnt == 0, i); + app.getTargetPointsHelper().makeWayPointDestination(cnt == 0, i); changeDestinationFlag = false; }else if(!checkedIntermediates[i]){ cnt--; - app.getTargetPointsHelper().removeWayPoint((MapActivity) (mapActivity instanceof MapActivity?mapActivity : null), cnt == 0, i); + app.getTargetPointsHelper().removeWayPoint(cnt == 0, i); } } - if(mapActivity instanceof MapActivity) { - ((MapActivity) mapActivity).getMapLayers().getContextMenuLayer().setLocation(null, ""); - } + // FIXME +// if(mapActivity instanceof MapActivity) { +// ((MapActivity) mapActivity).getMapLayers().getContextMenuLayer().setLocation(null, ""); +// } } } } - private static void commitChangePointsOrder(OsmandApplication app, final Activity mapActivity, List target, List names) { + private static void commitChangePointsOrder(OsmandApplication app, List target, List names) { TargetPointsHelper targets = app.getTargetPointsHelper(); List cur = targets.getIntermediatePointsWithTarget(); boolean eq = true; @@ -187,7 +188,7 @@ public class IntermediatePointsDialog { } } if(!eq) { - targets.reorderAllTargetPoints((MapActivity) (mapActivity instanceof MapActivity?mapActivity : null), target, names, true); + targets.reorderAllTargetPoints(target, names, true); } } } diff --git a/OsmAnd/src/net/osmand/plus/activities/LiveMonitoringHelper.java b/OsmAnd/src/net/osmand/plus/activities/LiveMonitoringHelper.java index bfc06c28d8..8341930958 100644 --- a/OsmAnd/src/net/osmand/plus/activities/LiveMonitoringHelper.java +++ b/OsmAnd/src/net/osmand/plus/activities/LiveMonitoringHelper.java @@ -8,9 +8,12 @@ import java.util.ArrayList; import java.util.List; import net.osmand.PlatformUtil; +import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; +import net.osmand.plus.monitoring.OsmandMonitoringPlugin; import org.apache.commons.logging.Log; import org.apache.http.HttpResponse; @@ -40,6 +43,16 @@ public class LiveMonitoringHelper { return settings.LIVE_MONITORING.get(); } + public void updateLocation(net.osmand.Location location) { + if (OsmAndLocationProvider.isPointAccurateForRouting(location) && isLiveMonitoringEnabled() + && OsmandPlugin.getEnabledPlugin(OsmandMonitoringPlugin.class) != null) { + long locationTime = System.currentTimeMillis(); + insertData(location.getLatitude(), location.getLongitude(), location.getAltitude(), + location.getSpeed(), location.getAccuracy(), locationTime, settings); + } + + } + public void insertData(double lat, double lon, double alt, double speed, double hdop, long time, OsmandSettings settings){ //* 1000 in next line seems to be wrong with new IntervalChooseDialog //if (time - lastTimeUpdated > settings.LIVE_MONITORING_INTERVAL.get() * 1000) { diff --git a/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java b/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java index 73e773576c..c37b866aec 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java @@ -5,6 +5,7 @@ import java.text.MessageFormat; import java.util.Random; import net.osmand.access.AccessibleAlertBuilder; +import net.osmand.data.LatLon; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.Version; @@ -21,6 +22,8 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -35,6 +38,7 @@ import android.view.View.OnClickListener; import android.view.Window; import android.view.animation.AccelerateInterpolator; import android.view.animation.Animation; +import android.view.animation.Transformation; import android.view.animation.TranslateAnimation; import android.widget.TextView; @@ -364,6 +368,98 @@ public class MainMenuActivity extends Activity { } return super.onKeyDown(keyCode, event); } + + public static void backToMainMenuDialog(final Activity a, final LatLon searchLocation) { + final Dialog dlg = new Dialog(a, R.style.Dialog_Fullscreen); + final View menuView = (View) a.getLayoutInflater().inflate(R.layout.menu, null); + menuView.setBackgroundColor(Color.argb(200, 150, 150, 150)); + dlg.setContentView(menuView); + MainMenuActivity.onCreateMainMenu(dlg.getWindow(), a); + Animation anim = new Animation() { + @Override + protected void applyTransformation(float interpolatedTime, Transformation t) { + ColorDrawable colorDraw = ((ColorDrawable) menuView.getBackground()); + colorDraw.setAlpha((int) (interpolatedTime * 200)); + } + }; + anim.setDuration(700); + anim.setInterpolator(new AccelerateInterpolator()); + menuView.setAnimation(anim); + + View showMap = dlg.findViewById(R.id.MapButton); + showMap.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + dlg.dismiss(); + } + }); + View settingsButton = dlg.findViewById(R.id.SettingsButton); + settingsButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + final Intent settings = new Intent(a, OsmandIntents.getSettingsActivity()); + a.startActivity(settings); + dlg.dismiss(); + } + }); + + View favouritesButton = dlg.findViewById(R.id.FavoritesButton); + favouritesButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + final Intent favorites = new Intent(a, OsmandIntents.getFavoritesActivity()); + favorites.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + a.startActivity(favorites); + dlg.dismiss(); + } + }); + + View closeButton = dlg.findViewById(R.id.CloseButton); + closeButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + dlg.dismiss(); + // 1. Work for almost all cases when user open apps from main menu + Intent newIntent = new Intent(a, OsmandIntents.getMainMenuActivity()); + newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + newIntent.putExtra(MainMenuActivity.APP_EXIT_KEY, MainMenuActivity.APP_EXIT_CODE); + a.startActivity(newIntent); + // 2. good analogue but user will come back to the current activity onResume() + // so application is not reloaded !!! + // moveTaskToBack(true); + // 3. bad results if user comes from favorites + // a.setResult(MainMenuActivity.APP_EXIT_CODE); + // a.finish(); + } + }); + + View searchButton = dlg.findViewById(R.id.SearchButton); + searchButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + final Intent search = new Intent(a, OsmandIntents.getSearchActivity()); + LatLon loc = searchLocation; + search.putExtra(SearchActivity.SEARCH_LAT, loc.getLatitude()); + search.putExtra(SearchActivity.SEARCH_LON, loc.getLongitude()); + // causes wrong position caching: search.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + search.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + a.startActivity(search); + dlg.dismiss(); + } + }); + menuView.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + dlg.dismiss(); + } + }); + + dlg.show(); + // Intent newIntent = new Intent(a, MainMenuActivity.class); + // newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + // startActivity(newIntent); + } @Override diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 1cd745e749..dd073a4d16 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -1,33 +1,23 @@ package net.osmand.plus.activities; -import java.io.File; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import net.osmand.GeoidAltitudeCorrection; -import net.osmand.PlatformUtil; +import net.osmand.StateChangedListener; import net.osmand.access.AccessibilityPlugin; import net.osmand.access.AccessibleActivity; -import net.osmand.access.AccessibleAlertBuilder; import net.osmand.access.AccessibleToast; import net.osmand.access.MapAccessibilityActions; -import net.osmand.access.NavigationInfo; import net.osmand.binary.RouteDataObject; -import net.osmand.map.IMapLocationListener; +import net.osmand.data.LatLon; import net.osmand.map.MapTileDownloader.DownloadRequest; import net.osmand.map.MapTileDownloader.IMapDownloaderCallback; -import net.osmand.data.LatLon; -import net.osmand.util.MapUtils; import net.osmand.plus.ApplicationMode; import net.osmand.plus.BusyIndicator; -import net.osmand.plus.CurrentPositionHelper; -import net.osmand.plus.FavouritesDbHelper; -import net.osmand.plus.GPXUtilities; -import net.osmand.plus.GPXUtilities.GPXFile; -import net.osmand.plus.MapScreen; +import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandSettings; @@ -37,17 +27,17 @@ import net.osmand.plus.ResourceManager; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.Version; import net.osmand.plus.activities.search.SearchActivity; -import net.osmand.plus.monitoring.OsmandMonitoringPlugin; +import net.osmand.plus.base.FailSafeFuntions; +import net.osmand.plus.base.MapViewTrackingUtilities; +import net.osmand.plus.render.RendererRegistry; import net.osmand.plus.routing.RouteProvider.GPXRouteParams; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper.RouteCalculationProgressCallback; import net.osmand.plus.views.AnimateDraggingMapThread; import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.OsmandMapTileView; -import net.osmand.plus.views.PointLocationLayer; +import net.osmand.render.RenderingRulesStorage; import net.osmand.util.Algorithms; -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.Notification; import android.app.NotificationManager; @@ -55,134 +45,82 @@ import android.app.PendingIntent; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; -import android.content.DialogInterface.OnCancelListener; -import android.content.DialogInterface.OnDismissListener; import android.content.Intent; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; -import android.hardware.GeomagneticField; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.location.LocationProvider; import android.media.AudioManager; import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.util.DisplayMetrics; -import android.util.Log; import android.view.Gravity; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.view.Window; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.Animation; -import android.view.animation.Transformation; import android.widget.FrameLayout; import android.widget.ProgressBar; -import android.widget.TextView; import android.widget.Toast; -public class MapActivity extends AccessibleActivity implements IMapLocationListener, SensorEventListener, MapScreen { - - // stupid error but anyway hero 2.1 : always lost gps signal (temporarily unavailable) for timeout = 2000 - private static final int GPS_TIMEOUT_REQUEST = 0; - private static final int GPS_DIST_REQUEST = 0; - // use only gps (not network) for 12 seconds - private static final int USE_ONLY_GPS_INTERVAL = 12000; +public class MapActivity extends AccessibleActivity { private static final int SHOW_POSITION_MSG_ID = 7; - private static final int SHOW_POSITION_DELAY = 2500; - public static final float ACCURACY_FOR_GPX_AND_ROUTING = 50; - - private static final int AUTO_FOLLOW_MSG_ID = 8; - private static final int LOST_LOCATION_MSG_ID = 10; - private static final long LOST_LOCATION_CHECK_DELAY = 18000; - private static final int LONG_KEYPRESS_MSG_ID = 28; private static final int LONG_KEYPRESS_DELAY = 500; - private long lastTimeAutoZooming = 0; - private long lastTimeSensorRotation = 0; - private long lastTimeGPSLocationFixed = 0; + private static MapViewTrackingUtilities mapViewTrackingUtilities; /** Called when the activity is first created. */ private OsmandMapTileView mapView; + private MapActivityActions mapActions; private MapActivityLayers mapLayers; - private CurrentPositionHelper currentPositionHelper; - private NavigationInfo navigationInfo; - private SavingTrackHelper savingTrackHelper; - private LiveMonitoringHelper liveMonitoringHelper; - private RoutingHelper routingHelper; - - private boolean sensorRegistered = false; - private float previousSensorValue = 0; - private float[] mGravs; - private float[] mGeoMags; - private float previousCorrectionValue = 360; - private boolean quitRouteRestoreDialog = false; - // Notification status private NotificationManager mNotificationManager; private int APP_NOTIFICATION_ID = 1; + // handler to show/hide trackball position and to link map with delay private Handler uiHandler = new Handler(); - // Current screen orientation - private int currentScreenOrientation; - // - private Dialog progressDlg = null; - // App settings + // App variables + private OsmandApplication app; private OsmandSettings settings; - // by default turn off causing unexpected movements due to network establishing - private static boolean isMapLinkedToLocation = false; + private Dialog progressDlg = null; private ProgressDialog startProgressDialog; private List dialogProviders = new ArrayList(2); + private StateChangedListener applicationModeListener; - private Notification getNotification(){ + + private Notification getNotification() { Intent notificationIndent = new Intent(this, OsmandIntents.getMapActivity()); notificationIndent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); Notification notification = new Notification(R.drawable.icon, "", //$NON-NLS-1$ System.currentTimeMillis()); notification.flags |= Notification.FLAG_AUTO_CANCEL; - notification.setLatestEventInfo(this, Version.getAppName(getMyApplication()), - getString(R.string.go_back_to_osmand), PendingIntent.getActivity( - this, 0, notificationIndent, - PendingIntent.FLAG_UPDATE_CURRENT)); + notification.setLatestEventInfo(this, Version.getAppName(app), getString(R.string.go_back_to_osmand), + PendingIntent.getActivity(this, 0, notificationIndent, PendingIntent.FLAG_UPDATE_CURRENT)); return notification; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - settings = getMyApplication().getSettings(); + app = getMyApplication(); + settings = app.getSettings(); mapActions = new MapActivityActions(this); mapLayers = new MapActivityLayers(this); - currentPositionHelper = new CurrentPositionHelper(getMyApplication()); - navigationInfo = new NavigationInfo(this); requestWindowFeature(Window.FEATURE_NO_TITLE); // Full screen is not used here //getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.main); startProgressDialog = new ProgressDialog(this); startProgressDialog.setCancelable(true); - ((OsmandApplication) getApplication()).checkApplicationIsBeingInitialized(this, startProgressDialog); + app.checkApplicationIsBeingInitialized(this, startProgressDialog); parseLaunchIntentLocation(); mapView = (OsmandMapTileView) findViewById(R.id.MapView); @@ -194,21 +132,25 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe } }); mapView.setAccessibilityActions(new MapAccessibilityActions(this)); + if(mapViewTrackingUtilities == null) { + mapViewTrackingUtilities = new MapViewTrackingUtilities(app); + } + mapViewTrackingUtilities.setMapView(mapView); // Do some action on close startProgressDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { - getMyApplication().getResourceManager().getRenderer().clearCache(); + app.getResourceManager().getRenderer().clearCache(); mapView.refreshMap(true); } }); - getMyApplication().getResourceManager().getMapTileDownloader().addDownloaderCallback(new IMapDownloaderCallback(){ + app.getResourceManager().getMapTileDownloader().addDownloaderCallback(new IMapDownloaderCallback(){ @Override public void tileDownloaded(DownloadRequest request) { if(request != null && !request.error && request.fileToSave != null){ - ResourceManager mgr = getMyApplication().getResourceManager(); + ResourceManager mgr = app.getResourceManager(); mgr.tileDownloaded(request); } if(request == null || !request.error){ @@ -216,37 +158,19 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe } } }); - - - savingTrackHelper = getMyApplication().getSavingTrackHelper(); - liveMonitoringHelper = getMyApplication().getLiveMonitoringHelper(); - routingHelper = getMyApplication().getRoutingHelper(); createProgressBarForRouting(); // This situtation could be when navigation suddenly crashed and after restarting // it tries to continue the last route - if(settings.FOLLOW_THE_ROUTE.get() && !routingHelper.isRouteCalculated()){ - restoreRoutingMode(); + if(settings.FOLLOW_THE_ROUTE.get() && !app.getRoutingHelper().isRouteCalculated()){ + FailSafeFuntions.restoreRoutingMode(this); } - mapView.setMapLocationListener(this); + mapLayers.createLayers(mapView); if(!settings.isLastKnownMapLocation()){ // show first time when application ran - LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); - Location location = null; - for (String provider : service.getAllProviders()) { - try { - Location loc = service.getLastKnownLocation(provider); - if (location == null) { - location = loc; - } else if (loc != null && location.getTime() < loc.getTime()) { - location = loc; - } - } catch (IllegalArgumentException e) { - Log.d(PlatformUtil.TAG, "Location provider not available"); //$NON-NLS-1$ - } - } + net.osmand.Location location = app.getLocationProvider().getFirstTimeRunDefaultLocation(); if(location != null){ mapView.setLatLon(location.getLatitude(), location.getLongitude()); mapView.setZoom(14); @@ -270,7 +194,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe pb.setVisibility(View.GONE); parent.addView(pb); - routingHelper.setProgressBar(new RouteCalculationProgressCallback() { + app.getRoutingHelper().setProgressBar(new RouteCalculationProgressCallback() { @Override public void updateProgress(int progress) { @@ -311,19 +235,12 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe protected void onResume() { super.onResume(); cancelNotification(); - if (settings.MAP_SCREEN_ORIENTATION.get() != getRequestedOrientation()) { setRequestedOrientation(settings.MAP_SCREEN_ORIENTATION.get()); // can't return from this method we are not sure if activity will be recreated or not } - net.osmand.Location loc = getLastKnownLocation(); - if (loc != null && (System.currentTimeMillis() - loc.getTime()) > 30 * 1000) { - setLocation(null); - } - - currentScreenOrientation = getWindow().getWindowManager().getDefaultDisplay().getOrientation(); - + app.getLocationProvider().checkIfLastKnownLocationIsValid(); // for voice navigation if (settings.AUDIO_STREAM_GUIDANCE.get() != null) { setVolumeControlStream(settings.AUDIO_STREAM_GUIDANCE.get()); @@ -331,30 +248,35 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe setVolumeControlStream(AudioManager.STREAM_MUSIC); } + applicationModeListener = new StateChangedListener() { + @Override + public void stateChanged(ApplicationMode change) { + updateApplicationModeSettings(); + } + }; + settings.APPLICATION_MODE.addListener(applicationModeListener); updateApplicationModeSettings(); String filterId = settings.getPoiFilterForMap(); - PoiFilter poiFilter = getMyApplication().getPoiFilters().getFilterById(filterId); + PoiFilter poiFilter = app.getPoiFilters().getFilterById(filterId); if (poiFilter == null) { - poiFilter = new PoiFilter(null, getMyApplication()); + poiFilter = new PoiFilter(null, app); } mapLayers.getPoiMapLayer().setFilter(poiFilter); - mapLayers.getMapInfoLayer().getBackToLocation().setEnabled(false); - // if destination point was changed try to recalculate route - TargetPointsHelper targets = getTargetPoints(); + TargetPointsHelper targets = app.getTargetPointsHelper(); + RoutingHelper routingHelper = app.getRoutingHelper(); if (routingHelper.isFollowingMode() && ( !Algorithms.objectEquals(targets.getPointToNavigate(), routingHelper.getFinalLocation() )|| !Algorithms.objectEquals(targets.getIntermediatePoints(), routingHelper.getIntermediatePoints()) )) { routingHelper.setFinalAndCurrentLocation(targets.getPointToNavigate(), targets.getIntermediatePoints(), - getLastKnownLocation(), routingHelper.getCurrentGPXRoute()); + app.getLocationProvider().getLastKnownLocation(), routingHelper.getCurrentGPXRoute()); } - - startLocationRequests(); + app.getLocationProvider().resumeAllUpdates(); if (settings != null && settings.isLastKnownMapLocation()) { LatLon l = settings.getLastKnownMapLocation(); @@ -381,151 +303,22 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe if (latLonToShow != null && !latLonToShow.equals(cur)) { mapView.getAnimatedDraggingThread().startMoving(latLonToShow.getLatitude(), latLonToShow.getLongitude(), settings.getMapZoomToShow(), true); - } if(latLonToShow != null) { // remember if map should come back to isMapLinkedToLocation=true - setMapLinkedToLocation(false); - } else { - setMapLinkedToLocation(isMapLinkedToLocation); + mapViewTrackingUtilities.setMapLinkedToLocation(false); } View progress = mapLayers.getMapInfoLayer().getProgressBar(); if (progress != null) { - getMyApplication().getResourceManager().setBusyIndicator(new BusyIndicator(this, progress)); + app.getResourceManager().setBusyIndicator(new BusyIndicator(this, progress)); } OsmandPlugin.onMapActivityResume(this); - getMyApplication().getDaynightHelper().onMapResume(); + app.getDaynightHelper().startSensorIfNeeded(); mapView.refreshMap(true); } - public void startLocationRequests() { - LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); - try { - service.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, gpsListener); - } catch (IllegalArgumentException e) { - Log.d(PlatformUtil.TAG, "GPS location provider not available"); //$NON-NLS-1$ - } - // try to always ask for network provide : it is faster way to find location - try { - service.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, networkListener); - } catch (IllegalArgumentException e) { - Log.d(PlatformUtil.TAG, "Network location provider not available"); //$NON-NLS-1$ - } - } - - private void notRestoreRoutingMode(){ - boolean changed = settings.APPLICATION_MODE.set(settings.PREV_APPLICATION_MODE.get()); - updateApplicationModeSettings(); - routingHelper.clearCurrentRoute(null, new ArrayList()); - mapView.refreshMap(changed); - } - - private void restoreRoutingMode() { - final String gpxPath = settings.FOLLOW_THE_GPX_ROUTE.get(); - final TargetPointsHelper targetPoints = getTargetPoints(); - final LatLon pointToNavigate = targetPoints.getPointToNavigate(); - if (pointToNavigate == null && gpxPath == null) { - notRestoreRoutingMode(); - } else { - quitRouteRestoreDialog = false; - Runnable encapsulate = new Runnable() { - int delay = 7; - Runnable delayDisplay = null; - - @Override - public void run() { - Builder builder = new AccessibleAlertBuilder(MapActivity.this); - final TextView tv = new TextView(MapActivity.this); - tv.setText(getString(R.string.continue_follow_previous_route_auto, delay + "")); - tv.setPadding(7, 5, 7, 5); - builder.setView(tv); - builder.setPositiveButton(R.string.default_buttons_yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - quitRouteRestoreDialog = true; - restoreRoutingModeInner(); - - } - }); - builder.setNegativeButton(R.string.default_buttons_no, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - quitRouteRestoreDialog = true; - notRestoreRoutingMode(); - } - }); - final AlertDialog dlg = builder.show(); - dlg.setOnDismissListener(new OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - quitRouteRestoreDialog = true; - } - }); - dlg.setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - quitRouteRestoreDialog = true; - } - }); - delayDisplay = new Runnable() { - @Override - public void run() { - if(!quitRouteRestoreDialog) { - delay --; - tv.setText(getString(R.string.continue_follow_previous_route_auto, delay + "")); - if(delay <= 0) { - if(dlg.isShowing() && !quitRouteRestoreDialog) { - dlg.dismiss(); - } - quitRouteRestoreDialog = true; - restoreRoutingModeInner(); - } else { - uiHandler.postDelayed(delayDisplay, 1000); - } - } - } - }; - delayDisplay.run(); - } - - private void restoreRoutingModeInner() { - AsyncTask task = new AsyncTask() { - @Override - protected GPXFile doInBackground(String... params) { - if (gpxPath != null) { - // Reverse also should be stored ? - GPXFile f = GPXUtilities.loadGPXFile(getMyApplication(), new File(gpxPath), false); - if (f.warning != null) { - return null; - } - return f; - } else { - return null; - } - } - - @Override - protected void onPostExecute(GPXFile result) { - final GPXRouteParams gpxRoute = result == null ? null : new GPXRouteParams(result, false, settings); - LatLon endPoint = pointToNavigate != null ? pointToNavigate : gpxRoute.getLastPoint(); - net.osmand.Location startPoint = gpxRoute == null ? null : gpxRoute.getStartPointForRoute(); - if (endPoint == null) { - notRestoreRoutingMode(); - } else { - followRoute(settings.getApplicationMode(), endPoint, targetPoints.getIntermediatePoints(), startPoint, gpxRoute); - } - } - }; - task.execute(gpxPath); - - } - }; - encapsulate.run(); - } - - } public OsmandApplication getMyApplication() { return ((OsmandApplication) getApplication()); @@ -562,119 +355,22 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe newZoom = Math.round(newZoom * OsmandMapTileView.ZOOM_DELTA) * OsmandMapTileView.ZOOM_DELTA_1; boolean changeLocation = settings.AUTO_ZOOM_MAP.get(); mapView.getAnimatedDraggingThread().startZooming(newZoom, changeLocation); - if (getMyApplication().getInternalAPI().accessibilityEnabled()) + if (app.getInternalAPI().accessibilityEnabled()) AccessibleToast.makeText(this, getString(R.string.zoomIs) + " " + String.valueOf(newZoom), Toast.LENGTH_SHORT).show(); //$NON-NLS-1$ showAndHideMapPosition(); } - - - public void backToMainMenu() { - final Dialog dlg = new Dialog(this, R.style.Dialog_Fullscreen); - final View menuView = (View) getLayoutInflater().inflate(R.layout.menu, null); - menuView.setBackgroundColor(Color.argb(200, 150, 150, 150)); - dlg.setContentView(menuView); - MainMenuActivity.onCreateMainMenu(dlg.getWindow(), this); - Animation anim = new Animation() { - @Override - protected void applyTransformation(float interpolatedTime, Transformation t) { - ColorDrawable colorDraw = ((ColorDrawable) menuView.getBackground()); - colorDraw.setAlpha((int) (interpolatedTime * 200)); - } - }; - anim.setDuration(700); - anim.setInterpolator(new AccelerateInterpolator()); - menuView.setAnimation(anim); - - View showMap = dlg.findViewById(R.id.MapButton); - showMap.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - dlg.dismiss(); - } - }); - View settingsButton = dlg.findViewById(R.id.SettingsButton); - settingsButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - final Intent settings = new Intent(MapActivity.this, OsmandIntents.getSettingsActivity()); - MapActivity.this.startActivity(settings); - dlg.dismiss(); - } - }); - - View favouritesButton = dlg.findViewById(R.id.FavoritesButton); - favouritesButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - final Intent favorites = new Intent(MapActivity.this, OsmandIntents.getFavoritesActivity()); - favorites.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - MapActivity.this.startActivity(favorites); - dlg.dismiss(); - } - }); - - View closeButton = dlg.findViewById(R.id.CloseButton); - closeButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - dlg.dismiss(); - // 1. Work for almost all cases when user open apps from main menu - Intent newIntent = new Intent(MapActivity.this, OsmandIntents.getMainMenuActivity()); - newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - newIntent.putExtra(MainMenuActivity.APP_EXIT_KEY, MainMenuActivity.APP_EXIT_CODE); - startActivity(newIntent); - // 2. good analogue but user will come back to the current activity onResume() - // so application is not reloaded !!! - // moveTaskToBack(true); - // 3. bad results if user comes from favorites - // MapActivity.this.setResult(MainMenuActivity.APP_EXIT_CODE); - // MapActivity.this.finish(); - } - }); - - View searchButton = dlg.findViewById(R.id.SearchButton); - searchButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - final Intent search = new Intent(MapActivity.this, OsmandIntents.getSearchActivity()); - LatLon loc = getMapLocation(); - search.putExtra(SearchActivity.SEARCH_LAT, loc.getLatitude()); - search.putExtra(SearchActivity.SEARCH_LON, loc.getLongitude()); - // causes wrong position caching: search.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - search.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - MapActivity.this.startActivity(search); - dlg.dismiss(); - } - }); - menuView.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - dlg.dismiss(); - } - }); - - dlg.show(); - // Intent newIntent = new Intent(MapActivity.this, MainMenuActivity.class); - // newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - // startActivity(newIntent); - } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - //some application/hardware needs that back button reacts on key up, so - //that they could do some key combinations with it... - // Victor : doing in that way doesn't close dialog properly! - //return true; - } else if (getMyApplication().getInternalAPI().accessibilityEnabled() && (keyCode == KeyEvent.KEYCODE_DPAD_CENTER)) { + if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && + app.getInternalAPI().accessibilityEnabled()) { if (!uiHandler.hasMessages(LONG_KEYPRESS_MSG_ID)) { Message msg = Message.obtain(uiHandler, new Runnable() { - @Override - public void run() { - emitNavigationHint(); - } - }); + @Override + public void run() { + app.getLocationProvider().emitNavigationHint(); + } + }); msg.what = LONG_KEYPRESS_MSG_ID; uiHandler.sendMessageDelayed(msg, LONG_KEYPRESS_DELAY); } @@ -688,7 +384,8 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe startActivity(newIntent); newIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); return true; - } else if (!routingHelper.isFollowingMode() && OsmandPlugin.getEnabledPlugin(AccessibilityPlugin.class) != null) { + } else if (!app.getRoutingHelper().isFollowingMode() && + OsmandPlugin.getEnabledPlugin(AccessibilityPlugin.class) != null) { // Find more appropriate plugin for it? if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && event.getRepeatCount() == 0) { if (mapView.isZooming()) { @@ -705,29 +402,9 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe return super.onKeyDown(keyCode, event); } - public String getNavigationHint(LatLon point) { - String hint = navigationInfo.getDirectionString(point, mapLayers.getLocationLayer().getHeading()); - if (hint == null) - hint = getString(R.string.no_info); - return hint; - } - - public void emitNavigationHint() { - final LatLon point = getTargetPoints().getPointToNavigate(); - if (point != null) { - if (routingHelper.isRouteCalculated()) { - routingHelper.getVoiceRouter().announceCurrentDirection(getLastKnownLocation()); - } else { - AccessibleToast.makeText(this, getNavigationHint(point), Toast.LENGTH_LONG).show(); - } - } else { - AccessibleToast.makeText(this, R.string.mark_final_location_first, Toast.LENGTH_SHORT).show(); - } - } - public void setMapLocation(double lat, double lon){ mapView.setLatLon(lat, lon); - locationChanged(lat, lon, this); + mapViewTrackingUtilities.locationChanged(lat, lon, this); } @Override @@ -757,7 +434,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe @Override protected void onStop() { - if(routingHelper.isFollowingMode()){ + if(app.getRoutingHelper().isFollowingMode()){ mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); if(mNotificationManager != null) { mNotificationManager.notify(APP_NOTIFICATION_ID, getNotification()); @@ -773,11 +450,11 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe @Override protected void onDestroy() { super.onDestroy(); - quitRouteRestoreDialog = true; + FailSafeFuntions.quitRouteRestoreDialog(); OsmandPlugin.onMapActivityDestroy(this); - savingTrackHelper.close(); + mapViewTrackingUtilities.setMapView(null); cancelNotification(); - getMyApplication().getResourceManager().getMapTileDownloader().removeDownloaderCallback(mapView); + app.getResourceManager().getMapTileDownloader().removeDownloaderCallback(mapView); } private void cancelNotification() { @@ -789,434 +466,44 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe } } - - - private void registerUnregisterSensor(net.osmand.Location location, boolean overruleRegister){ - boolean currentShowingAngle = settings.SHOW_VIEW_ANGLE.get(); - int currentMapRotation = settings.ROTATE_MAP.get(); - boolean show = overruleRegister || (currentShowingAngle && location != null) || currentMapRotation == OsmandSettings.ROTATE_MAP_COMPASS; - // show point view only if gps enabled - if (sensorRegistered && !show) { - Log.d(PlatformUtil.TAG, "Disable sensor"); //$NON-NLS-1$ - ((SensorManager) getSystemService(SENSOR_SERVICE)).unregisterListener(this); - sensorRegistered = false; - previousSensorValue = 0; - mapLayers.getLocationLayer().setHeading(null); - } else if (!sensorRegistered && show) { - Log.d(PlatformUtil.TAG, "Enable sensor"); //$NON-NLS-1$ - SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); - Sensor s = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); - if (s == null || !sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI)) { - Log.e(PlatformUtil.TAG, "Sensor accelerometer could not be enabled"); - } - s = sensorMgr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); - if (s == null || !sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI)) { - Log.e(PlatformUtil.TAG, "Sensor magnetic field could not be enabled"); - } -// s = sensorMgr.getDefaultSensor(Sensor.TYPE_ORIENTATION); -// if (s == null || !sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI)) { -// Log.e(LogUtil.TAG, "Sensor orientation could not be enabled"); -// } - sensorRegistered = true; - } - } - - public void backToLocationImpl() { - mapLayers.getMapInfoLayer().getBackToLocation().setEnabled(false); - PointLocationLayer locationLayer = mapLayers.getLocationLayer(); - if(!isMapLinkedToLocation()){ - setMapLinkedToLocation(true); - if(locationLayer.getLastKnownLocation() != null){ - net.osmand.Location lastKnownLocation = locationLayer.getLastKnownLocation(); - AnimateDraggingMapThread thread = mapView.getAnimatedDraggingThread(); - float fZoom = mapView.getFloatZoom() < 13 ? 13 : mapView.getFloatZoom(); - thread.startMoving( lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude(), fZoom, false); - } - } - if(locationLayer.getLastKnownLocation() == null){ - AccessibleToast.makeText(this, R.string.unknown_location, Toast.LENGTH_LONG).show(); - } - } - - // location not null! - private void updateSpeedBearingEmulator(net.osmand.Location location) { - // For network/gps it's bad way (not accurate). It's widely used for testing purposes - // possibly keep using only for emulator case - PointLocationLayer locationLayer = mapLayers.getLocationLayer(); - if (locationLayer.getLastKnownLocation() != null) { - if (locationLayer.getLastKnownLocation().distanceTo(location) > 3) { - float d = location.distanceTo(locationLayer.getLastKnownLocation()); - long time = location.getTime() - locationLayer.getLastKnownLocation().getTime(); - float speed; - if (time == 0) { - speed = 0; - } else { - speed = ((float) d * 1000) / time ; - } - // Be aware only for emulator ! code is incorrect in case of airplane - if (speed > 100) { - speed = 100; - } - location.setSpeed(speed); - } - } - if(locationLayer.getLastKnownLocation() != null && !location.hasBearing()){ - if(locationLayer.getLastKnownLocation().distanceTo(location) > 10 && !isRunningOnEmulator()){ - // very innacurate - // location.setBearing(locationLayer.getLastKnownLocation().bearingTo(location)); - } - } - } - - public boolean isPointAccurateForRouting(net.osmand.Location loc) { - return loc != null && loc.getAccuracy() < ACCURACY_FOR_GPX_AND_ROUTING * 3 /2; - } - - public void setLocation(net.osmand.Location location) { - if (Log.isLoggable(PlatformUtil.TAG, Log.DEBUG)) { - Log.d(PlatformUtil.TAG, "Location changed " + location.getProvider()); //$NON-NLS-1$ - } - // 1. Logging services - if (location != null) { - // use because there is a bug on some devices with location.getTime() - long locationTime = System.currentTimeMillis(); - // write only with 50 meters accuracy - if (!location.hasAccuracy() || location.getAccuracy() < ACCURACY_FOR_GPX_AND_ROUTING) { - if (settings.SAVE_TRACK_TO_GPX.get() && OsmandPlugin.getEnabledPlugin(OsmandMonitoringPlugin.class) != null) { - savingTrackHelper.insertData(location.getLatitude(), location.getLongitude(), location.getAltitude(), - location.getSpeed(), location.getAccuracy(), locationTime, settings); - } - // live monitoring is aware of accuracy (it would be good to create an option) - if (liveMonitoringHelper.isLiveMonitoringEnabled()) { - liveMonitoringHelper.insertData(location.getLatitude(), location.getLongitude(), location.getAltitude(), - location.getSpeed(), location.getAccuracy(), location.getTime(), settings); - } - - } - - } - - if(location != null && isRunningOnEmulator()) { - // only for emulator - updateSpeedBearingEmulator(location); - } - // 2. accessibility routing - navigationInfo.setLocation(location); - - // 3. routing - boolean enableSensorNavigation = routingHelper.isFollowingMode() && settings.USE_COMPASS_IN_NAVIGATION.get() ? location == null - || !location.hasBearing() : false; - registerUnregisterSensor(location, enableSensorNavigation); - net.osmand.Location updatedLocation = location; - if (routingHelper.isFollowingMode()) { - if (location == null || !location.hasAccuracy() || location.getAccuracy() < ACCURACY_FOR_GPX_AND_ROUTING) { - // Update routing position and get location for sticking mode - updatedLocation = routingHelper.setCurrentLocation(location, settings.SNAP_TO_ROAD.get()); - if(!routingHelper.isFollowingMode()) { - // finished - Message msg = Message.obtain(uiHandler, new Runnable() { - @Override - public void run() { - settings.APPLICATION_MODE.set(settings.PREV_APPLICATION_MODE.get()); - updateApplicationModeSettings(); - } - }); - uiHandler.sendMessage(msg); - } - // Check with delay that gps location is not lost - if (location != null && routingHelper.getLeftDistance() > 0) { - final long fixTime = location.getTime(); - Message msg = Message.obtain(uiHandler, new Runnable() { - @Override - public void run() { - net.osmand.Location lastKnown = getLastKnownLocation(); - if (lastKnown != null && lastKnown.getTime() - fixTime < LOST_LOCATION_CHECK_DELAY / 2) { - // false positive case, still strange how we got here with removeMessages - return; - } - if (routingHelper.getLeftDistance() > 0 && settings.MAP_ACTIVITY_ENABLED.get()) { - routingHelper.getVoiceRouter().gpsLocationLost(); - } - } - }); - msg.what = LOST_LOCATION_MSG_ID; - uiHandler.removeMessages(LOST_LOCATION_MSG_ID); - uiHandler.sendMessageDelayed(msg, LOST_LOCATION_CHECK_DELAY); - } - } - } - - - // Update information - mapLayers.getLocationLayer().setLastKnownLocation(updatedLocation); - if (updatedLocation != null) { - updateAutoMapViewConfiguration(updatedLocation); - } else { - if (mapLayers.getMapInfoLayer().getBackToLocation().isEnabled()) { - mapLayers.getMapInfoLayer().getBackToLocation().setEnabled(false); - } - } - - // When location is changed we need to refresh map in order to show movement! - mapView.refreshMap(); - } - - private void updateAutoMapViewConfiguration(net.osmand.Location location) { - long now = System.currentTimeMillis(); - if (isMapLinkedToLocation()) { - if (settings.AUTO_ZOOM_MAP.get() && location.hasSpeed()) { - float zdelta = defineZoomFromSpeed(location.getSpeed()); - if (Math.abs(zdelta) >= OsmandMapTileView.ZOOM_DELTA_1) { - // prevent ui hysteresis (check time interval for autozoom) - if (zdelta >= 2) { - // decrease a bit - zdelta -= 3 * OsmandMapTileView.ZOOM_DELTA_1; - } else if (zdelta <= -2) { - // decrease a bit - zdelta += 3 * OsmandMapTileView.ZOOM_DELTA_1; - } - if (now - lastTimeAutoZooming > 4500) { - lastTimeAutoZooming = now; - float newZoom = Math.round((mapView.getFloatZoom() + zdelta) * OsmandMapTileView.ZOOM_DELTA) * OsmandMapTileView.ZOOM_DELTA_1; - mapView.setZoom(newZoom); - // mapView.getAnimatedDraggingThread().startZooming(mapView.getFloatZoom() + zdelta, false); - } - } - } - int currentMapRotation = settings.ROTATE_MAP.get(); - if (currentMapRotation == OsmandSettings.ROTATE_MAP_BEARING) { - if (location.hasBearing()) { - if(location.getBearing() != 0f) { - mapView.setRotate(-location.getBearing()); - } - } else if (routingHelper.isFollowingMode() && settings.USE_COMPASS_IN_NAVIGATION.get()) { - if (previousSensorValue != 0 && Math.abs(MapUtils.degreesDiff(mapView.getRotate(), -previousSensorValue)) > 15) { - if(now - lastTimeSensorRotation > 1500 && now - lastTimeSensorRotation < 15000) { - lastTimeSensorRotation = now; - mapView.setRotate(-previousSensorValue); - } - } - } - } - mapView.setLatLon(location.getLatitude(), location.getLongitude()); - } else { - if (!mapLayers.getMapInfoLayer().getBackToLocation().isEnabled()) { - mapLayers.getMapInfoLayer().getBackToLocation().setEnabled(true); - } - if (settings.AUTO_FOLLOW_ROUTE.get() > 0 && routingHelper.isFollowingMode() && !uiHandler.hasMessages(AUTO_FOLLOW_MSG_ID)) { - backToLocationWithDelay(1); - } - } - } - - public float defineZoomFromSpeed(float speed) { - if (speed < 7f / 3.6) { - return 0; - } - double topLat = mapView.calcLatitude(-mapView.getCenterPointY()); - double cLat = mapView.calcLatitude(0); - double visibleDist = MapUtils.getDistance(cLat, mapView.getLongitude(), topLat, mapView.getLongitude()); - float time = 75f; - if (speed < 83f / 3.6) { - time = 60f; - } - double distToSee = speed * time; - float zoomDelta = (float) (Math.log(visibleDist / distToSee) / Math.log(2.0f)); - zoomDelta = Math.round(zoomDelta * OsmandMapTileView.ZOOM_DELTA) * OsmandMapTileView.ZOOM_DELTA_1; - // check if 17, 18 is correct? - if(zoomDelta + mapView.getFloatZoom() > 18 - OsmandMapTileView.ZOOM_DELTA_1) { - return 18 - OsmandMapTileView.ZOOM_DELTA_1 - mapView.getFloatZoom(); - } - return zoomDelta; - } - public void followRoute(ApplicationMode appMode, LatLon finalLocation, List intermediatePoints, net.osmand.Location currentLocation, GPXRouteParams gpxRoute){ - // change global settings - // Do not overwrite PREV_APPLICATION_MODE if already navigating - if (!routingHelper.isFollowingMode()) { - settings.PREV_APPLICATION_MODE.set(settings.APPLICATION_MODE.get()); - } - boolean changed = settings.APPLICATION_MODE.set(appMode); - if (changed) { - updateApplicationModeSettings(); - } - getMapView().refreshMap(changed); + RoutingHelper routingHelper = app.getRoutingHelper(); + settings.APPLICATION_MODE.set(appMode); settings.FOLLOW_THE_ROUTE.set(true); if(gpxRoute == null) { settings.FOLLOW_THE_GPX_ROUTE.set(null); } routingHelper.setFollowingMode(true); routingHelper.setFinalAndCurrentLocation(finalLocation, intermediatePoints, currentLocation, gpxRoute); - getMyApplication().showDialogInitializingCommandPlayer(MapActivity.this); + app.showDialogInitializingCommandPlayer(MapActivity.this); } - public net.osmand.Location getLastKnownLocation(){ - if(mapLayers.getLocationLayer() == null) { - return null; - } - return mapLayers.getLocationLayer().getLastKnownLocation(); - } - - public float getLastSensorRotation(){ - return previousSensorValue; - } - public RouteDataObject getLastRouteDataObject(){ - return currentPositionHelper.getLastKnownRouteSegment(getLastKnownLocation()); + OsmAndLocationProvider locationProvider = app.getLocationProvider(); + return locationProvider.getLastKnownRouteSegment(); } public LatLon getMapLocation(){ return new LatLon(mapView.getLatitude(), mapView.getLongitude()); } - public TargetPointsHelper getTargetPoints(){ - return getMyApplication().getTargetPointsHelper(); - } - + // Duplicate methods to OsmAndApplication public LatLon getPointToNavigate(){ - return getTargetPoints().getPointToNavigate(); + return app.getTargetPointsHelper().getPointToNavigate(); } public RoutingHelper getRoutingHelper() { - return routingHelper; - } - - private boolean isRunningOnEmulator(){ - if (Build.DEVICE.equals("generic")) { //$NON-NLS-1$ - return true; - } - return false; - } - - private boolean useOnlyGPS() { - return (routingHelper != null && routingHelper.isFollowingMode()) - || (System.currentTimeMillis() - lastTimeGPSLocationFixed) < USE_ONLY_GPS_INTERVAL || isRunningOnEmulator(); - } - - - // Working with location listeners - private LocationListener networkListener = new LocationListener(){ - - @Override - public void onLocationChanged(Location location) { - // double check about use only gps - // that strange situation but it could happen? - if(!useOnlyGPS()){ - setLocation(convertLocation(location, getMyApplication())); - } - } - - @Override - public void onProviderDisabled(String provider) { - if(!useOnlyGPS()){ - setLocation(null); - } - } - - @Override - public void onProviderEnabled(String provider) { - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - if(LocationProvider.OUT_OF_SERVICE == status && !useOnlyGPS()){ - setLocation(null); - } - } - - }; - - public static net.osmand.Location convertLocation(Location l, OsmandApplication app) { - net.osmand.Location r = new net.osmand.Location(l.getProvider()); - r.setLatitude(l.getLatitude()); - r.setLongitude(l.getLongitude()); - r.setTime(l.getTime()); - if(l.hasAccuracy()) { - r.setAccuracy(l.getAccuracy()); - } - if(l.hasSpeed()) { - r.setSpeed(l.getSpeed()); - } - if(l.hasAltitude()) { - r.setAltitude(l.getAltitude()); - } - if(l.hasBearing()) { - r.setBearing(l.getBearing()); - } - if (l.hasAltitude() && app != null) { - double alt = l.getAltitude(); - final GeoidAltitudeCorrection geo = app.getResourceManager().getGeoidAltitudeCorrection(); - if (geo != null) { - alt -= geo.getGeoidHeight(l.getLatitude(), l.getLongitude()); - r.setAltitude(alt); - } - } - return r; - } - - - private LocationListener gpsListener = new LocationListener(){ - @Override - public void onLocationChanged(Location location) { - if (location != null) { - lastTimeGPSLocationFixed = location.getTime(); - } - setLocation(convertLocation(location, getMyApplication())); - } - - @Override - public void onProviderDisabled(String provider) { - LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); - if (!useOnlyGPS() && service.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { - Location loc = service.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); - if(loc != null && (System.currentTimeMillis() - loc.getTime()) < USE_ONLY_GPS_INTERVAL){ - setLocation(convertLocation(loc, getMyApplication())); - } - } else { - setLocation(null); - } - } - - @Override - public void onProviderEnabled(String provider) { - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - if (LocationProvider.TEMPORARILY_UNAVAILABLE == status) { - if(routingHelper.isFollowingMode() && routingHelper.getLeftDistance() > 0){ - // Suppress gpsLocationLost() prompt here for now, as it causes duplicate announcement and then also prompts when signal is found again - //routingHelper.getVoiceRouter().gpsLocationLost(); - } - } else if (LocationProvider.OUT_OF_SERVICE == status) { - if(routingHelper.isFollowingMode() && routingHelper.getLeftDistance() > 0){ - routingHelper.getVoiceRouter().gpsLocationLost(); - } - } else if (LocationProvider.AVAILABLE == status) { - // Do not remove right now network listener - // service.removeUpdates(networkListener); - } - - } - }; - - - public LocationListener getGpsListener() { - return gpsListener; + return app.getRoutingHelper(); } @Override protected void onPause() { super.onPause(); - stopLocationRequests(); - - SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); - sensorMgr.unregisterListener(this); - sensorRegistered = false; - - getMyApplication().getDaynightHelper().onMapPause(); + app.getLocationProvider().pauseAllUpdates(); + app.getDaynightHelper().stopSensorIfNeeded(); + settings.APPLICATION_MODE.removeListener(applicationModeListener); settings.setLastKnownMapLocation((float) mapView.getLatitude(), (float) mapView.getLongitude()); AnimateDraggingMapThread animatedThread = mapView.getAnimatedDraggingThread(); @@ -1227,68 +514,37 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe settings.setLastKnownMapZoom(mapView.getZoom()); settings.MAP_ACTIVITY_ENABLED.set(false); - getMyApplication().getResourceManager().interruptRendering(); - getMyApplication().getResourceManager().setBusyIndicator(null); + app.getResourceManager().interruptRendering(); + app.getResourceManager().setBusyIndicator(null); OsmandPlugin.onMapActivityPause(this); } - public void stopLocationRequests() { - LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); - service.removeUpdates(gpsListener); - service.removeUpdates(networkListener); - } - public void updateApplicationModeSettings(){ - int currentMapRotation = settings.ROTATE_MAP.get(); - if(currentMapRotation == OsmandSettings.ROTATE_MAP_NONE){ - mapView.setRotate(0); + public void updateApplicationModeSettings() { + // update vector renderer + RendererRegistry registry = app.getRendererRegistry(); + RenderingRulesStorage newRenderer = registry.getRenderer(settings.RENDERER.get()); + if (newRenderer == null) { + newRenderer = registry.defaultRender(); } - routingHelper.setAppMode(settings.getApplicationMode()); - // mapView.setMapPosition(settings.POSITION_ON_MAP.get()); - mapView.setMapPosition(settings.ROTATE_MAP.get() == OsmandSettings.ROTATE_MAP_BEARING - || settings.ROTATE_MAP.get() == OsmandSettings.ROTATE_MAP_COMPASS ? OsmandSettings.BOTTOM_CONSTANT : - OsmandSettings.CENTER_CONSTANT); - registerUnregisterSensor(getLastKnownLocation(), false); + if (registry.getCurrentSelectedRenderer() != newRenderer) { + registry.setCurrentSelectedRender(newRenderer); + app.getResourceManager().getRenderer().clearCache(); + } + mapViewTrackingUtilities.updateSettings(); + app.getRoutingHelper().setAppMode(settings.getApplicationMode()); if (mapLayers.getMapInfoLayer() != null) { mapLayers.getMapInfoLayer().recreateControls(); } mapLayers.updateLayers(mapView); - - getMyApplication().getDaynightHelper().setDayNightMode(settings.DAYNIGHT_MODE.get()); + app.getDaynightHelper().startSensorIfNeeded(); } - public void switchRotateMapMode(){ - int vl = (settings.ROTATE_MAP.get() + 1) % 3; - settings.ROTATE_MAP.set(vl); - registerUnregisterSensor(getLastKnownLocation(), false); - if(settings.ROTATE_MAP.get() != OsmandSettings.ROTATE_MAP_COMPASS){ - mapView.setRotate(0); - } - int resId = R.string.rotate_map_none_opt; - if(settings.ROTATE_MAP.get() == OsmandSettings.ROTATE_MAP_COMPASS){ - resId = R.string.rotate_map_compass_opt; - } else if(settings.ROTATE_MAP.get() == OsmandSettings.ROTATE_MAP_BEARING){ - resId = R.string.rotate_map_bearing_opt; - } - mapView.setMapPosition(settings.ROTATE_MAP.get() == OsmandSettings.ROTATE_MAP_BEARING - || settings.ROTATE_MAP.get() == OsmandSettings.ROTATE_MAP_COMPASS ? OsmandSettings.BOTTOM_CONSTANT : - OsmandSettings.CENTER_CONSTANT); - - AccessibleToast.makeText(this, getString(resId), Toast.LENGTH_SHORT).show(); - mapView.refreshMap(); - } - @Override public boolean onKeyUp(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - //some application/hardware needs that back button reacts on key up, so - //that they could do some key combinations with it... - // Android 1.6 doesn't have onBackPressed() method it should be finish instead! - //onBackPressed(); - //return true; - } else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { - if (!getMyApplication().getInternalAPI().accessibilityEnabled()) { + if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { + if (!app.getInternalAPI().accessibilityEnabled()) { mapActions.contextMenuPoint(mapView.getLatitude(), mapView.getLongitude()); } else if (uiHandler.hasMessages(LONG_KEYPRESS_MSG_ID)) { uiHandler.removeMessages(LONG_KEYPRESS_MSG_ID); @@ -1332,7 +588,7 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe public void showAndHideMapPosition() { mapView.setShowMapPosition(true); - Message msg = Message.obtain(uiHandler, new Runnable() { + app.runMessageInUIThreadAndCancelPrevious(SHOW_POSITION_MSG_ID, new Runnable() { @Override public void run() { if (mapView.isShowMapPosition()) { @@ -1340,105 +596,18 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe mapView.refreshMap(); } } - - }); - msg.what = SHOW_POSITION_MSG_ID; - uiHandler.removeMessages(SHOW_POSITION_MSG_ID); - uiHandler.sendMessageDelayed(msg, SHOW_POSITION_DELAY); + }, 2500); } - - @Override - public void locationChanged(double newLatitude, double newLongitude, Object source) { - // when user start dragging - if(mapLayers.getLocationLayer().getLastKnownLocation() != null){ - setMapLinkedToLocation(false); - if (!mapLayers.getMapInfoLayer().getBackToLocation().isEnabled()) { - runOnUiThread(new Runnable() { - @Override - public void run() { - mapLayers.getMapInfoLayer().getBackToLocation().setEnabled(true); - } - }); - } - } - } - public OsmandMapTileView getMapView() { return mapView; } - @Override - public void onSensorChanged(SensorEvent event) { - // Attention : sensor produces a lot of events & can hang the system - - float val = 0; - switch (event.sensor.getType()) { - case Sensor.TYPE_ACCELEROMETER: - if (mGravs == null) { - mGravs = new float[3]; - } - System.arraycopy(event.values, 0, mGravs, 0, 3); - break; - case Sensor.TYPE_MAGNETIC_FIELD: - if (mGeoMags == null) { - mGeoMags = new float[3]; - } - System.arraycopy(event.values, 0, mGeoMags, 0, 3); - break; - case Sensor.TYPE_ORIENTATION: - val = event.values[0]; - if (mGravs != null && mGeoMags != null) { - return; - } - break; - default: - return; - } - if (mGravs != null && mGeoMags != null) { - float[] mRotationM = new float[9]; - boolean success = SensorManager.getRotationMatrix(mRotationM, null, mGravs, mGeoMags); - if(!success) { - return; - } - float[] orientation = SensorManager.getOrientation(mRotationM, new float[3]); - val = (float) Math.toDegrees(orientation[0]); - } else if(event.sensor.getType() != Sensor.TYPE_ORIENTATION){ - return; - } - - if(currentScreenOrientation == 1){ - val += 90; - } else if(currentScreenOrientation == 2){ - val += 180; - } else if(currentScreenOrientation == 3){ - val += 270; - } - if(previousCorrectionValue == 360 && getLastKnownLocation() != null) { - net.osmand.Location l = getLastKnownLocation(); - GeomagneticField gf = new GeomagneticField((float)l.getLatitude(), (float)l.getLongitude(), - (float)l.getAltitude(), System.currentTimeMillis()); - previousCorrectionValue = gf.getDeclination(); - } - if(previousCorrectionValue != 360 ){ - val += previousCorrectionValue; - } - - previousSensorValue = val; - if (settings.ROTATE_MAP.get() == OsmandSettings.ROTATE_MAP_COMPASS) { - if(Math.abs(MapUtils.degreesDiff(mapView.getRotate(), -val)) > 15) { - mapView.setRotate(-val); - } - } - if(settings.SHOW_VIEW_ANGLE.get().booleanValue()){ - if(mapLayers.getLocationLayer().getHeading() == null || Math.abs(mapLayers.getLocationLayer().getHeading() - val) > 10){ - mapLayers.getLocationLayer().setHeading(val); - } - } - + public MapViewTrackingUtilities getMapViewTrackingUtilities() { + return mapViewTrackingUtilities; } - + @Override public boolean onCreateOptionsMenu(Menu menu) { return mapActions.onCreateOptionsMenu(menu); @@ -1481,10 +650,6 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe } } - public FavouritesDbHelper getFavoritesHelper() { - return getMyApplication().getFavorites(); - } - public MapActivityActions getMapActions() { return mapActions; } @@ -1493,13 +658,6 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe return mapLayers; } - public SavingTrackHelper getSavingTrackHelper() { - return savingTrackHelper; - } - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - } public static void launchMapActivityMoveToTop(Context activity){ Intent newIntent = new Intent(activity, OsmandIntents.getMapActivity()); @@ -1508,48 +666,13 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe } - public boolean isMapLinkedToLocation(){ - return isMapLinkedToLocation; - } - - public void setMapLinkedToLocation(boolean isMapLinkedToLocation) { - if(!isMapLinkedToLocation){ - int autoFollow = settings.AUTO_FOLLOW_ROUTE.get(); - if(autoFollow > 0 && routingHelper.isFollowingMode()){ - backToLocationWithDelay(autoFollow); - } - } - MapActivity.isMapLinkedToLocation = isMapLinkedToLocation; - } - - private void backToLocationWithDelay(int delay) { - uiHandler.removeMessages(AUTO_FOLLOW_MSG_ID); - Message msg = Message.obtain(uiHandler, new Runnable() { - @Override - public void run() { - if (settings.MAP_ACTIVITY_ENABLED.get() && !isMapLinkedToLocation()) { - AccessibleToast.makeText(MapActivity.this, R.string.auto_follow_location_enabled, Toast.LENGTH_SHORT).show(); - backToLocationImpl(); - } - } - }); - msg.what = AUTO_FOLLOW_MSG_ID; - uiHandler.sendMessageDelayed(msg, delay * 1000); - } - - public NavigationInfo getNavigationInfo() { - return navigationInfo; - } - @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { OsmandPlugin.onMapActivityResult(requestCode, resultCode, data); } - @Override public void refreshMap() { getMapView().refreshMap(); - } } diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index 8663395fb1..fa7e52ea02 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -34,6 +34,7 @@ import net.osmand.plus.GPXUtilities; import net.osmand.plus.GPXUtilities.GPXFile; import net.osmand.plus.OptionsMenuHelper; import net.osmand.plus.OptionsMenuHelper.OnOptionsMenuClick; +import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandSettings; @@ -268,7 +269,8 @@ public class MapActivityActions implements DialogProvider { double latitude = args.getDouble(KEY_LATITUDE); double longitude = args.getDouble(KEY_LONGITUDE); String name = editText.getText().toString(); - mapActivity.getSavingTrackHelper().insertPointData(latitude, longitude, System.currentTimeMillis(), name); + SavingTrackHelper savingTrackHelper = mapActivity.getMyApplication().getSavingTrackHelper(); + savingTrackHelper.insertPointData(latitude, longitude, System.currentTimeMillis(), name); if(settings.SHOW_CURRENT_GPX_TRACK.get()) { getMyApplication().getFavorites().addFavoritePointToGPXFile(new FavouritePoint(latitude, longitude, name, "")); } @@ -490,7 +492,7 @@ public class MapActivityActions implements DialogProvider { from = getRoutePointDescription(fromOrCurrent.getLatitude(), fromOrCurrent.getLongitude()); } - TargetPointsHelper targets = mapActivity.getTargetPoints(); + TargetPointsHelper targets = getTargets(); String tos; if(to == null) { tos = getRoutePointDescription(targets.getPointToNavigate(), @@ -517,7 +519,7 @@ public class MapActivityActions implements DialogProvider { public void getDirections(final Location fromOrCurrent, final LatLon to, boolean gpxRouteEnabled) { Builder builder = new AlertDialog.Builder(mapActivity); - final TargetPointsHelper targets = mapActivity.getTargetPoints(); + final TargetPointsHelper targets = getTargets(); View view = mapActivity.getLayoutInflater().inflate(R.layout.calculate_route, null); final CheckBox nonoptimal = (CheckBox) view.findViewById(R.id.OptimalCheckox); @@ -577,27 +579,20 @@ public class MapActivityActions implements DialogProvider { @Override public void onClick(DialogInterface dialog, int which) { if (to != null) { - targets.navigateToPoint(mapActivity, to, false, -1); + targets.navigateToPoint(to, false, -1); } if (!targets.checkPointToNavigate(getMyApplication())) { return; } Location from = fromOrCurrent; if (from == null) { - from = mapActivity.getLastKnownLocation(); + from = getLastKnownLocation(); } if (from == null) { AccessibleToast.makeText(mapActivity, R.string.unknown_from_location, Toast.LENGTH_LONG).show(); return; } - // PREV_APPLICATION_MODE also needs to be set here to overwrite possibly outdated value from prior follow-navigation in - // different profile - // Do not overwrite PREV_APPLICATION_MODE if already navigating - if (!routingHelper.isFollowingMode()) { - settings.PREV_APPLICATION_MODE.set(settings.APPLICATION_MODE.get()); - } - ApplicationMode mode = getAppMode(buttons, settings); routingHelper.setAppMode(mode); settings.OPTIMAL_ROUTE_MODE.setModeValue(mode, !nonoptimal.isChecked()); @@ -612,7 +607,7 @@ public class MapActivityActions implements DialogProvider { @Override public void onClick(DialogInterface dialog, int which) { if(to != null) { - targets.navigateToPoint(mapActivity, to, false, -1); + targets.navigateToPoint(to, false, -1); } if (!targets.checkPointToNavigate(getMyApplication())) { return; @@ -620,14 +615,14 @@ public class MapActivityActions implements DialogProvider { boolean msg = true; Location current = fromOrCurrent; if(current == null) { - current = mapActivity.getLastKnownLocation(); + current = getLastKnownLocation(); } - if (!mapActivity.isPointAccurateForRouting(current)) { + if (!OsmAndLocationProvider.isPointAccurateForRouting(current)) { current = null; } - Location lastKnownLocation = mapActivity.getLastKnownLocation(); - if (mapActivity.isPointAccurateForRouting(lastKnownLocation)) { + Location lastKnownLocation = getLastKnownLocation(); + if (OsmAndLocationProvider.isPointAccurateForRouting(lastKnownLocation)) { current = lastKnownLocation; msg = false; } @@ -646,7 +641,7 @@ public class MapActivityActions implements DialogProvider { @Override public void onClick(DialogInterface dialog, int which) { if(to != null) { - targets.navigateToPoint(mapActivity, to, false, -1); + targets.navigateToPoint(to, false, -1); } ApplicationMode mode = getAppMode(buttons, settings); navigateUsingGPX(mode); @@ -665,7 +660,11 @@ public class MapActivityActions implements DialogProvider { builder.show(); } - protected OsmandApplication getMyApplication() { + protected Location getLastKnownLocation() { + return getMyApplication().getLocationProvider().getLastKnownLocation(); + } + + protected OsmandApplication getMyApplication() { return mapActivity.getMyApplication(); } @@ -694,12 +693,12 @@ public class MapActivityActions implements DialogProvider { boolean useDestination = props[1]; GPXRouteParams gpxRoute = new GPXRouteParams(result, reverse, settings); - Location loc = mapActivity.getLastKnownLocation(); + Location loc = getLastKnownLocation(); if(passWholeWay && loc != null){ gpxRoute.setStartPoint(loc); } - Location startForRouting = mapActivity.getLastKnownLocation(); + Location startForRouting = getLastKnownLocation(); if(startForRouting == null){ startForRouting = gpxRoute.getStartPointForRoute(); } @@ -711,8 +710,7 @@ public class MapActivityActions implements DialogProvider { endPoint = point; } if(endPoint != null) { - mapActivity.getTargetPoints().navigateToPoint( - mapActivity, point, false, -1); + getTargets().navigateToPoint(point, false, -1); } } if(endPoint != null){ @@ -817,7 +815,7 @@ public class MapActivityActions implements DialogProvider { Builder builder = new AlertDialog.Builder(mapActivity); adapter.registerItem(R.string.context_menu_item_navigate_point, R.drawable.list_view_set_destination); - final TargetPointsHelper targets = mapActivity.getTargetPoints(); + final TargetPointsHelper targets = getMyApplication().getTargetPointsHelper(); if(targets.getPointToNavigate() != null) { adapter.registerItem(R.string.context_menu_item_intermediate_point, R.drawable.list_view_set_intermediate); } @@ -867,8 +865,7 @@ public class MapActivityActions implements DialogProvider { intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); mapActivity.startActivity(intent); } else if (standardId == R.string.context_menu_item_navigate_point) { - mapActivity.getTargetPoints().navigateToPoint(mapActivity, - new LatLon(latitude, longitude), true, -1); + getMyApplication().getTargetPointsHelper().navigateToPoint(new LatLon(latitude, longitude), true, -1); // always enable and follow and let calculate it (GPS is not accessible in garage) if(!routingHelper.isRouteBeingCalculated() && !routingHelper.isRouteCalculated() ) { getDirections(null, new LatLon(latitude, longitude), true); @@ -881,8 +878,8 @@ public class MapActivityActions implements DialogProvider { getDirections(loc, null, true); } } else if (standardId == R.string.context_menu_item_intermediate_point) { - targets.navigateToPoint(mapActivity, - new LatLon(latitude, longitude), true, targets.getIntermediatePoints().size()); + targets.navigateToPoint(new LatLon(latitude, longitude), + true, targets.getIntermediatePoints().size()); IntermediatePointsDialog.openIntermediatePointsDialog(mapActivity); } else if (standardId == R.string.context_menu_item_share_location) { shareLocation(latitude, longitude, mapActivity.getMapView().getZoom()); @@ -999,7 +996,7 @@ public class MapActivityActions implements DialogProvider { if (getMyApplication().getInternalAPI().accessibilityEnabled()) { whereAmIDialog(); } else { - mapActivity.backToLocationImpl(); + mapActivity.getMapViewTrackingUtilities().backToLocationImpl(); } return true; } @@ -1104,7 +1101,7 @@ public class MapActivityActions implements DialogProvider { optionsMenuHelper.registerOptionsMenuItem(R.string.target_points, R.string.target_points, new OnOptionsMenuClick() { @Override public void prepareOptionsMenu(Menu menu, MenuItem item) { - item.setVisible(mapActivity.getTargetPoints().getIntermediatePoints().size() > 0); + item.setVisible(getTargets().getIntermediatePoints().size() > 0); } @Override public boolean onClick(MenuItem item) { @@ -1156,18 +1153,20 @@ public class MapActivityActions implements DialogProvider { public void stopNavigationAction(final OsmandMapTileView mapView) { if (routingHelper.isRouteCalculated() || routingHelper.isFollowingMode() || routingHelper.isRouteBeingCalculated()) { - routingHelper.setFinalAndCurrentLocation(null, new ArrayList(), mapActivity.getLastKnownLocation(), + routingHelper.setFinalAndCurrentLocation(null, new ArrayList(), getLastKnownLocation(), routingHelper.getCurrentGPXRoute()); // restore default mode - boolean changed = settings.APPLICATION_MODE.set(settings.PREV_APPLICATION_MODE.get()); - mapActivity.updateApplicationModeSettings(); - mapView.refreshMap(changed); + settings.APPLICATION_MODE.set(settings.DEFAULT_APPLICATION_MODE.get()); } else { - mapActivity.getTargetPoints().clearPointToNavigate(mapActivity, true); + getTargets().clearPointToNavigate(true); mapView.refreshMap(); } } + + private TargetPointsHelper getTargets() { + return mapActivity.getMyApplication().getTargetPointsHelper(); + } public void stopNavigationActionConfirm(final OsmandMapTileView mapView){ Builder builder = new AlertDialog.Builder(mapActivity); @@ -1179,12 +1178,9 @@ public class MapActivityActions implements DialogProvider { builder.setPositiveButton(R.string.default_buttons_yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - routingHelper.setFinalAndCurrentLocation(null, new ArrayList(), mapActivity.getLastKnownLocation(), + routingHelper.setFinalAndCurrentLocation(null, new ArrayList(), getLastKnownLocation(), routingHelper.getCurrentGPXRoute()); - // restore default mode - boolean changed = settings.APPLICATION_MODE.set(settings.PREV_APPLICATION_MODE.get()); - mapActivity.updateApplicationModeSettings(); - mapView.refreshMap(changed); + settings.APPLICATION_MODE.set(settings.DEFAULT_APPLICATION_MODE.get()); } }); } else { @@ -1194,7 +1190,7 @@ public class MapActivityActions implements DialogProvider { builder.setPositiveButton(R.string.default_buttons_yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - mapActivity.getTargetPoints().clearPointToNavigate(mapActivity, true); + getTargets().clearPointToNavigate(true); mapView.refreshMap(); } }); @@ -1246,11 +1242,11 @@ public class MapActivityActions implements DialogProvider { dialog.dismiss(); switch (item) { case 0: - mapActivity.backToLocationImpl(); + mapActivity.getMapViewTrackingUtilities().backToLocationImpl(); break; case 1: - mapActivity.getNavigationInfo().show(mapActivity.getPointToNavigate(), - mapActivity.getMapLayers().getLocationLayer().getHeading(), mapActivity); + OsmAndLocationProvider locationProvider = getMyApplication().getLocationProvider(); + locationProvider.showNavigationInfo(mapActivity.getPointToNavigate(), mapActivity); break; default: break; diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java index ea194e465a..c3b3a5c6f7 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java @@ -349,7 +349,7 @@ public class MapActivityLayers { if(!settings.SAVE_TRACK_TO_GPX.get()){ AccessibleToast.makeText(activity, R.string.gpx_monitoring_disabled_warn, Toast.LENGTH_SHORT).show(); } - Map data = activity.getSavingTrackHelper().collectRecordedData(); + Map data = getApplication().getSavingTrackHelper().collectRecordedData(); if(toShow == null) { toShow = new GPXFile(); toShow.showCurrentTrack = true; diff --git a/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java b/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java index a6df48cd08..49e30628e1 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java +++ b/OsmAnd/src/net/osmand/plus/activities/SavingTrackHelper.java @@ -16,7 +16,10 @@ import net.osmand.plus.GPXUtilities.GPXFile; import net.osmand.plus.GPXUtilities.Track; import net.osmand.plus.GPXUtilities.TrkSegment; import net.osmand.plus.GPXUtilities.WptPt; +import net.osmand.plus.monitoring.OsmandMonitoringPlugin; +import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandSettings; import org.apache.commons.logging.Log; @@ -278,6 +281,17 @@ public class SavingTrackHelper extends SQLiteOpenHelper { addTrackPoint(null, true); } + public void updateLocation(net.osmand.Location location) { + // use because there is a bug on some devices with location.getTime() + long locationTime = System.currentTimeMillis(); + OsmandSettings settings = ctx.getSettings(); + if (OsmAndLocationProvider.isPointAccurateForRouting(location) && settings.SAVE_TRACK_TO_GPX.get() + && OsmandPlugin.getEnabledPlugin(OsmandMonitoringPlugin.class) != null) { + insertData(location.getLatitude(), location.getLongitude(), location.getAltitude(), location.getSpeed(), + location.getAccuracy(), locationTime, settings); + } + } + public void insertData(double lat, double lon, double alt, double speed, double hdop, long time, OsmandSettings settings){ //* 1000 in next line seems to be wrong with new IntervalChooseDialog //if (time - lastTimeUpdated > settings.SAVE_TRACK_INTERVAL.get() * 1000) { diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java index 643229999e..87f464a240 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java @@ -538,6 +538,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference routerServicePreference.setSummary(getString(R.string.router_service_descr) + " [" + osmandSettings.ROUTER_SERVICE.get() + "]"); } else if (listPref.getId().equals(osmandSettings.APPLICATION_MODE.getId())) { + osmandSettings.DEFAULT_APPLICATION_MODE.set(osmandSettings.APPLICATION_MODE.get()); updateAllSettings(); } else if (listPref.getId().equals(osmandSettings.PREFERRED_LOCALE.getId())) { // restart application to update locale diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchActivity.java index 2f5a66b9fa..d9b7cb1964 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchActivity.java @@ -8,6 +8,8 @@ import java.util.Locale; import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; +import net.osmand.plus.OsmAndLocationProvider; +import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; @@ -17,9 +19,6 @@ import net.osmand.util.Algorithms; import android.app.Activity; import android.app.TabActivity; import android.content.Intent; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; @@ -36,7 +35,7 @@ import android.widget.TabWidget; import android.widget.TextView; -public class SearchActivity extends TabActivity { +public class SearchActivity extends TabActivity implements OsmAndLocationListener { private static final String SEARCH_HISTORY = "Search_History"; private static final String SEARCH_FAVORITES = "Search_Favorites"; private static final String SEARCH_TRANSPORT = "Search_Transport"; @@ -55,10 +54,6 @@ public class SearchActivity extends TabActivity { protected static final int POSITION_FAVORITES = 3; protected static final int POSITION_ADDRESS = 4; - private static final int GPS_TIMEOUT_REQUEST = 1000; - private static final int GPS_DIST_REQUEST = 5; - private static final int GPS_ACCURACY = 50; - private static final int REQUEST_FAVORITE_SELECT = 1; private static final int REQUEST_ADDRESS_SELECT = 2; @@ -72,7 +67,6 @@ public class SearchActivity extends TabActivity { private boolean searchAroundCurrentLocation = false; private static boolean searchOnLine = false; - private LocationListener locationListener = null; private ArrayAdapter spinnerAdapter; private Spinner spinner; private OsmandSettings settings; @@ -178,8 +172,13 @@ public class SearchActivity extends TabActivity { public void onItemSelected(AdapterView parent, View view, int position, long id) { if (position != 0) { if (position == POSITION_CURRENT_LOCATION) { - startSearchCurrentLocation(); - searchAroundCurrentLocation = true; + net.osmand.Location loc = getLocationProvider().getLastKnownLocation(); + if(loc != null && System.currentTimeMillis() - loc.getTime() < 10000) { + updateLocation(loc); + } else { + startSearchCurrentLocation(); + searchAroundCurrentLocation = true; + } } else { searchAroundCurrentLocation = false; endSearchCurrentLocation(); @@ -232,43 +231,29 @@ public class SearchActivity extends TabActivity { } - - public void startSearchCurrentLocation(){ - if(locationListener == null){ - locationListener = new LocationListener() { - @Override - public void onStatusChanged(String provider, int status, Bundle extras) {} - @Override - public void onProviderEnabled(String provider) {} - @Override - public void onProviderDisabled(String provider) {} - @Override - public void onLocationChanged(Location location) { - if(location != null){ - updateSearchPoint(new LatLon(location.getLatitude(), location.getLongitude()), - getString(R.string.search_position_current_location_found), false); - if(location.getAccuracy() < GPS_ACCURACY){ - endSearchCurrentLocation(); - } - } - - } - }; - LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); - for(String provider : locationManager.getAllProviders()){ - locationManager.requestLocationUpdates(provider, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, locationListener); + public void updateLocation(net.osmand.Location location){ + if (location != null) { + updateSearchPoint(new LatLon(location.getLatitude(), location.getLongitude()), + getString(R.string.search_position_current_location_found), false); + if (location.getAccuracy() < 20) { + endSearchCurrentLocation(); } } + } + public void startSearchCurrentLocation(){ + getLocationProvider().resumeAllUpdates(); + getLocationProvider().addLocationListener(this); updateSearchPoint(null, getString(R.string.search_position_current_location_search), false); } + + private OsmAndLocationProvider getLocationProvider() { + return ((OsmandApplication) getApplication()).getLocationProvider(); + } public void endSearchCurrentLocation(){ - if (locationListener != null) { - LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); - locationManager.removeUpdates(locationListener); - locationListener = null; - } + getLocationProvider().pauseAllUpdates(); + getLocationProvider().removeLocationListener(this); } @Override diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java index 0b8c21b885..8e4a9d575c 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java @@ -17,7 +17,6 @@ import java.util.Map.Entry; import net.londatiga.android.ActionItem; import net.londatiga.android.QuickAction; -import net.osmand.PlatformUtil; import net.osmand.ResultMatcher; import net.osmand.access.AccessibleToast; import net.osmand.access.NavigationInfo; @@ -26,6 +25,8 @@ import net.osmand.data.AmenityType; import net.osmand.data.LatLon; import net.osmand.plus.NameFinderPoiFilter; import net.osmand.plus.OsmAndFormatter; +import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener; +import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandSettings; import net.osmand.plus.PoiFilter; @@ -51,17 +52,9 @@ import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Path; import android.graphics.drawable.Drawable; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.location.LocationProvider; import android.os.AsyncTask; import android.os.AsyncTask.Status; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -70,7 +63,6 @@ import android.text.Spannable; import android.text.TextWatcher; import android.text.style.ForegroundColorSpan; import android.util.DisplayMetrics; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -89,18 +81,13 @@ import android.widget.Toast; /** * Search poi activity */ -public class SearchPOIActivity extends OsmandListActivity implements SensorEventListener { +public class SearchPOIActivity extends OsmandListActivity implements OsmAndCompassListener, OsmAndLocationListener { public static final String AMENITY_FILTER = "net.osmand.amenity_filter"; //$NON-NLS-1$ public static final String SEARCH_LAT = SearchActivity.SEARCH_LAT; //$NON-NLS-1$ public static final String SEARCH_LON = SearchActivity.SEARCH_LON; //$NON-NLS-1$ - private static final int GPS_TIMEOUT_REQUEST = 1000; - private static final int GPS_DIST_REQUEST = 5; - private static final int MIN_DISTANCE_TO_RESEARCH = 70; - private static final int MIN_DISTANCE_TO_UPDATE = 6; - - private NavigationInfo navigationInfo; - + private static final float MIN_DISTANCE_TO_RESEARCH = 20; + private static final float MIN_DISTANCE_TO_REFRESH = 5; private Button searchPOILevel; private ImageButton showOnMap; @@ -115,8 +102,6 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent private net.osmand.Location location = null; private Float heading = null; - private String currentLocationProvider = null; - private boolean sensorRegistered = false; private Handler uiHandler; private OsmandSettings settings; private Path directionPath = new Path(); @@ -126,16 +111,18 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent // never null represents current running task or last finished private SearchAmenityTask currentSearchTask = new SearchAmenityTask(null); private CustomTitleBar titleBar; + private OsmandApplication app; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - navigationInfo = new NavigationInfo(this); titleBar = new CustomTitleBar(this, R.string.searchpoi_activity, R.drawable.tab_search_poi_icon); setContentView(R.layout.searchpoi); titleBar.afterSetContentView(); + app = (OsmandApplication)getApplication(); + uiHandler = new Handler(); searchPOILevel = (Button) findViewById(R.id.SearchPOILevelButton); searchArea = (TextView) findViewById(R.id.SearchAreaText); @@ -276,7 +263,7 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent } String filterId = bundle.getString(AMENITY_FILTER); - PoiFilter filter = ((OsmandApplication)getApplication()).getPoiFilters().getFilterById(filterId); + PoiFilter filter = app.getPoiFilters().getFilterById(filterId); if (filter != this.filter) { this.filter = filter; if (filter != null) { @@ -309,19 +296,13 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent if (filter != null) { searchArea.setText(filter.getSearchArea()); updateSearchPoiTextButton(); - - setLocation(location); if (searchNearBy) { - LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); - service.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, gpsListener); - currentLocationProvider = LocationManager.GPS_PROVIDER; - if (!isRunningOnEmulator()) { - // try to always ask for network provide it is faster way to find location - service.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, - networkListener); - currentLocationProvider = LocationManager.NETWORK_PROVIDER; - } + app.getLocationProvider().addCompassListener(this); + app.getLocationProvider().addLocationListener(this); + location = app.getLocationProvider().getLastKnownLocation(); + app.getLocationProvider().resumeAllUpdates(); } + updateLocation(location); } } @@ -381,36 +362,6 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent } } - public void setLocation(net.osmand.Location l){ - registerUnregisterSensor(l); - navigationInfo.setLocation(l); - boolean handled = false; - if (l != null && filter != null) { - net.osmand.Location searchedLocation = getSearchedLocation(); - if (searchedLocation == null) { - searchedLocation = l; - if (!isNameFinderFilter() && !isSearchByNameFilter()) { - runNewSearchQuery(SearchAmenityRequest.buildRequest(l, SearchAmenityRequest.NEW_SEARCH_INIT)); - } - handled = true; - } else if (l.distanceTo(searchedLocation) > MIN_DISTANCE_TO_RESEARCH) { - runNewSearchQuery(SearchAmenityRequest.buildRequest(l, SearchAmenityRequest.SEARCH_AGAIN)); - handled = true; - } else if(location == null || location.distanceTo(l) > MIN_DISTANCE_TO_UPDATE){ - handled = true; - } - } else { - if(location != null){ - handled = true; - } - } - if(handled) { - location = l; - updateSearchPoiTextButton(); - amenityAdapter.notifyDataSetInvalidated(); - } - - } private net.osmand.Location getSearchedLocation(){ return currentSearchTask.getSearchedLocation(); @@ -432,13 +383,6 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent } - private boolean isRunningOnEmulator(){ - if (Build.DEVICE.equals("generic")) { //$NON-NLS-1$ - return true; - } - return false; - } - public boolean isNameFinderFilter(){ return filter instanceof NameFinderPoiFilter; } @@ -449,14 +393,48 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent @Override - public void onSensorChanged(SensorEvent event) { - // Attention : sensor produces a lot of events & can hang the system - if(heading != null && Math.abs(heading - event.values[0]) < 4){ - // this is very small variation - return; + public void updateLocation(net.osmand.Location location) { + app.getLocationProvider().registerOrUnregisterCompassListener(location != null); + boolean handled = false; + if (location != null && filter != null) { + net.osmand.Location searchedLocation = getSearchedLocation(); + if (searchedLocation == null) { + searchedLocation = location; + if (!isNameFinderFilter() && !isSearchByNameFilter()) { + runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.NEW_SEARCH_INIT)); + } + handled = true; + } else if (location.distanceTo(searchedLocation) > MIN_DISTANCE_TO_RESEARCH) { + searchedLocation = location; + runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.SEARCH_AGAIN)); + handled = true; + } else if (location.distanceTo(searchedLocation) > MIN_DISTANCE_TO_REFRESH){ + handled = true; + } + } else { + if(location != null){ + handled = true; + } } - heading = event.values[0]; + if (handled) { + this.location = location; + updateSearchPoiTextButton(); + // Get the top position from the first visible element + int idx = getListView().getFirstVisiblePosition(); + View vfirst = getListView().getChildAt(0); + int pos = 0; + if (vfirst != null) + pos = vfirst.getTop(); + amenityAdapter.notifyDataSetInvalidated(); + // Restore the position + getListView().setSelectionFromTop(idx, pos); + } + } + + @Override + public void updateCompassValue(float value) { + heading = value; if(!uiHandler.hasMessages(5)){ Message msg = Message.obtain(uiHandler, new Runnable(){ @Override @@ -467,49 +445,16 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent msg.what = 5; uiHandler.sendMessageDelayed(msg, 100); } - } - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - } - - - private void registerUnregisterSensor(net.osmand.Location location){ - // show point view only if gps enabled - if(location == null){ - if(sensorRegistered) { - Log.d(PlatformUtil.TAG, "Disable sensor"); //$NON-NLS-1$ - ((SensorManager) getSystemService(SENSOR_SERVICE)).unregisterListener(this); - sensorRegistered = false; - heading = null; - } - } else { - if(!sensorRegistered){ - Log.d(PlatformUtil.TAG, "Enable sensor"); //$NON-NLS-1$ - SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); - Sensor s = sensorMgr.getDefaultSensor(Sensor.TYPE_ORIENTATION); - if (s != null) { - sensorMgr.registerListener(this, s, SensorManager.SENSOR_DELAY_UI); - } - sensorRegistered = true; - } - } - } - @Override protected void onPause() { super.onPause(); if (searchNearBy) { - LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); - service.removeUpdates(gpsListener); - service.removeUpdates(networkListener); - - SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE); - sensorMgr.unregisterListener(this); - sensorRegistered = false; - currentLocationProvider = null; + app.getLocationProvider().pauseAllUpdates(); + app.getLocationProvider().removeCompassListener(this); + app.getLocationProvider().removeLocationListener(this); } } @@ -823,6 +768,7 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent } }); List attributes = new ArrayList(); + NavigationInfo navigationInfo = app.getLocationProvider().getNavigationInfo(); String direction = navigationInfo.getDirectionString(amenity.getLocation(), heading); if (direction != null) attributes.add(direction); @@ -841,66 +787,6 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent b.show(); } - // Working with location listeners - private LocationListener networkListener = new LocationListener(){ - @Override - public void onLocationChanged(Location location) { - setLocation(MapActivity.convertLocation(location, getMyApplication())); - } - - @Override - public void onProviderDisabled(String provider) { - setLocation(null); - } - - @Override - public void onProviderEnabled(String provider) { - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - if(LocationProvider.OUT_OF_SERVICE == status){ - setLocation(null); - } - } - }; - private LocationListener gpsListener = new LocationListener(){ - @Override - public void onLocationChanged(Location location) { - setLocation(MapActivity.convertLocation(location, getMyApplication())); - } - - @Override - public void onProviderDisabled(String provider) { - setLocation(null); - } - - @Override - public void onProviderEnabled(String provider) { - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE); - // do not change provider for temporarily unavailable (possible bug for htc hero 2.1 ?) - if (LocationProvider.OUT_OF_SERVICE == status /*|| LocationProvider.TEMPORARILY_UNAVAILABLE == status*/) { - if(LocationProvider.OUT_OF_SERVICE == status){ - setLocation(null); - } - if (!isRunningOnEmulator() && service.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { - if (!Algorithms.objectEquals(currentLocationProvider, LocationManager.NETWORK_PROVIDER)) { - currentLocationProvider = LocationManager.NETWORK_PROVIDER; - service.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, GPS_TIMEOUT_REQUEST, GPS_DIST_REQUEST, this); - } - } - } else if (LocationProvider.AVAILABLE == status) { - if (!Algorithms.objectEquals(currentLocationProvider, LocationManager.GPS_PROVIDER)) { - currentLocationProvider = LocationManager.GPS_PROVIDER; - service.removeUpdates(networkListener); - } - } - } - }; class DirectionDrawable extends Drawable { Paint paintRouteDirection; @@ -953,4 +839,6 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent paintRouteDirection.setColorFilter(cf); } } + + } diff --git a/OsmAnd/src/net/osmand/plus/api/InternalToDoAPIImpl.java b/OsmAnd/src/net/osmand/plus/api/InternalToDoAPIImpl.java index f51dea288f..21b0b90f99 100644 --- a/OsmAnd/src/net/osmand/plus/api/InternalToDoAPIImpl.java +++ b/OsmAnd/src/net/osmand/plus/api/InternalToDoAPIImpl.java @@ -7,7 +7,6 @@ import net.osmand.binary.BinaryMapIndexReader; import net.osmand.map.ITileSource; import net.osmand.map.TileSourceManager.TileSourceTemplate; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.OsmandSettings.DayNightMode; import net.osmand.plus.SQLiteTileSource; public class InternalToDoAPIImpl implements InternalToDoAPI { @@ -18,21 +17,11 @@ public class InternalToDoAPIImpl implements InternalToDoAPI { this.app = app; } - @Override - public void forceMapRendering() { - app.getResourceManager().getRenderer().clearCache(); - } - @Override public BinaryMapIndexReader[] getRoutingMapFiles() { return app.getResourceManager().getRoutingMapFiles(); } - @Override - public void setDayNightMode(DayNightMode val) { - app.getDaynightHelper().setDayNightMode(val); - } - @Override public ITileSource newSqliteTileSource(File dir, List knownTemplates) { return new SQLiteTileSource(app, dir, knownTemplates); diff --git a/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java b/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java index d74260385d..275c7c2b6d 100644 --- a/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java +++ b/OsmAnd/src/net/osmand/plus/audionotes/AudioVideoNotesPlugin.java @@ -474,7 +474,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin { } private void defaultAction(final MapActivity mapActivity) { - final Location loc = mapActivity.getLastKnownLocation(); + final Location loc = app.getLocationProvider().getLastKnownLocation(); // double lat = mapActivity.getMapView().getLatitude(); // double lon = mapActivity.getMapView().getLongitude(); if (loc == null) { @@ -838,8 +838,9 @@ public class AudioVideoNotesPlugin extends OsmandPlugin { LatLon l = MapUtils.decodeShortLocString(encodeName); r.lat = l.getLatitude(); r.lon = l.getLongitude(); - if(lastTakingPhoto != null && lastTakingPhoto.getName().equals(f.getName())) { - float rot = activity.getLastSensorRotation(); + Float heading = app.getLocationProvider().getHeading(); + if(lastTakingPhoto != null && lastTakingPhoto.getName().equals(f.getName()) && heading != null) { + float rot = heading.floatValue(); try { r.updatePhotoInformation(r.lat, r.lon, rot == 0 ? Double.NaN : rot); } catch (IOException e) { diff --git a/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java b/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java new file mode 100644 index 0000000000..7443cf32f6 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/base/FailSafeFuntions.java @@ -0,0 +1,145 @@ +package net.osmand.plus.base; + +import java.io.File; +import java.util.ArrayList; + +import net.osmand.access.AccessibleAlertBuilder; +import net.osmand.data.LatLon; +import net.osmand.plus.GPXUtilities; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandSettings; +import net.osmand.plus.R; +import net.osmand.plus.TargetPointsHelper; +import net.osmand.plus.GPXUtilities.GPXFile; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.routing.RouteProvider.GPXRouteParams; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; +import android.content.DialogInterface; +import android.content.DialogInterface.OnCancelListener; +import android.content.DialogInterface.OnDismissListener; +import android.os.AsyncTask; +import android.os.Handler; +import android.widget.TextView; + +public class FailSafeFuntions { + private static boolean quitRouteRestoreDialog = false; + + public static void restoreRoutingMode(final MapActivity ma) { + final OsmandApplication app = ma.getMyApplication(); + final OsmandSettings settings = app.getSettings(); + final Handler uiHandler = new Handler(); + final String gpxPath = settings.FOLLOW_THE_GPX_ROUTE.get(); + final TargetPointsHelper targetPoints = app.getTargetPointsHelper(); + final LatLon pointToNavigate = targetPoints.getPointToNavigate(); + if (pointToNavigate == null && gpxPath == null) { + notRestoreRoutingMode(ma, app); + } else { + quitRouteRestoreDialog = false; + Runnable encapsulate = new Runnable() { + int delay = 7; + Runnable delayDisplay = null; + + @Override + public void run() { + Builder builder = new AccessibleAlertBuilder(ma); + final TextView tv = new TextView(ma); + tv.setText(ma.getString(R.string.continue_follow_previous_route_auto, delay + "")); + tv.setPadding(7, 5, 7, 5); + builder.setView(tv); + builder.setPositiveButton(R.string.default_buttons_yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + quitRouteRestoreDialog = true; + restoreRoutingModeInner(); + + } + }); + builder.setNegativeButton(R.string.default_buttons_no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + quitRouteRestoreDialog = true; + notRestoreRoutingMode(ma, app); + } + }); + final AlertDialog dlg = builder.show(); + dlg.setOnDismissListener(new OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + quitRouteRestoreDialog = true; + } + }); + dlg.setOnCancelListener(new OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + quitRouteRestoreDialog = true; + } + }); + delayDisplay = new Runnable() { + @Override + public void run() { + if(!quitRouteRestoreDialog) { + delay --; + tv.setText(ma.getString(R.string.continue_follow_previous_route_auto, delay + "")); + if(delay <= 0) { + if(dlg.isShowing() && !quitRouteRestoreDialog) { + dlg.dismiss(); + } + quitRouteRestoreDialog = true; + restoreRoutingModeInner(); + } else { + uiHandler.postDelayed(delayDisplay, 1000); + } + } + } + }; + delayDisplay.run(); + } + + private void restoreRoutingModeInner() { + AsyncTask task = new AsyncTask() { + @Override + protected GPXFile doInBackground(String... params) { + if (gpxPath != null) { + // Reverse also should be stored ? + GPXFile f = GPXUtilities.loadGPXFile(app, new File(gpxPath), false); + if (f.warning != null) { + return null; + } + return f; + } else { + return null; + } + } + + @Override + protected void onPostExecute(GPXFile result) { + final GPXRouteParams gpxRoute = result == null ? null : new GPXRouteParams(result, false, settings); + LatLon endPoint = pointToNavigate != null ? pointToNavigate : gpxRoute.getLastPoint(); + net.osmand.Location startPoint = gpxRoute == null ? null : gpxRoute.getStartPointForRoute(); + if (endPoint == null) { + notRestoreRoutingMode(ma, app); + } else { + ma.followRoute(settings.getApplicationMode(), endPoint, targetPoints.getIntermediatePoints(), startPoint, gpxRoute); + } + } + }; + task.execute(gpxPath); + + } + }; + encapsulate.run(); + } + + } + + private static void notRestoreRoutingMode(MapActivity ma, OsmandApplication app){ + ma.updateApplicationModeSettings(); + app.getRoutingHelper().clearCurrentRoute(null, new ArrayList()); + ma.refreshMap(); + } + + public static void quitRouteRestoreDialog() { + quitRouteRestoreDialog = true; + } +} diff --git a/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java new file mode 100644 index 0000000000..49acb94704 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/base/MapViewTrackingUtilities.java @@ -0,0 +1,263 @@ +package net.osmand.plus.base; + +import android.content.Context; +import android.view.WindowManager; +import net.osmand.Location; +import net.osmand.StateChangedListener; +import net.osmand.map.IMapLocationListener; +import net.osmand.plus.OsmAndLocationProvider; +import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener; +import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandSettings; +import net.osmand.plus.R; +import net.osmand.plus.routing.RoutingHelper; +import net.osmand.plus.views.AnimateDraggingMapThread; +import net.osmand.plus.views.OsmandMapTileView; +import net.osmand.util.MapUtils; + +public class MapViewTrackingUtilities implements OsmAndLocationListener, IMapLocationListener, OsmAndCompassListener { + private static final int AUTO_FOLLOW_MSG_ID = 8; + + private long lastTimeAutoZooming = 0; + private long lastTimeSensorMapRotation = 0; + private boolean sensorRegistered = false; + private OsmandMapTileView mapView; + private OsmandSettings settings; + private OsmandApplication app; + // by default turn off causing unexpected movements due to network establishing + private boolean isMapLinkedToLocation = false; + private boolean followingMode; + + + + public MapViewTrackingUtilities(OsmandApplication app){ + this.app = app; + settings = app.getSettings(); + app.getLocationProvider().addLocationListener(this); + app.getLocationProvider().addCompassListener(this); + addTargetPointListener(app); + } + + private void addTargetPointListener(OsmandApplication app) { + app.getTargetPointsHelper().addListener(new StateChangedListener() { + + @Override + public void stateChanged(Void change) { + if(mapView != null) { + mapView.refreshMap(); + } + } + }); + } + + public void setMapView(OsmandMapTileView mapView) { + this.mapView = mapView; + if(mapView != null) { + WindowManager wm = (WindowManager) app.getSystemService(Context.WINDOW_SERVICE); + int orientation = wm.getDefaultDisplay().getOrientation(); + app.getLocationProvider().updateScreenOrientation(orientation); + mapView.setMapLocationListener(this); + } + } + + @Override + public void updateCompassValue(float val) { + if (mapView != null) { + if (settings.ROTATE_MAP.get() == OsmandSettings.ROTATE_MAP_COMPASS) { + if (Math.abs(MapUtils.degreesDiff(mapView.getRotate(), -val)) > 15) { + mapView.setRotate(-val); + } + } else if (settings.SHOW_VIEW_ANGLE.get()) { + mapView.refreshMap(); + } + } + } + + @Override + public void updateLocation(Location location) { + if (mapView != null) { + if (isMapLinkedToLocation() && location != null) { + if (settings.AUTO_ZOOM_MAP.get()) { + autozoom(location); + } + int currentMapRotation = settings.ROTATE_MAP.get(); + if (currentMapRotation == OsmandSettings.ROTATE_MAP_BEARING) { + if (location.hasBearing()) { + // special case when bearing equals to zero (we don't change anything) + if (location.getBearing() != 0f) { + mapView.setRotate(-location.getBearing()); + } + } else if (app.getRoutingHelper().isFollowingMode() && settings.USE_COMPASS_IN_NAVIGATION.get()) { + long now = System.currentTimeMillis(); + OsmAndLocationProvider provider = app.getLocationProvider(); + Float lastSensorRotation = provider.getHeading(); + if (lastSensorRotation != null && Math.abs(MapUtils.degreesDiff(mapView.getRotate(), -lastSensorRotation)) > 15) { + if (now - lastTimeSensorMapRotation > 1500) { + lastTimeSensorMapRotation = now; + mapView.setRotate(-lastSensorRotation); + } + } + } + } + mapView.setLatLon(location.getLatitude(), location.getLongitude()); + + RoutingHelper routingHelper = app.getRoutingHelper(); + boolean enableSensorNavigation = false; + if(routingHelper.isFollowingMode() && settings.USE_COMPASS_IN_NAVIGATION.get()) { + enableSensorNavigation = !location.hasBearing() ; + } + registerUnregisterSensor(location, enableSensorNavigation); + } + RoutingHelper routingHelper = app.getRoutingHelper(); + // we arrived at destination finished + if (!routingHelper.isFollowingMode() && followingMode) { + app.runInUIThread(new Runnable() { + @Override + public void run() { + settings.APPLICATION_MODE.set(settings.DEFAULT_APPLICATION_MODE.get()); + } + }); + + } + followingMode = routingHelper.isFollowingMode(); + + // When location is changed we need to refresh map in order to show movement! + mapView.refreshMap(); + } + + } + + public void updateSettings(){ + if(settings.ROTATE_MAP.get() != OsmandSettings.ROTATE_MAP_COMPASS){ + mapView.setRotate(0); + } + mapView.setMapPosition(settings.ROTATE_MAP.get() == OsmandSettings.ROTATE_MAP_BEARING + ? OsmandSettings.BOTTOM_CONSTANT : OsmandSettings.CENTER_CONSTANT); + registerUnregisterSensor(app.getLocationProvider().getLastKnownLocation(), false); + } + + private void registerUnregisterSensor(net.osmand.Location location, boolean overruleRegister) { + boolean currentShowingAngle = settings.SHOW_VIEW_ANGLE.get(); + int currentMapRotation = settings.ROTATE_MAP.get(); + boolean registerCompassListener = overruleRegister || (currentShowingAngle && location != null) + || currentMapRotation == OsmandSettings.ROTATE_MAP_COMPASS; + // show point view only if gps enabled + if(sensorRegistered != registerCompassListener) { + app.getLocationProvider().registerOrUnregisterCompassListener(registerCompassListener); + } + } + + private float defineZoomFromSpeed(float speed) { + if (speed < 7f / 3.6) { + return 0; + } + double topLat = mapView.calcLatitude(-mapView.getCenterPointY()); + double cLat = mapView.calcLatitude(0); + double visibleDist = MapUtils.getDistance(cLat, mapView.getLongitude(), topLat, mapView.getLongitude()); + float time = 75f; + if (speed < 83f / 3.6) { + time = 60f; + } + double distToSee = speed * time; + float zoomDelta = (float) (Math.log(visibleDist / distToSee) / Math.log(2.0f)); + zoomDelta = Math.round(zoomDelta * OsmandMapTileView.ZOOM_DELTA) * OsmandMapTileView.ZOOM_DELTA_1; + // check if 17, 18 is correct? + if (zoomDelta + mapView.getFloatZoom() > 18 - OsmandMapTileView.ZOOM_DELTA_1) { + return 18 - OsmandMapTileView.ZOOM_DELTA_1 - mapView.getFloatZoom(); + } + return zoomDelta; + } + + public void autozoom(Location location) { + if (location.hasSpeed()) { + long now = System.currentTimeMillis(); + float zdelta = defineZoomFromSpeed(location.getSpeed()); + if (Math.abs(zdelta) >= OsmandMapTileView.ZOOM_DELTA_1) { + // prevent ui hysteresis (check time interval for autozoom) + if (zdelta >= 2) { + // decrease a bit + zdelta -= 3 * OsmandMapTileView.ZOOM_DELTA_1; + } else if (zdelta <= -2) { + // decrease a bit + zdelta += 3 * OsmandMapTileView.ZOOM_DELTA_1; + } + if (now - lastTimeAutoZooming > 4500) { + lastTimeAutoZooming = now; + float newZoom = Math.round((mapView.getFloatZoom() + zdelta) * OsmandMapTileView.ZOOM_DELTA) + * OsmandMapTileView.ZOOM_DELTA_1; + mapView.setZoom(newZoom); + // mapView.getAnimatedDraggingThread().startZooming(mapView.getFloatZoom() + zdelta, false); + } + } + } + } + + public void backToLocationImpl() { + if (mapView != null) { + OsmAndLocationProvider locationProvider = app.getLocationProvider(); + if (!isMapLinkedToLocation()) { + setMapLinkedToLocation(true); + if (locationProvider.getLastKnownLocation() != null) { + net.osmand.Location lastKnownLocation = locationProvider.getLastKnownLocation(); + AnimateDraggingMapThread thread = mapView.getAnimatedDraggingThread(); + float fZoom = mapView.getFloatZoom() < 15 ? 15 : mapView.getFloatZoom(); + thread.startMoving(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude(), fZoom, false); + } + mapView.refreshMap(); + } + if (locationProvider.getLastKnownLocation() == null) { + app.showToastMessage(R.string.unknown_location); + } + } + } + + private void backToLocationWithDelay(int delay) { + app.runMessageInUIThreadAndCancelPrevious(AUTO_FOLLOW_MSG_ID, new Runnable() { + @Override + public void run() { + if (mapView != null && !isMapLinkedToLocation()) { + app.showToastMessage(R.string.auto_follow_location_enabled); + backToLocationImpl(); + } + } + }, delay * 1000); + } + + public boolean isMapLinkedToLocation(){ + return isMapLinkedToLocation; + } + + public void setMapLinkedToLocation(boolean isMapLinkedToLocation) { + if(!isMapLinkedToLocation){ + int autoFollow = settings.AUTO_FOLLOW_ROUTE.get(); + if(autoFollow > 0 && app.getRoutingHelper().isFollowingMode()){ + backToLocationWithDelay(autoFollow); + } + } + this.isMapLinkedToLocation = isMapLinkedToLocation; + } + + @Override + public void locationChanged(double newLatitude, double newLongitude, Object source) { + // when user start dragging + if(app.getLocationProvider().getLastKnownLocation() != null){ + setMapLinkedToLocation(false); + } + } + + public void switchRotateMapMode(){ + int vl = (settings.ROTATE_MAP.get() + 1) % 3; + settings.ROTATE_MAP.set(vl); + int resId = R.string.rotate_map_none_opt; + if(settings.ROTATE_MAP.get() == OsmandSettings.ROTATE_MAP_COMPASS){ + resId = R.string.rotate_map_compass_opt; + } else if(settings.ROTATE_MAP.get() == OsmandSettings.ROTATE_MAP_BEARING){ + resId = R.string.rotate_map_bearing_opt; + } + app.showShortToastMessage(resId); + updateSettings(); + mapView.refreshMap(); + } + +} diff --git a/OsmAnd/src/net/osmand/plus/development/OsmandDevelopmentPlugin.java b/OsmAnd/src/net/osmand/plus/development/OsmandDevelopmentPlugin.java index 1bd57419fb..1f1b63c6dd 100644 --- a/OsmAnd/src/net/osmand/plus/development/OsmandDevelopmentPlugin.java +++ b/OsmAnd/src/net/osmand/plus/development/OsmandDevelopmentPlugin.java @@ -4,14 +4,13 @@ import java.text.SimpleDateFormat; import net.osmand.plus.OptionsMenuHelper; import net.osmand.plus.OptionsMenuHelper.OnOptionsMenuClick; +import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.SettingsActivity; -import net.osmand.plus.routing.RouteAnimation; -import net.osmand.plus.routing.RoutingHelper; import net.osmand.util.SunriseSunset; import android.content.Intent; import android.os.Debug; @@ -28,7 +27,6 @@ public class OsmandDevelopmentPlugin extends OsmandPlugin { private static final String ID = "osmand.development"; private OsmandSettings settings; private OsmandApplication app; - private RouteAnimation routeAnimation = new RouteAnimation(); public OsmandDevelopmentPlugin(OsmandApplication app) { this.app = app; @@ -59,18 +57,18 @@ public class OsmandDevelopmentPlugin extends OsmandPlugin { @Override public void registerOptionsMenuItems(final MapActivity mapActivity, OptionsMenuHelper helper) { + final OsmAndLocationProvider loc = mapActivity.getMyApplication().getLocationProvider(); helper.registerOptionsMenuItem(R.string.animate_route, R.string.animate_route, false, new OnOptionsMenuClick() { @Override public void prepareOptionsMenu(Menu menu, MenuItem animateMenu) { - animateMenu.setTitle(routeAnimation.isRouteAnimating() ? R.string.animate_route_off : R.string.animate_route); + animateMenu.setTitle(loc.getLocationSimulation().isRouteAnimating() ? R.string.animate_route_off : R.string.animate_route); animateMenu.setVisible(app.getTargetPointsHelper().getPointToNavigate() != null); } @Override public boolean onClick(MenuItem item) { - RoutingHelper routingHelper = mapActivity.getRoutingHelper(); // animate moving on route - routeAnimation.startStopRouteAnimation(routingHelper, mapActivity); + loc.getLocationSimulation().startStopRouteAnimation(mapActivity); return true; } }); diff --git a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java index 903147cf3a..9633164cb6 100644 --- a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java @@ -197,7 +197,7 @@ public class ContextMenuLayer extends OsmandMapLayer { public boolean onLongPressEvent(PointF point) { if ((Build.VERSION.SDK_INT < 14) && !view.getSettings().SCROLL_MAP_BY_GESTURES.get()) { if (!selectedObjects.isEmpty()) - view.showMessage(activity.getNavigationHint(latLon)); + view.showMessage(activity.getMyApplication().getLocationProvider().getNavigationHint(latLon)); return true; } diff --git a/OsmAnd/src/net/osmand/plus/views/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/MapControlsLayer.java index 7d55bbc712..960c988c77 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapControlsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/MapControlsLayer.java @@ -3,10 +3,12 @@ package net.osmand.plus.views; import net.londatiga.android.ActionItem; import net.londatiga.android.QuickAction; import net.osmand.util.MapUtils; +import net.osmand.data.LatLon; import net.osmand.plus.ApplicationMode; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandSettings.CommonPreference; import net.osmand.plus.R; +import net.osmand.plus.activities.MainMenuActivity; import net.osmand.plus.activities.MapActivity; import android.content.Context; import android.graphics.Canvas; @@ -180,8 +182,6 @@ public class MapControlsLayer extends OsmandMapLayer { @Override public void onClick(View v) { view.getSettings().APPLICATION_MODE.set(modes[j]); - activity.updateApplicationModeSettings(); - view.refreshMap(true); mQuickAction.dismiss(); } }); @@ -253,7 +253,9 @@ public class MapControlsLayer extends OsmandMapLayer { backToMenuButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - activity.backToMainMenu(); + double lat = activity.getMapView().getLatitude(); + double lon = activity.getMapView().getLongitude(); + MainMenuActivity.backToMainMenuDialog(activity, new LatLon(lat, lon)); } }); diff --git a/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java b/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java index cd002891a6..17f98a0ba8 100644 --- a/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/MapInfoLayer.java @@ -180,26 +180,26 @@ public class MapInfoLayer extends OsmandMapLayer { statusBar = new LinearLayout(view.getContext()); statusBar.setOrientation(LinearLayout.HORIZONTAL); RouteInfoControls ric = new RouteInfoControls(scaleCoefficient); - lanesControl = ric.createLanesControl(view.getApplication().getRoutingHelper(), view); + OsmandApplication app = view.getApplication(); + lanesControl = ric.createLanesControl(app.getRoutingHelper(), view); lanesControl.setBackgroundDrawable(view.getResources().getDrawable(R.drawable.box_free)); - alarmControl = ric.createAlarmInfoControl(view.getApplication().getRoutingHelper(), + alarmControl = ric.createAlarmInfoControl(app.getRoutingHelper(), view.getContext(), view.getSettings()); // register right stack EnumSet all = EnumSet.allOf(ApplicationMode.class); - EnumSet carDefault = EnumSet.of(ApplicationMode.CAR, ApplicationMode.DEFAULT); EnumSet carBicycleDefault = EnumSet.of(ApplicationMode.CAR, ApplicationMode.DEFAULT, ApplicationMode.BICYCLE); EnumSet exceptCar = EnumSet.of(ApplicationMode.BICYCLE, ApplicationMode.PEDESTRIAN, ApplicationMode.DEFAULT); EnumSet none = EnumSet.noneOf(ApplicationMode.class); - RoutingHelper routingHelper = view.getApplication().getRoutingHelper(); - NextTurnInfoControl bigInfoControl = ric.createNextInfoControl(routingHelper, view.getApplication(), view.getSettings(), paintText, + RoutingHelper routingHelper = app.getRoutingHelper(); + NextTurnInfoControl bigInfoControl = ric.createNextInfoControl(routingHelper, app, view.getSettings(), paintText, paintSubText, false); mapInfoControls.registerSideWidget(bigInfoControl, R.drawable.widget_next_turn, R.string.map_widget_next_turn,"next_turn", true, carBicycleDefault, none, 5); - NextTurnInfoControl smallInfoControl = ric.createNextInfoControl(routingHelper, view.getApplication(), view.getSettings(), + NextTurnInfoControl smallInfoControl = ric.createNextInfoControl(routingHelper, app, view.getSettings(), paintSmallText, paintSmallSubText, true); mapInfoControls.registerSideWidget(smallInfoControl, R.drawable.widget_next_turn, R.string.map_widget_next_turn_small, "next_turn_small", true, EnumSet.of(ApplicationMode.PEDESTRIAN), none, 10); - NextTurnInfoControl nextNextInfoControl = ric.createNextNextInfoControl(routingHelper, view.getApplication(), view.getSettings(), + NextTurnInfoControl nextNextInfoControl = ric.createNextNextInfoControl(routingHelper, app, view.getSettings(), paintSmallText, paintSmallSubText, true); mapInfoControls.registerSideWidget(nextNextInfoControl, R.drawable.widget_next_turn, R.string.map_widget_next_next_turn, "next_next_turn",true, carBicycleDefault, none, 15); //MiniMapControl miniMap = ric.createMiniMapControl(routingHelper, view); @@ -213,6 +213,8 @@ public class MapInfoLayer extends OsmandMapLayer { mapInfoControls.registerSideWidget(time, R.drawable.widget_time, R.string.map_widget_time, "time",false, all, none, 10); TextInfoControl speed = ric.createSpeedControl(map, paintText, paintSubText); mapInfoControls.registerSideWidget(speed, R.drawable.widget_speed, R.string.map_widget_speed, "speed", false, all, none, 15); + TextInfoControl gpsInfo = ric.createGPSInfoControl(map, paintText, paintSubText); + mapInfoControls.registerSideWidget(gpsInfo, R.drawable.widget_gps_info, R.string.map_widget_gps_info, "gps_info", false, none, none, 17); TextInfoControl maxspeed = ric.createMaxSpeedControl(map, paintText, paintSubText); mapInfoControls.registerSideWidget(maxspeed, R.drawable.widget_max_speed, R.string.map_widget_max_speed, "max_speed", false, none, none, 18); TextInfoControl alt = ric.createAltitudeControl(map, paintText, paintSubText); @@ -314,7 +316,7 @@ public class MapInfoLayer extends OsmandMapLayer { @Override public void run() { view.getSettings().SHOW_VIEW_ANGLE.set(!view.getSettings().SHOW_VIEW_ANGLE.get()); - map.updateApplicationModeSettings(); + map.getMapViewTrackingUtilities().updateSettings(); } }); @@ -714,10 +716,6 @@ public class MapInfoLayer extends OsmandMapLayer { } - public ImageView getBackToLocation() { - return backToLocation; - } - public View getProgressBar() { return progressBar; } @@ -759,13 +757,22 @@ public class MapInfoLayer extends OsmandMapLayer { } private ImageView createBackToLocation(final MapActivity map){ - ImageView backToLocation = new ImageView(view.getContext()); + ImageView backToLocation = new ImageViewControl(view.getContext()) { + + @Override + public boolean updateInfo() { + boolean enabled = map.getMyApplication().getLocationProvider().getLastKnownLocation() != null; + enabled = enabled && !map.getMapViewTrackingUtilities().isMapLinkedToLocation(); + setEnabled(enabled); + return true; + } + }; backToLocation.setPadding((int) (5 * scaleCoefficient), 0, (int) (5 * scaleCoefficient), 0); backToLocation.setImageDrawable(map.getResources().getDrawable(R.drawable.back_to_loc)); backToLocation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - map.backToLocationImpl(); + map.getMapViewTrackingUtilities().backToLocationImpl(); } }); return backToLocation; @@ -820,7 +827,7 @@ public class MapInfoLayer extends OsmandMapLayer { public void onClick(View v) { if (!isScreenLocked) { parent.addView(transparentLockView); - map.backToLocationImpl(); + map.getMapViewTrackingUtilities().backToLocationImpl(); } else { parent.removeView(transparentLockView); } @@ -830,7 +837,7 @@ public class MapInfoLayer extends OsmandMapLayer { } else { lockView.setBackgroundDrawable(lockDisabled); } - map.backToLocationImpl(); + map.getMapViewTrackingUtilities().backToLocationImpl(); } }); return lockView; @@ -865,7 +872,7 @@ public class MapInfoLayer extends OsmandMapLayer { compassView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - map.switchRotateMapMode(); + map.getMapViewTrackingUtilities().switchRotateMapMode(); } }); compassView.setImageDrawable(compass); @@ -908,7 +915,7 @@ public class MapInfoLayer extends OsmandMapLayer { text = RoutingHelper.formatStreetName(next.getStreetName(), next.getRef()); } } - } else if(map.isMapLinkedToLocation()) { + } else if(map.getMapViewTrackingUtilities().isMapLinkedToLocation()) { RouteDataObject rt = map.getLastRouteDataObject(); if(rt != null) { text = RoutingHelper.formatStreetName(rt.getName(), rt.getRef()); diff --git a/OsmAnd/src/net/osmand/plus/views/PointLocationLayer.java b/OsmAnd/src/net/osmand/plus/views/PointLocationLayer.java index 7ec59c87ec..125f421e69 100644 --- a/OsmAnd/src/net/osmand/plus/views/PointLocationLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/PointLocationLayer.java @@ -4,6 +4,7 @@ package net.osmand.plus.views; import net.osmand.Location; import net.osmand.util.MapUtils; import net.osmand.plus.ApplicationMode; +import net.osmand.plus.OsmAndLocationProvider; import net.osmand.plus.R; import android.content.Context; import android.graphics.Bitmap; @@ -24,15 +25,13 @@ public class PointLocationLayer extends OsmandMapLayer { private Paint aroundArea; private Paint headingPaint; - protected Location lastKnownLocation = null; private DisplayMetrics dm; private OsmandMapTileView view; - private Float heading = null; - private ApplicationMode appMode; private Bitmap bearingIcon; private Bitmap locationIcon; + private OsmAndLocationProvider locationProvider; private void initUI() { locationPaint = new Paint(); @@ -40,6 +39,7 @@ public class PointLocationLayer extends OsmandMapLayer { locationPaint.setFilterBitmap(true); locationPaint.setDither(true); + area = new Paint(); area.setColor(view.getResources().getColor(R.color.pos_area)); @@ -55,6 +55,7 @@ public class PointLocationLayer extends OsmandMapLayer { headingPaint.setStyle(Style.FILL); checkAppMode(view.getSettings().getApplicationMode()); + locationProvider = view.getApplication().getLocationProvider(); } @@ -76,7 +77,8 @@ public class PointLocationLayer extends OsmandMapLayer { @Override public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) { - // draw + // draw + Location lastKnownLocation = locationProvider.getLastKnownLocation(); if(lastKnownLocation == null || view == null){ return; } @@ -101,7 +103,7 @@ public class PointLocationLayer extends OsmandMapLayer { canvas.drawBitmap(locationIcon, locationX - locationIcon.getWidth() / 2, locationY - locationIcon.getHeight() / 2, locationPaint); } - + Float heading = locationProvider.getHeading(); if (heading != null && view.getSettings().SHOW_VIEW_ANGLE.get()) { canvas.drawArc(getHeadingRect(locationX, locationY), heading - HEADING_ANGLE / 2 - 90, HEADING_ANGLE, true, headingPaint); } @@ -123,29 +125,6 @@ public class PointLocationLayer extends OsmandMapLayer { return view.isPointOnTheRotatedMap(l.getLatitude(), l.getLongitude()); } - - public Location getLastKnownLocation() { - return lastKnownLocation; - } - - public void setHeading(Float heading){ - this.heading = heading; - if(!view.mapIsRefreshing() && isLocationVisible(this.lastKnownLocation)){ - view.refreshMap(); - } - } - - public Float getHeading() { - return heading; - } - - public void setLastKnownLocation(Location lastKnownLocation) { - boolean redraw = isLocationVisible(this.lastKnownLocation) || isLocationVisible(lastKnownLocation); - this.lastKnownLocation = lastKnownLocation; - if (redraw) { - view.refreshMap(); - } - } @Override public void destroyLayer() { diff --git a/OsmAnd/src/net/osmand/plus/views/PointNavigationLayer.java b/OsmAnd/src/net/osmand/plus/views/PointNavigationLayer.java index 0f71ea7861..7ee7e06a96 100644 --- a/OsmAnd/src/net/osmand/plus/views/PointNavigationLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/PointNavigationLayer.java @@ -92,7 +92,7 @@ public class PointNavigationLayer extends OsmandMapLayer implements IContextMenu public void onDraw(Canvas canvas, RectF latLonBounds, RectF tilesRect, DrawSettings nightMode) { int index = 0; - TargetPointsHelper targetPoints = map.getTargetPoints(); + TargetPointsHelper targetPoints = map.getMyApplication().getTargetPointsHelper(); for (LatLon ip : targetPoints.getIntermediatePoints()) { index ++; if (isLocationVisible(ip)) { @@ -157,7 +157,8 @@ public class PointNavigationLayer extends OsmandMapLayer implements IContextMenu @Override public void collectObjectsFromPoint(PointF point, List o) { - List intermediatePoints = map.getTargetPoints().getIntermediatePointsWithTarget(); + TargetPointsHelper tg = map.getMyApplication().getTargetPointsHelper(); + List intermediatePoints = tg.getIntermediatePointsWithTarget(); for (int i = 0; i < intermediatePoints.size(); i++) { LatLon latLon = intermediatePoints.get(i); boolean target = i == intermediatePoints.size() - 1; @@ -233,9 +234,9 @@ public class PointNavigationLayer extends OsmandMapLayer implements IContextMenu if (itemId == R.string.delete_target_point) { TargetPointsHelper targetPointsHelper = map.getMyApplication().getTargetPointsHelper(); if(a.intermediate) { - targetPointsHelper.removeWayPoint(map, true, a.index); + targetPointsHelper.removeWayPoint(true, a.index); } else { - targetPointsHelper.removeWayPoint(map, true, -1); + targetPointsHelper.removeWayPoint(true, -1); } } map.getMapLayers().getContextMenuLayer().setLocation(null, ""); diff --git a/OsmAnd/src/net/osmand/plus/views/RouteInfoControls.java b/OsmAnd/src/net/osmand/plus/views/RouteInfoControls.java index 3d6753d3da..a04b23770d 100644 --- a/OsmAnd/src/net/osmand/plus/views/RouteInfoControls.java +++ b/OsmAnd/src/net/osmand/plus/views/RouteInfoControls.java @@ -3,17 +3,19 @@ package net.osmand.plus.views; import java.util.Arrays; -import net.osmand.GeoidAltitudeCorrection; import net.osmand.Location; import net.osmand.binary.RouteDataObject; import net.osmand.data.LatLon; import net.osmand.plus.OsmAndFormatter; +import net.osmand.plus.OsmAndLocationProvider; +import net.osmand.plus.OsmAndLocationProvider.GPSInfo; import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings.OsmandPreference; import net.osmand.plus.R; import net.osmand.plus.TargetPointsHelper; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.base.MapViewTrackingUtilities; import net.osmand.plus.routing.AlarmInfo; import net.osmand.plus.routing.RouteCalculationResult.NextDirectionInfo; import net.osmand.plus.routing.RouteDirectionInfo; @@ -281,7 +283,7 @@ public class RouteInfoControls { @Override public boolean updateInfo() { // draw speed - Location loc = map.getLastKnownLocation(); + Location loc = map.getMyApplication().getLastKnownLocation(); if (loc != null && loc.hasAltitude()) { double compAlt = loc.getAltitude(); if (cachedAlt != (int) compAlt) { @@ -309,14 +311,15 @@ public class RouteInfoControls { } protected TextInfoControl createMaxSpeedControl(final MapActivity map, Paint paintText, Paint paintSubText) { - final RoutingHelper rh = map.getRoutingHelper(); + final RoutingHelper rh = map.getMyApplication().getRoutingHelper(); + final MapViewTrackingUtilities trackingUtilities = map.getMapViewTrackingUtilities(); final TextInfoControl speedControl = new TextInfoControl(map, 3, paintText, paintSubText) { private float cachedSpeed = 0; @Override public boolean updateInfo() { float mx = 0; - if ((rh == null || !rh.isFollowingMode()) && map.isMapLinkedToLocation()) { + if ((rh == null || !rh.isFollowingMode()) && trackingUtilities.isMapLinkedToLocation()) { RouteDataObject ro = map.getLastRouteDataObject(); if(ro != null) { mx = ro.getMaximumSpeed(); @@ -349,14 +352,41 @@ public class RouteInfoControls { return speedControl; } + + protected TextInfoControl createGPSInfoControl(final MapActivity map, Paint paintText, Paint paintSubText) { + final OsmandApplication app = map.getMyApplication(); + final OsmAndLocationProvider loc = app.getLocationProvider(); + final TextInfoControl gpsInfoControl = new TextInfoControl(map, 3, paintText, paintSubText) { + private int u = -1; + private int f = -1; + + @Override + public boolean updateInfo() { + GPSInfo gpsInfo = loc.getGPSInfo(); + if(gpsInfo.usedSatellites != u || gpsInfo.foundSatellites != f) { + u = gpsInfo.usedSatellites; + f = gpsInfo.foundSatellites; + setText(gpsInfo.usedSatellites+"/"+gpsInfo.foundSatellites, ""); + return true; + } + return false; + } + }; + gpsInfoControl.setImageDrawable(app.getResources().getDrawable(R.drawable.info_gps_info)); + gpsInfoControl.setText(null, null); + return gpsInfoControl; + } + protected TextInfoControl createSpeedControl(final MapActivity map, Paint paintText, Paint paintSubText) { + final OsmandApplication app = map.getMyApplication(); final TextInfoControl speedControl = new TextInfoControl(map, 3, paintText, paintSubText) { private float cachedSpeed = 0; @Override public boolean updateInfo() { + Location loc = app.getLastKnownLocation(); // draw speed - if (map.getLastKnownLocation() != null && map.getLastKnownLocation().hasSpeed()) { + if (loc != null && loc.hasSpeed()) { // .1 mps == 0.36 kph float minDelta = .1f; // Update more often at walk/run speeds, since we give higher resolution @@ -364,9 +394,9 @@ public class RouteInfoControls { if (cachedSpeed < 6) { minDelta = .015f; } - if (Math.abs(map.getLastKnownLocation().getSpeed() - cachedSpeed) > minDelta) { - cachedSpeed = map.getLastKnownLocation().getSpeed(); - String ds = OsmAndFormatter.getFormattedSpeed(cachedSpeed, map.getMyApplication()); + if (Math.abs(loc.getSpeed() - cachedSpeed) > minDelta) { + cachedSpeed = loc.getSpeed(); + String ds = OsmAndFormatter.getFormattedSpeed(cachedSpeed, app); int ls = ds.lastIndexOf(' '); if (ls == -1) { setText(ds, null); @@ -383,7 +413,7 @@ public class RouteInfoControls { return false; } }; - speedControl.setImageDrawable(map.getResources().getDrawable(R.drawable.info_speed)); + speedControl.setImageDrawable(app.getResources().getDrawable(R.drawable.info_speed)); speedControl.setText(null, null); return speedControl; } @@ -475,7 +505,7 @@ public class RouteInfoControls { protected TextInfoControl createIntermediateDistanceControl(final MapActivity map, Paint paintText, Paint paintSubText) { final OsmandMapTileView view = map.getMapView(); - final TargetPointsHelper targets = map.getTargetPoints(); + final TargetPointsHelper targets = map.getMyApplication().getTargetPointsHelper(); DistanceToPointInfoControl distanceControl = new DistanceToPointInfoControl(map, 0, paintText, paintSubText, map.getResources() .getDrawable(R.drawable.info_intermediate), view) {