diff --git a/android/jni/com/mapswithme/location/LocationService.cpp b/android/jni/com/mapswithme/location/LocationService.cpp index ec5a9d7534..1da2ff8cf6 100644 --- a/android/jni/com/mapswithme/location/LocationService.cpp +++ b/android/jni/com/mapswithme/location/LocationService.cpp @@ -14,26 +14,32 @@ android::LocationService * g_locationService = 0; namespace android { - LocationService::LocationService(location::LocationObserver & locationObserver, - jobject observer) - : location::LocationService(locationObserver), - m_javaObserver(observer) + LocationService::LocationService(location::LocationObserver & observer, + jobject javaObserver) + : m_observer(observer), + m_javaObserver(javaObserver) { jclass k = jni::GetCurrentThreadJNIEnv()->GetObjectClass(m_javaObserver); m_onLocationChanged.reset(new jni::Method(k, "onLocationChanged", "(JDDF)V")); - m_onStatusChanged.reset(new jni::Method(k, "onStatusChanged", "(J)V")); + m_onStatusChanged.reset(new jni::Method(k, "onStatusChanged", "(I)V")); } - void LocationService::Start() + void LocationService::Start(bool doChangeStatus) { - m_observer.OnLocationStatusChanged(location::EStarted); - m_onStatusChanged->CallVoid(m_javaObserver, location::EStarted); + if (doChangeStatus) + { + m_observer.OnLocationStatusChanged(location::EStarted); + m_onStatusChanged->CallVoid(m_javaObserver, location::EStarted); + } } - void LocationService::Stop() + void LocationService::Stop(bool doChangeStatus) { - m_observer.OnLocationStatusChanged(location::EStopped); - m_onStatusChanged->CallVoid(m_javaObserver, location::EStopped); + if (doChangeStatus) + { + m_observer.OnLocationStatusChanged(location::EStopped); + m_onStatusChanged->CallVoid(m_javaObserver, location::EStopped); + } } void LocationService::Disable() @@ -47,6 +53,12 @@ namespace android m_observer.OnGpsUpdated(info); m_onLocationChanged->CallVoid(m_javaObserver, info.m_timestamp, info.m_latitude, info.m_longitude, info.m_horizontalAccuracy); } + + void LocationService::OnLocationStatusChanged(int status) + { + m_observer.OnLocationStatusChanged((location::TLocationStatus)status); + m_onStatusChanged->CallVoid(m_javaObserver, status); + } } /////////////////////////////////////////////////////////////////////////////////// @@ -57,19 +69,25 @@ namespace android extern "C" { JNIEXPORT void JNICALL - Java_com_mapswithme_maps_location_LocationService_nativeStartUpdate(JNIEnv * env, jobject thiz, jobject observer) + Java_com_mapswithme_maps_location_LocationService_nativeStartUpdate(JNIEnv * env, jobject thiz, jobject observer, jboolean changeStatus) { g_locationService = new android::LocationService(*g_framework, observer); - g_locationService->Start(); + g_locationService->Start(changeStatus); } JNIEXPORT void JNICALL - Java_com_mapswithme_maps_location_LocationService_nativeStopUpdate(JNIEnv * env, jobject thiz) + Java_com_mapswithme_maps_location_LocationService_nativeStopUpdate(JNIEnv * env, jobject thiz, jboolean changeStatus) { - g_locationService->Stop(); + g_locationService->Stop(changeStatus); delete g_locationService; } + JNIEXPORT void JNICALL + Java_com_mapswithme_maps_location_LocationService_nativeLocationStatusChanged(JNIEnv * env, jobject thiz, int status) + { + g_locationService->OnLocationStatusChanged(status); + } + JNIEXPORT void JNICALL Java_com_mapswithme_maps_location_LocationService_nativeLocationChanged(JNIEnv * env, jobject thiz, jlong time, jdouble lat, jdouble lon, jfloat accuracy) diff --git a/android/jni/com/mapswithme/location/LocationService.hpp b/android/jni/com/mapswithme/location/LocationService.hpp index 040cb70687..653594fd7d 100644 --- a/android/jni/com/mapswithme/location/LocationService.hpp +++ b/android/jni/com/mapswithme/location/LocationService.hpp @@ -8,11 +8,12 @@ namespace android { - class LocationService : public location::LocationService + class LocationService { private: jobject m_javaObserver; + location::LocationObserver & m_observer; scoped_ptr m_onLocationChanged; scoped_ptr m_onStatusChanged; @@ -22,10 +23,11 @@ namespace android LocationService(location::LocationObserver & locationObserver, jobject observer); - void Start(); - void Stop(); + void Start(bool doChangeStatus); + void Stop(bool doChangeStatus); void Disable(); void OnLocationUpdate(location::GpsInfo const & info); + void OnLocationStatusChanged(int status); }; } diff --git a/android/res/drawable-hdpi/download_maps.png b/android/res/drawable-hdpi/download_maps.png deleted file mode 100644 index 8074c4c571..0000000000 Binary files a/android/res/drawable-hdpi/download_maps.png and /dev/null differ diff --git a/android/res/drawable-hdpi/ic_menu_download.png b/android/res/drawable-hdpi/ic_menu_download.png new file mode 100644 index 0000000000..5a4d708f20 Binary files /dev/null and b/android/res/drawable-hdpi/ic_menu_download.png differ diff --git a/android/res/drawable-hdpi/ic_menu_location.png b/android/res/drawable-hdpi/ic_menu_location.png new file mode 100644 index 0000000000..6ff8c131af Binary files /dev/null and b/android/res/drawable-hdpi/ic_menu_location.png differ diff --git a/android/res/drawable-hdpi/ic_menu_location_found.png b/android/res/drawable-hdpi/ic_menu_location_found.png new file mode 100644 index 0000000000..5fd6616bcb Binary files /dev/null and b/android/res/drawable-hdpi/ic_menu_location_found.png differ diff --git a/android/res/drawable-hdpi/ic_menu_location_search.png b/android/res/drawable-hdpi/ic_menu_location_search.png new file mode 100644 index 0000000000..c3a474aa31 Binary files /dev/null and b/android/res/drawable-hdpi/ic_menu_location_search.png differ diff --git a/android/res/drawable-hdpi/ic_menu_search.png b/android/res/drawable-hdpi/ic_menu_search.png new file mode 100644 index 0000000000..cf503b86d7 Binary files /dev/null and b/android/res/drawable-hdpi/ic_menu_search.png differ diff --git a/android/res/drawable-hdpi/my_position.png b/android/res/drawable-hdpi/my_position.png deleted file mode 100644 index 8074c4c571..0000000000 Binary files a/android/res/drawable-hdpi/my_position.png and /dev/null differ diff --git a/android/res/drawable-ldpi/download_maps.png b/android/res/drawable-ldpi/download_maps.png deleted file mode 100644 index 1095584ec2..0000000000 Binary files a/android/res/drawable-ldpi/download_maps.png and /dev/null differ diff --git a/android/res/drawable-ldpi/ic_menu_download.png b/android/res/drawable-ldpi/ic_menu_download.png new file mode 100644 index 0000000000..8c2face52b Binary files /dev/null and b/android/res/drawable-ldpi/ic_menu_download.png differ diff --git a/android/res/drawable-ldpi/ic_menu_location.png b/android/res/drawable-ldpi/ic_menu_location.png new file mode 100644 index 0000000000..21e77b9420 Binary files /dev/null and b/android/res/drawable-ldpi/ic_menu_location.png differ diff --git a/android/res/drawable-ldpi/ic_menu_location_found.png b/android/res/drawable-ldpi/ic_menu_location_found.png new file mode 100644 index 0000000000..085d0eb626 Binary files /dev/null and b/android/res/drawable-ldpi/ic_menu_location_found.png differ diff --git a/android/res/drawable-ldpi/ic_menu_location_search.png b/android/res/drawable-ldpi/ic_menu_location_search.png new file mode 100644 index 0000000000..18a62c2cbd Binary files /dev/null and b/android/res/drawable-ldpi/ic_menu_location_search.png differ diff --git a/android/res/drawable-ldpi/ic_menu_search.png b/android/res/drawable-ldpi/ic_menu_search.png new file mode 100644 index 0000000000..817cc94604 Binary files /dev/null and b/android/res/drawable-ldpi/ic_menu_search.png differ diff --git a/android/res/drawable-ldpi/my_position.png b/android/res/drawable-ldpi/my_position.png deleted file mode 100644 index 1095584ec2..0000000000 Binary files a/android/res/drawable-ldpi/my_position.png and /dev/null differ diff --git a/android/res/drawable-mdpi/download_maps.png b/android/res/drawable-mdpi/download_maps.png deleted file mode 100644 index a07c69fa5a..0000000000 Binary files a/android/res/drawable-mdpi/download_maps.png and /dev/null differ diff --git a/android/res/drawable-mdpi/ic_menu_download.png b/android/res/drawable-mdpi/ic_menu_download.png new file mode 100644 index 0000000000..d9204c4f88 Binary files /dev/null and b/android/res/drawable-mdpi/ic_menu_download.png differ diff --git a/android/res/drawable-mdpi/ic_menu_location.png b/android/res/drawable-mdpi/ic_menu_location.png new file mode 100644 index 0000000000..541d57dd07 Binary files /dev/null and b/android/res/drawable-mdpi/ic_menu_location.png differ diff --git a/android/res/drawable-mdpi/ic_menu_location_found.png b/android/res/drawable-mdpi/ic_menu_location_found.png new file mode 100644 index 0000000000..5cf57f5cd1 Binary files /dev/null and b/android/res/drawable-mdpi/ic_menu_location_found.png differ diff --git a/android/res/drawable-mdpi/ic_menu_location_search.png b/android/res/drawable-mdpi/ic_menu_location_search.png new file mode 100644 index 0000000000..0b2e799fe0 Binary files /dev/null and b/android/res/drawable-mdpi/ic_menu_location_search.png differ diff --git a/android/res/drawable-mdpi/ic_menu_search.png b/android/res/drawable-mdpi/ic_menu_search.png new file mode 100644 index 0000000000..8256f79775 Binary files /dev/null and b/android/res/drawable-mdpi/ic_menu_search.png differ diff --git a/android/res/drawable-mdpi/my_position.png b/android/res/drawable-mdpi/my_position.png deleted file mode 100644 index a07c69fa5a..0000000000 Binary files a/android/res/drawable-mdpi/my_position.png and /dev/null differ diff --git a/android/res/menu/main.xml b/android/res/menu/main.xml index 845ab94ca8..e6ba3e33de 100644 --- a/android/res/menu/main.xml +++ b/android/res/menu/main.xml @@ -1,10 +1,10 @@ diff --git a/android/src/com/mapswithme/maps/MWMActivity.java b/android/src/com/mapswithme/maps/MWMActivity.java index 8416409c41..7d355bec1a 100644 --- a/android/src/com/mapswithme/maps/MWMActivity.java +++ b/android/src/com/mapswithme/maps/MWMActivity.java @@ -20,10 +20,14 @@ import android.util.Log; public class MWMActivity extends NvEventQueueActivity implements LocationService.Observer { VideoTimer m_timer; + private static String TAG = "MWMActivity"; private final static String PACKAGE_NAME = "com.mapswithme.maps"; - private boolean m_locationEnabled = false; + private int m_locationStatus; + private int m_locationIconRes; + private boolean m_isLocationServicePaused = false; + private LocationService m_locationService = null; private String getAppBundlePath() throws NameNotFoundException @@ -43,7 +47,7 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - + final String storagePath = getDataStoragePath(); // create folder if it doesn't exist File f = new File(storagePath); @@ -59,36 +63,68 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService } m_timer = new VideoTimer(); + m_locationStatus = (int)LocationService.STOPPED; + m_locationIconRes = R.drawable.ic_menu_location; m_locationService = new LocationService(this); + m_isLocationServicePaused = false; } - public void onStatusChanged(long status) + public void onStatusChanged(int status) { - Log.d(TAG, "onStatusChanged"); + m_locationStatus = status; + + switch (status) + { + case LocationService.FIRST_EVENT: + m_locationIconRes = R.drawable.ic_menu_location_found; + break; + case LocationService.STOPPED: + m_locationIconRes = R.drawable.ic_menu_location; + break; + case LocationService.DISABLED_BY_USER: + m_locationIconRes = R.drawable.ic_menu_location; + break; + case LocationService.STARTED: + m_locationIconRes = R.drawable.ic_menu_location_search; + break; + default: + m_locationIconRes = R.drawable.ic_menu_location; + } + + Log.d(TAG, "StatusChanged: " + status); } public void onLocationChanged(long time, double latitude, double longitude, float accuracy) { - Log.d(TAG, "onLocationChanged"); + } + + public void onLocationNotAvailable() + { + Log.d(TAG, "location services is disabled or not available"); } -/* @Override + @Override protected void onPause() { + if (m_locationService.isActive()) + { + m_locationService.enterBackground(); + m_isLocationServicePaused = true; + } + super.onPause(); - m_view.onPause(); - if (m_locationEnabled) - LocationService.stop(); } @Override protected void onResume() { - super.onResume(); - m_view.onResume(); - if (m_locationEnabled) - LocationService.start(this); - }*/ + if (m_isLocationServicePaused) + { + m_locationService.enterForeground(); + m_isLocationServicePaused = false; + } + super.onResume(); + } @Override public boolean onCreateOptionsMenu(Menu menu) @@ -99,19 +135,28 @@ public class MWMActivity extends NvEventQueueActivity implements LocationService //menu.removeItem(R.id.download_maps); return true; } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) + { + menu.findItem(R.id.my_position).setIcon(m_locationIconRes); + return super.onPrepareOptionsMenu(menu); + } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle item selection + switch (item.getItemId()) { case R.id.my_position: + if (m_locationService.isActive()) - m_locationService.stopUpdate(); + m_locationService.stopUpdate(true); else - m_locationService.startUpdate(this); - m_locationEnabled = !m_locationEnabled; + m_locationService.startUpdate(this, true); + return true; case R.id.download_maps: Intent intent = new Intent(this, DownloadUI.class); diff --git a/android/src/com/mapswithme/maps/location/LocationService.java b/android/src/com/mapswithme/maps/location/LocationService.java index 9c7652295b..f96e25d1cb 100644 --- a/android/src/com/mapswithme/maps/location/LocationService.java +++ b/android/src/com/mapswithme/maps/location/LocationService.java @@ -16,20 +16,36 @@ import android.view.WindowManager; public class LocationService implements LocationListener, SensorEventListener { + private static String TAG = "Location"; + + /// This constants should correspond to values defined in platform/location.hpp + /// @{ + public static final int STOPPED = 0; + public static final int STARTED = 1; + public static final int FIRST_EVENT = 2; + public static final int NOT_SUPPORTED = 3; + public static final int DISABLED_BY_USER = 4; + /// @} public interface Observer { public void onLocationChanged(long time, double lat, double lon, float accuracy); - public void onStatusChanged(long status); + public void onStatusChanged(int status); + public void onLocationNotAvailable(); }; + Observer m_observer; + private boolean m_isActive = false; - private static String TAG = "Location"; + private Location m_location = null; + private LocationManager m_locationManager; private SensorManager m_sensorManager; private Sensor m_compassSensor; // To calculate true north for compass private GeomagneticField m_field; + private boolean m_hasRealProviders; + private boolean m_reportFirstUpdate; public LocationService(Context c) { @@ -45,54 +61,110 @@ public class LocationService implements LocationListener, SensorEventListener return m_isActive; } - public void startUpdate(Observer observer) + public void startUpdate(Observer observer, boolean doChangeState) { + m_observer = observer; m_isActive = false; + m_hasRealProviders = false; + m_reportFirstUpdate = true; - /*if (m_locationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER)) - { - m_locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, this); - m_isActive = true; - }*/ - if (m_locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { m_locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); + m_hasRealProviders = true; m_isActive = true; } if (m_locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { m_locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); + m_hasRealProviders = true; m_isActive = true; } + + if (m_hasRealProviders) + { + if (m_locationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER)) + m_locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, this); + } if (m_isActive) { m_sensorManager.registerListener(this, m_compassSensor, SensorManager.SENSOR_DELAY_NORMAL); - nativeStartUpdate(observer); + nativeStartUpdate(m_observer, doChangeState); } else { Log.d(TAG, "no locationProviders are found"); + m_observer.onLocationNotAvailable(); // TODO : callback into gui to show the "providers are not enabled" messagebox } } - public void stopUpdate() + public void stopUpdate(boolean doChangeState) { m_locationManager.removeUpdates(this); m_sensorManager.unregisterListener(this); m_isActive = false; - nativeStopUpdate(); + nativeStopUpdate(doChangeState); + } + + public void enterBackground() + { + stopUpdate(false); + + /// requesting location updates from the low-power location provider + if (m_locationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER)) + { + m_locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, this); + nativeStartUpdate(m_observer, false); + } + } + + public void enterForeground() + { + nativeStopUpdate(false); + + m_isActive = false; + m_hasRealProviders = false; + + if (m_locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) + { + m_locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); + m_hasRealProviders = true; + m_isActive = true; + } + + if (m_locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) + { + m_locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); + m_hasRealProviders = true; + m_isActive = true; + } + + nativeStartUpdate(m_observer, false); + + m_sensorManager.registerListener(this, m_compassSensor, SensorManager.SENSOR_DELAY_NORMAL); + + if (m_location != null) + nativeLocationChanged(m_location.getTime(), + m_location.getLatitude(), + m_location.getLongitude(), + m_location.getAccuracy()); } //@Override public void onLocationChanged(Location l) { + if (m_reportFirstUpdate) + { + nativeLocationStatusChanged(FIRST_EVENT); + m_reportFirstUpdate = false; + } // used for compass updates if (m_field == null) m_field = new GeomagneticField((float)l.getLatitude(), (float)l.getLongitude(), (float)l.getAltitude(), l.getTime()); + m_location = l; nativeLocationChanged(l.getTime(), l.getLatitude(), l.getLongitude(), l.getAccuracy()); Log.d(TAG, l.toString()); } @@ -109,8 +181,7 @@ public class LocationService implements LocationListener, SensorEventListener { Log.d(TAG, "to receive a location data please enable some of the location providers"); nativeDisable(); - stopUpdate(); - /// TODO : callback into GUI to set the button into the "disabled" state + stopUpdate(true); } } } @@ -120,7 +191,7 @@ public class LocationService implements LocationListener, SensorEventListener { Log.d(TAG, "onProviderEnabled " + provider); if (m_isActive) - m_locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); + m_locationManager.requestLocationUpdates(provider, 0, 0, this); } //@Override @@ -145,9 +216,10 @@ public class LocationService implements LocationListener, SensorEventListener nativeCompassChanged(event.timestamp, event.values[0], event.values[0] + m_field.getDeclination(), m_field.getDeclination()); } - private native void nativeStartUpdate(Observer observer); - private native void nativeStopUpdate(); + private native void nativeStartUpdate(Observer observer, boolean changeState); + private native void nativeStopUpdate(boolean changeState); private native void nativeDisable(); private native void nativeLocationChanged(long time, double lat, double lon, float accuracy); + private native void nativeLocationStatusChanged(int status); private native void nativeCompassChanged(long time, double magneticNorth, double trueNorth, float accuracy); }