From f7a60a238e50fc0658b4fd2c00c97d765c05cced Mon Sep 17 00:00:00 2001 From: Alex Zolotarev Date: Thu, 2 Feb 2012 18:59:36 +0300 Subject: [PATCH] [android] Closes #502 - compass is not working - Renamed compass variables - Additional checks for devices without orientation sensor --- .../maps/location/LocationService.java | 43 ++++++++++++++++--- map/location_state.cpp | 13 +++--- map/location_state.hpp | 3 +- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/android/src/com/mapswithme/maps/location/LocationService.java b/android/src/com/mapswithme/maps/location/LocationService.java index a8f0437d7c..515acd2e0e 100644 --- a/android/src/com/mapswithme/maps/location/LocationService.java +++ b/android/src/com/mapswithme/maps/location/LocationService.java @@ -43,7 +43,7 @@ public class LocationService implements LocationListener, SensorEventListener, W private LocationManager m_locationManager; private SensorManager m_sensorManager; - private Sensor m_compassSensor; + private Sensor m_compassSensor = null; // To calculate true north for compass private GeomagneticField m_magneticField = null; private boolean m_isActive = false; @@ -81,6 +81,28 @@ public class LocationService implements LocationListener, SensorEventListener, W it.next().onCompassUpdated(time, magneticNorth, trueNorth, accuracy); } + private WakeLock m_wakeLock = null; + + private void disableAutomaticStandby() + { + if (m_wakeLock == null) + { + PowerManager pm = (PowerManager) MWMActivity.getCurrentContext().getSystemService( + android.content.Context.POWER_SERVICE); + m_wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, TAG); + } + m_wakeLock.acquire(); + } + + private void enableAutomaticStandby() + { + if (m_wakeLock != null) + m_wakeLock.release(); + } + + // How often compass is updated + private final static int COMPASS_REFRESH_MKS = 333 * 1000; + public void startUpdate(Listener observer, Context c) { m_observers.add(observer); @@ -127,8 +149,8 @@ public class LocationService implements LocationListener, SensorEventListener, W onLocationChanged(lastKnown); } } - if (m_sensorManager != null) - m_sensorManager.registerListener(this, m_compassSensor, SensorManager.SENSOR_DELAY_NORMAL); + if (m_sensorManager != null && m_compassSensor != null) + m_sensorManager.registerListener(this, m_compassSensor, COMPASS_REFRESH_MKS); } } else @@ -142,7 +164,7 @@ public class LocationService implements LocationListener, SensorEventListener, W if (m_observers.size() == 0) { m_locationManager.removeUpdates(this); - if (m_sensorManager != null) + if (m_sensorManager != null && m_compassSensor != null) m_sensorManager.unregisterListener(this); m_isActive = false; m_reportFirstUpdate = true; @@ -234,7 +256,7 @@ public class LocationService implements LocationListener, SensorEventListener, W if (m_sensorManager != null) { // Recreate magneticField if location has changed significantly - if (m_lastLocation == null || l.distanceTo(m_lastLocation) > HUNDRED_METRES) + if (m_magneticField == null || m_lastLocation == null || l.distanceTo(m_lastLocation) > HUNDRED_METRES) m_magneticField = new GeomagneticField((float)l.getLatitude(), (float)l.getLongitude(), (float)l.getAltitude(), l.getTime()); } notifyLocationUpdated(l.getTime(), l.getLatitude(), l.getLongitude(), l.getAccuracy()); @@ -242,13 +264,20 @@ public class LocationService implements LocationListener, SensorEventListener, W } } + // Used when only magnetic north is available + private final static double INVALID_TRUE_NORTH = -1.0; + private final static float UNKNOWN_COMPASS_ACCURACY = 10.0f; + //@Override public void onSensorChanged(SensorEvent event) { if (m_magneticField == null) - notifyCompassUpdated(event.timestamp, event.values[0], 0.0, 1.0f); + notifyCompassUpdated(event.timestamp, event.values[0], INVALID_TRUE_NORTH, UNKNOWN_COMPASS_ACCURACY); else - notifyCompassUpdated(event.timestamp, event.values[0], event.values[0] + m_magneticField.getDeclination(), m_magneticField.getDeclination()); + { + final float offset = m_magneticField.getDeclination(); + notifyCompassUpdated(event.timestamp, event.values[0], event.values[0] + offset, offset); + } } //@Override diff --git a/map/location_state.cpp b/map/location_state.cpp index 19ef69db8d..7417883907 100644 --- a/map/location_state.cpp +++ b/map/location_state.cpp @@ -31,7 +31,10 @@ namespace location m_headingRad = ((info.m_trueHeading >= 0.0) ? info.m_trueHeading : info.m_magneticHeading) / 180 * math::pi - math::pi / 2; // 0 angle is for North ("up"), but in our coordinates it's to the right. - m_headingAccuracyRad = info.m_accuracy / 180 * math::pi; + // Avoid situations when offset between magnetic north and true north is too small + static double const MIN_SECTOR_DEG = 10.; + m_headingHalfSectorRad = (info.m_accuracy < MIN_SECTOR_DEG ? MIN_SECTOR_DEG : info.m_accuracy) + / 180 * math::pi; } void State::DrawMyPosition(DrawerYG & drawer, ScreenBase const & screen) @@ -62,14 +65,14 @@ namespace location if (m_flags & State::ECompass) { drawer.screen()->drawSector(pxPosition, - m_headingRad - m_headingAccuracyRad, - m_headingRad + m_headingAccuracyRad, + m_headingRad - m_headingHalfSectorRad, + m_headingRad + m_headingHalfSectorRad, orientationRadius, yg::Color(255, 255, 255, 192), yg::maxDepth); drawer.screen()->fillSector(pxPosition, - m_headingRad - m_headingAccuracyRad, - m_headingRad + m_headingAccuracyRad, + m_headingRad - m_headingHalfSectorRad, + m_headingRad + m_headingHalfSectorRad, orientationRadius, yg::Color(255, 255, 255, 96), yg::maxDepth - 1); diff --git a/map/location_state.hpp b/map/location_state.hpp index c1e1a30b70..c79d70dc92 100644 --- a/map/location_state.hpp +++ b/map/location_state.hpp @@ -16,7 +16,8 @@ namespace location m2::PointD m_positionMercator; double m_headingRad; - double m_headingAccuracyRad; + /// Angle to the left and to the right from the North + double m_headingHalfSectorRad; int m_flags; ///< stores flags from SymbolType