Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvng <viktor.govako@gmail.com>2013-09-18 19:51:37 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:02:09 +0300
commitdb29320ae8bc371b50d923bed6b1286dfba5d0a7 (patch)
tree22032c77744c01d9a69af8a0dd3d2cc26e3a66a3
parent40c4e677ef0c7154edee3a005c61cf0b6fee4cf9 (diff)
[android] Use Location.getElapsedRealtimeNanos() for API level >= 17.
-rw-r--r--android/src/com/mapswithme/maps/location/LocationService.java66
-rw-r--r--android/src/com/mapswithme/maps/location/WifiLocation.java17
-rw-r--r--android/src/com/mapswithme/util/LocationUtils.java110
-rw-r--r--android/src/com/mapswithme/util/log/SimpleLogger.java6
4 files changed, 121 insertions, 78 deletions
diff --git a/android/src/com/mapswithme/maps/location/LocationService.java b/android/src/com/mapswithme/maps/location/LocationService.java
index 75500d5793..d615d11b69 100644
--- a/android/src/com/mapswithme/maps/location/LocationService.java
+++ b/android/src/com/mapswithme/maps/location/LocationService.java
@@ -16,7 +16,6 @@ import android.location.LocationListener;
import android.location.LocationManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
-import android.util.Log;
import android.view.Display;
import android.view.Surface;
@@ -24,14 +23,12 @@ import com.mapswithme.maps.MWMApplication;
import com.mapswithme.util.ConnectionState;
import com.mapswithme.util.LocationUtils;
import com.mapswithme.util.log.Logger;
-import com.mapswithme.util.log.StubLogger;
+import com.mapswithme.util.log.SimpleLogger;
public class LocationService implements LocationListener, SensorEventListener, WifiLocation.Listener
{
- private static final String TAG = "LocationService";
-
- private Logger mLogger = StubLogger.get();//SimpleLogger.get(this.toString());
+ private Logger mLogger = SimpleLogger.get(this.toString());
/// These constants should correspond to values defined in platform/location.hpp
/// Leave 0-value as no any error.
@@ -69,7 +66,6 @@ public class LocationService implements LocationListener, SensorEventListener, W
public LocationService(MWMApplication application)
{
- mLogger.d("Creating locserivice");
mApplication = application;
mLocationManager = (LocationManager) mApplication.getSystemService(Context.LOCATION_SERVICE);
@@ -121,7 +117,7 @@ public class LocationService implements LocationListener, SensorEventListener, W
public void startUpdate(Listener observer)
{
- mLogger.d("Start update", observer);
+ mLogger.d("Start update for listener: ", observer);
mObservers.add(observer);
@@ -130,11 +126,11 @@ public class LocationService implements LocationListener, SensorEventListener, W
mIsGPSOff = false;
List<String> providers = getFilteredProviders();
- Log.d(TAG, "Enabled providers count = " + providers.size());
+ mLogger.d("Enabled providers count = ", providers.size());
startWifiLocationUpdate();
- if ((providers.size() == 0) && (mWifiScanner == null))
+ if (providers.size() == 0 && mWifiScanner == null)
observer.onLocationError(ERROR_DENIED);
else
{
@@ -142,7 +138,8 @@ public class LocationService implements LocationListener, SensorEventListener, W
for (String provider : providers)
{
- Log.d(TAG, "Connected to provider = " + provider);
+ mLogger.d("Connected to provider = ", provider);
+
// Half of a second is more than enough, I think ...
mLocationManager.requestLocationUpdates(provider, 500, 0, this);
}
@@ -155,7 +152,9 @@ public class LocationService implements LocationListener, SensorEventListener, W
if (notExpiredLocations.size() > 0)
{
final Location newestLocation = LocationUtils.getNewestLocation(notExpiredLocations);
+ mLogger.d("Last newest location: ", newestLocation);
final Location mostAccurateLocation = LocationUtils.getMostAccurateLocation(notExpiredLocations);
+ mLogger.d("Last accurate location: ", mostAccurateLocation);
if (LocationUtils.isFirstOneBetterLocation(newestLocation, mostAccurateLocation))
lastKnownLocation = newestLocation;
@@ -163,19 +162,19 @@ public class LocationService implements LocationListener, SensorEventListener, W
lastKnownLocation = mostAccurateLocation;
}
- if (mLastLocation != null && LocationUtils.isFirstOneBetterLocation(mLastLocation, lastKnownLocation))
+ if (LocationUtils.isNotExpired(mLastLocation) &&
+ LocationUtils.isFirstOneBetterLocation(mLastLocation, lastKnownLocation))
+ {
lastKnownLocation = mLastLocation;
- // ### location chosen
+ }
// Pass last known location only in the end of all registerListener
// in case, when we want to disconnect in listener.
if (lastKnownLocation != null)
{
- //mark location with current time
- lastKnownLocation.setTime(System.currentTimeMillis());
+ LocationUtils.hackLocationTime(lastKnownLocation);
emitLocation(lastKnownLocation);
}
-
}
if (mIsGPSOff)
@@ -236,22 +235,23 @@ public class LocationService implements LocationListener, SensorEventListener, W
public void stopUpdate(Listener observer)
{
- mLogger.d("Stop update", observer);
+ mLogger.d("Stop update for listener: ", observer);
mObservers.remove(observer);
- stopWifiLocationUpdate();
-
// Stop only if no more observers are subscribed
if (mObservers.size() == 0)
{
+ stopWifiLocationUpdate();
+
mLocationManager.removeUpdates(this);
+
if (mSensorManager != null)
mSensorManager.unregisterListener(this);
//mLastLocation = null;
- // reset current parameters to force initialize in the next startUpdate
+ // Reset current parameters to force initialize in the next startUpdate
mMagneticField = null;
mDrivingHeading = -1.0;
mIsActive = false;
@@ -259,18 +259,15 @@ public class LocationService implements LocationListener, SensorEventListener, W
}
private static final long MAXTIME_CALC_DIRECTIONS = 1000 * 10;
- private static final long LOCATION_EXPIRATION_TIME = 5 * 60 * 1000; /* 5 minutes*/
private List<Location> getAllNotExpiredLocations(List<String> providers)
{
List<Location> locations = new ArrayList<Location>(providers.size());
-
- for (String prov : providers)
+ for (String pr : providers)
{
- Location loc = mLocationManager.getLastKnownLocation(prov);
- final long timeNow = System.currentTimeMillis();
- if (loc != null && ((timeNow - loc.getTime()) <= LOCATION_EXPIRATION_TIME))
- locations.add(loc);
+ final Location l = mLocationManager.getLastKnownLocation(pr);
+ if (LocationUtils.isNotExpired(l))
+ locations.add(l);
}
return locations;
@@ -293,6 +290,8 @@ public class LocationService implements LocationListener, SensorEventListener, W
private void emitLocation(Location l)
{
+ mLogger.d("Location accepted: ", l);
+
mLastLocation = l;
notifyLocationUpdated(l);
}
@@ -303,13 +302,13 @@ public class LocationService implements LocationListener, SensorEventListener, W
@Override
public void onLocationChanged(Location l)
{
- mLogger.d("Location changed", l);
+ mLogger.d("Location changed: ", l);
+
// Completely ignore locations without lat and lon
- if (l.getAccuracy() <= 0.)
+ if (l.getAccuracy() <= 0.0)
return;
- // hack to avoid time zone troubles
- l.setTime(System.currentTimeMillis());
+ LocationUtils.hackLocationTime(l);
if (LocationUtils.isFirstOneBetterLocation(l, mLastLocation))
{
final long timeNow = System.currentTimeMillis();
@@ -471,25 +470,24 @@ public class LocationService implements LocationListener, SensorEventListener, W
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
- //Log.d(TAG, "Compass accuracy changed to " + String.valueOf(accuracy));
}
@Override
public void onProviderDisabled(String provider)
{
- Log.d(TAG, "Disabled location provider: " + provider);
+ mLogger.d("Disabled location provider: ", provider);
}
@Override
public void onProviderEnabled(String provider)
{
- Log.d(TAG, "Enabled location provider: " + provider);
+ mLogger.d("Enabled location provider: ", provider);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
- Log.d(TAG, String.format("Status changed for location provider: %s to %d", provider, status));
+ mLogger.d("Status changed for location provider: ", provider, status);
}
@Override
diff --git a/android/src/com/mapswithme/maps/location/WifiLocation.java b/android/src/com/mapswithme/maps/location/WifiLocation.java
index e261a63a8e..fffe27b2ca 100644
--- a/android/src/com/mapswithme/maps/location/WifiLocation.java
+++ b/android/src/com/mapswithme/maps/location/WifiLocation.java
@@ -1,6 +1,4 @@
package com.mapswithme.maps.location;
-import com.mapswithme.util.statistics.Statistics;
-
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
@@ -20,6 +18,9 @@ import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
+import com.mapswithme.util.LocationUtils;
+import com.mapswithme.util.statistics.Statistics;
+
public class WifiLocation extends BroadcastReceiver
{
private static final String MWM_GEOLOCATION_SERVER = "http://geolocation.server/";
@@ -29,7 +30,6 @@ public class WifiLocation extends BroadcastReceiver
public void onWifiLocationUpdated(Location l);
}
- // @TODO support multiple listeners
private Listener mObserver = null;
private WifiManager mWifi = null;
@@ -40,8 +40,7 @@ public class WifiLocation extends BroadcastReceiver
{
}
- // @TODO support multiple listeners
- // Returns true if was started successfully
+ /// @return true if was started successfully.
public boolean startScan(Context context, Listener l)
{
mObserver = l;
@@ -113,7 +112,7 @@ public class WifiLocation extends BroadcastReceiver
if (mLocationManager == null)
mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
- Location l = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
+ final Location l = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (l != null)
{
if (wifiHeaderAdded)
@@ -162,8 +161,8 @@ public class WifiLocation extends BroadcastReceiver
protected void onPostExecute(Boolean result)
{
// Notify event should be called on UI thread
- if (mObserver != null && this.mLocation != null)
- mObserver.onWifiLocationUpdated(this.mLocation);
+ if (mObserver != null && mLocation != null)
+ mObserver.onWifiLocationUpdated(mLocation);
}
@Override
@@ -196,7 +195,7 @@ public class WifiLocation extends BroadcastReceiver
mLocation.setAccuracy((float) acc);
mLocation.setLatitude(lat);
mLocation.setLongitude(lon);
- mLocation.setTime(java.lang.System.currentTimeMillis());
+ LocationUtils.setLocationCurrentTime(mLocation);
wr.close();
rd.close();
diff --git a/android/src/com/mapswithme/util/LocationUtils.java b/android/src/com/mapswithme/util/LocationUtils.java
index 9a8e8dfa8b..85ec818bd7 100644
--- a/android/src/com/mapswithme/util/LocationUtils.java
+++ b/android/src/com/mapswithme/util/LocationUtils.java
@@ -1,18 +1,62 @@
package com.mapswithme.util;
-import android.location.Location;
-
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import android.annotation.SuppressLint;
+import android.location.Location;
+import android.os.SystemClock;
+
/**
* Locations utils from {@link http://developer.android.com/guide/topics/location/strategies.html}
* Partly modified and suited for MWM.
*/
public class LocationUtils
{
- private static final int TWO_MINUTES = 1000 * 60 * 2;
+ private static final int TWO_MINUTES = 2 * 60 * 1000;
+ private static final long LOCATION_EXPIRATION_TIME = 5 * 60 * 1000;
+
+ @SuppressLint("NewApi")
+ public static boolean isNotExpired(Location l)
+ {
+ if (l != null)
+ {
+ long timeDiff;
+ if (Utils.apiEqualOrGreaterThan(17))
+ timeDiff = (SystemClock.elapsedRealtimeNanos() - l.getElapsedRealtimeNanos()) / 1000000;
+ else
+ timeDiff = System.currentTimeMillis() - l.getTime();
+ return (timeDiff <= LOCATION_EXPIRATION_TIME);
+ }
+ return false;
+ }
+
+ @SuppressLint("NewApi")
+ public static long timeDiffMillis(Location l1, Location l2)
+ {
+ if (Utils.apiEqualOrGreaterThan(17))
+ return (l1.getElapsedRealtimeNanos() - l2.getElapsedRealtimeNanos()) / 1000000;
+ else
+ return (l1.getTime() - l2.getTime());
+ }
+
+ @SuppressLint("NewApi")
+ public static void setLocationCurrentTime(Location l)
+ {
+ if (Utils.apiEqualOrGreaterThan(17))
+ l.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
+ l.setTime(System.currentTimeMillis());
+ }
+
+ /// Call this function before comparing or after getting location to
+ /// avoid troubles with invalid system time.
+ @SuppressLint("NewApi")
+ public static void hackLocationTime(Location l)
+ {
+ if (Utils.apiLowerThan(17))
+ l.setTime(System.currentTimeMillis());
+ }
/** Determines whether one Location reading is better than the current Location fix
* @param firstLoc The new Location that you want to evaluate
@@ -20,47 +64,51 @@ public class LocationUtils
*/
public static boolean isFirstOneBetterLocation(Location firstLoc, Location secondLoc)
{
+ if (firstLoc == null)
+ return false;
if (secondLoc == null)
- {
- // A new location is always better than no location
return true;
- }
// Check whether the new location fix is newer or older
- long timeDelta = firstLoc.getTime() - secondLoc.getTime();
- boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
- boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
- boolean isNewer = timeDelta > 0;
-
- // If it's been more than two minutes since the current location, use the new location
- // because the user has likely moved
- if (isSignificantlyNewer)
+ final long timeDelta = timeDiffMillis(firstLoc, secondLoc);
+
+ // If it's been more than two minutes since the current location,
+ // use the new location because the user has likely moved
+ if (timeDelta > TWO_MINUTES)
{
+ // significantly newer
return true;
- // If the new location is more than two minutes older, it must be worse
}
- else if (isSignificantlyOlder)
+ else if (timeDelta < -TWO_MINUTES)
+ {
+ // significantly older
return false;
+ }
// Check whether the new location fix is more or less accurate
- int accuracyDelta = (int) (firstLoc.getAccuracy() - secondLoc.getAccuracy());
- // Relative diff, not absolute
- boolean almostAsAccurate = Math.abs(accuracyDelta) <= 0.1*secondLoc.getAccuracy();
-
- boolean isMoreAccurate = accuracyDelta < 0;
- boolean isSignificantlyLessAccurate = accuracyDelta > 200;
-
- // Check if the old and new location are from the same provider
- boolean isFromSameProvider = isSameProvider(firstLoc.getProvider(),
- secondLoc.getProvider());
+ final float accuracyDelta = firstLoc.getAccuracy() - secondLoc.getAccuracy();
+ // Relative difference, not absolute
+ final boolean almostAsAccurate = Math.abs(accuracyDelta) <= 0.1*secondLoc.getAccuracy();
// Determine location quality using a combination of timeliness and accuracy
- if (isMoreAccurate)
+ final boolean isNewer = timeDelta > 0;
+ if (accuracyDelta < 0)
+ {
+ // more accurate and has the same time order
return true;
+ }
else if (isNewer && almostAsAccurate)
+ {
+ // newer and has the same accuracy order
return true;
- else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider)
+ }
+ else if (isNewer && accuracyDelta <= 200 &&
+ isSameProvider(firstLoc.getProvider(), secondLoc.getProvider()))
+ {
+ // not significantly less accurate and from the same provider
return true;
+ }
+
return false;
}
@@ -85,8 +133,7 @@ public class LocationUtils
@Override
public int compare(Location lhs, Location rhs)
{
- final float deltaAcc = rhs.getAccuracy() - lhs.getAccuracy();
- return (int) (1 * Math.signum(deltaAcc));
+ return (int) (1 * Math.signum(rhs.getAccuracy() - lhs.getAccuracy()));
}
};
@@ -100,8 +147,7 @@ public class LocationUtils
@Override
public int compare(Location lhs, Location rhs)
{
- final long deltaTime = lhs.getTime() - rhs.getTime();
- return (int) (1 * Math.signum(deltaTime));
+ return (int) (1 * Math.signum(timeDiffMillis(lhs, rhs)));
}
};
diff --git a/android/src/com/mapswithme/util/log/SimpleLogger.java b/android/src/com/mapswithme/util/log/SimpleLogger.java
index 131bb394c4..cafc4ca5cf 100644
--- a/android/src/com/mapswithme/util/log/SimpleLogger.java
+++ b/android/src/com/mapswithme/util/log/SimpleLogger.java
@@ -34,9 +34,9 @@ public class SimpleLogger extends Logger
private static String join(Object ... args)
{
- return TextUtils.join(",", args);
+ return (args != null ? TextUtils.join(", ", args) : "");
}
- private SimpleLogger() {};
- private SimpleLogger(String tag) { super(tag); };
+ private SimpleLogger() {}
+ private SimpleLogger(String tag) { super(tag); }
}