mirror of
https://github.com/YTVanced/VancedMicroG
synced 2024-11-28 14:13:00 +00:00
Add basic support for location API (request and last location)
This commit is contained in:
parent
c57656d321
commit
3e573917ba
7 changed files with 337 additions and 43 deletions
|
@ -30,6 +30,8 @@ import static org.microg.gms.maps.Constants.ACTION_GMS_LOCATION_MANAGER_SERVICE_
|
||||||
|
|
||||||
public class GoogleLocationManagerService extends Service {
|
public class GoogleLocationManagerService extends Service {
|
||||||
private static final String TAG = "GmsLMS";
|
private static final String TAG = "GmsLMS";
|
||||||
|
|
||||||
|
private GoogleLocationManagerServiceImpl impl = new GoogleLocationManagerServiceImpl(this);
|
||||||
private AbstractGmsServiceBroker broker = new AbstractGmsServiceBroker() {
|
private AbstractGmsServiceBroker broker = new AbstractGmsServiceBroker() {
|
||||||
@Override
|
@Override
|
||||||
public void getGoogleLocationManagerService(IGmsCallbacks callback, int versionCode,
|
public void getGoogleLocationManagerService(IGmsCallbacks callback, int versionCode,
|
||||||
|
@ -38,7 +40,6 @@ public class GoogleLocationManagerService extends Service {
|
||||||
callback.onPostInitComplete(0, impl.asBinder(), null);
|
callback.onPostInitComplete(0, impl.asBinder(), null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private GoogleLocationManagerServiceImpl impl = new GoogleLocationManagerServiceImpl(this);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
|
|
|
@ -6,58 +6,64 @@ import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.os.Bundle;
|
import com.google.android.gms.location.ILocationListener;
|
||||||
import com.google.android.gms.location.LocationRequest;
|
import com.google.android.gms.location.LocationRequest;
|
||||||
import com.google.android.gms.location.internal.ILocationListener;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.List;
|
||||||
|
|
||||||
import static android.location.LocationManager.GPS_PROVIDER;
|
import static android.location.LocationManager.GPS_PROVIDER;
|
||||||
import static android.location.LocationManager.NETWORK_PROVIDER;
|
import static android.location.LocationManager.NETWORK_PROVIDER;
|
||||||
import static org.microg.gms.maps.Constants.KEY_MOCK_LOCATION;
|
|
||||||
|
|
||||||
public class GoogleLocationManager {
|
public class GoogleLocationManager implements LocationChangeListener {
|
||||||
private static final String MOCK_PROVIDER = KEY_MOCK_LOCATION;
|
private static final String MOCK_PROVIDER = "mock";
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
private LocationManager locationManager;
|
private LocationManager locationManager;
|
||||||
private Map<String, Location> lastKnownLocaton = new HashMap<>();
|
private RealLocationProvider gpsProvider;
|
||||||
|
private RealLocationProvider networkProvider;
|
||||||
|
private MockLocationProvider mockProvider;
|
||||||
|
private List<LocationRequestHelper> currentRequests = new ArrayList<>();
|
||||||
|
|
||||||
public GoogleLocationManager(Context context) {
|
public GoogleLocationManager(Context context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
||||||
updateLastKnownLocation();
|
gpsProvider = new RealLocationProvider(locationManager, GPS_PROVIDER, this);
|
||||||
}
|
networkProvider = new RealLocationProvider(locationManager, NETWORK_PROVIDER, this);
|
||||||
|
mockProvider = new MockLocationProvider(this);
|
||||||
private void updateLastKnownLocation() {
|
|
||||||
lastKnownLocaton.put(GPS_PROVIDER, locationManager.getLastKnownLocation(GPS_PROVIDER));
|
|
||||||
lastKnownLocaton.put(NETWORK_PROVIDER,
|
|
||||||
locationManager.getLastKnownLocation(NETWORK_PROVIDER));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location getLastLocation(String packageName) {
|
public Location getLastLocation(String packageName) {
|
||||||
if (lastKnownLocaton.get(KEY_MOCK_LOCATION) != null)
|
return getLocation(hasFineLocationPermission(), hasCoarseLocationPermission());
|
||||||
return lastKnownLocaton.get(KEY_MOCK_LOCATION);
|
}
|
||||||
if (hasFineLocationPermission()) {
|
|
||||||
Location network = lastKnownLocaton.get(NETWORK_PROVIDER);
|
public Location getLocation(boolean gpsPermission, boolean networkPermission) {
|
||||||
Location gps = lastKnownLocaton.get(GPS_PROVIDER);
|
if (mockProvider.getLocation() != null)
|
||||||
|
return mockProvider.getLocation();
|
||||||
|
if (gpsPermission) {
|
||||||
|
Location network = networkProvider.getLastLocation();
|
||||||
|
Location gps = gpsProvider.getLastLocation();
|
||||||
if (network == null)
|
if (network == null)
|
||||||
return gps;
|
return gps;
|
||||||
if (gps == null)
|
if (gps == null)
|
||||||
return network;
|
return network;
|
||||||
if (gps.getTime() > network.getTime())
|
if (gps.getTime() > network.getTime() - 10000)
|
||||||
return gps;
|
return gps;
|
||||||
return network;
|
return network;
|
||||||
} else if (hasCoarseLocationPermission()) {
|
} else if (networkPermission) {
|
||||||
return lastKnownLocaton.get(NETWORK_PROVIDER);
|
Location network = networkProvider.getLastLocation();
|
||||||
|
if (network.getExtras() != null &&
|
||||||
|
network.getExtras().getParcelable("no_gps_location") instanceof Location) {
|
||||||
|
network = network.getExtras().getParcelable("no_gps_location");
|
||||||
|
}
|
||||||
|
return network;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasCoarseLocationPermission() {
|
private boolean hasCoarseLocationPermission() {
|
||||||
return context.checkCallingPermission(Manifest.permission.ACCESS_COARSE_LOCATION) ==
|
return context.checkCallingPermission(Manifest.permission.ACCESS_COARSE_LOCATION) ==
|
||||||
PackageManager.PERMISSION_GRANTED;
|
PackageManager.PERMISSION_GRANTED || hasFineLocationPermission();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasFineLocationPermission() {
|
private boolean hasFineLocationPermission() {
|
||||||
|
@ -70,37 +76,75 @@ public class GoogleLocationManager {
|
||||||
PackageManager.PERMISSION_GRANTED;
|
PackageManager.PERMISSION_GRANTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void requestLocationUpdates(LocationRequestHelper request) {
|
||||||
|
currentRequests.add(request);
|
||||||
|
if (request.hasFinePermission &&
|
||||||
|
request.locationRequest.getPriority() == LocationRequest.PRIORITY_HIGH_ACCURACY)
|
||||||
|
gpsProvider.addRequest(request);
|
||||||
|
if (request.hasCoarsePermission &&
|
||||||
|
request.locationRequest.getPriority() != LocationRequest.PRIORITY_NO_POWER)
|
||||||
|
networkProvider.addRequest(request);
|
||||||
|
}
|
||||||
|
|
||||||
public void requestLocationUpdates(LocationRequest request, ILocationListener listener,
|
public void requestLocationUpdates(LocationRequest request, ILocationListener listener,
|
||||||
String packageName) {
|
String packageName) {
|
||||||
|
requestLocationUpdates(
|
||||||
|
new LocationRequestHelper(context, request, hasFineLocationPermission(),
|
||||||
|
hasCoarseLocationPermission(), packageName, listener));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestLocationUpdates(LocationRequest request, PendingIntent intent) {
|
public void requestLocationUpdates(LocationRequest request, PendingIntent intent,
|
||||||
|
String packageName) {
|
||||||
|
requestLocationUpdates(
|
||||||
|
new LocationRequestHelper(context, request, hasFineLocationPermission(),
|
||||||
|
hasCoarseLocationPermission(), packageName, intent));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeLocationUpdates(ILocationListener listener) {
|
private void removeLocationUpdates(LocationRequestHelper request) {
|
||||||
|
currentRequests.remove(request);
|
||||||
|
gpsProvider.removeRequest(request);
|
||||||
|
networkProvider.removeRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeLocationUpdates(PendingIntent intent) {
|
public void removeLocationUpdates(ILocationListener listener, String packageName) {
|
||||||
|
for (int i = 0; i < currentRequests.size(); i++) {
|
||||||
|
if (currentRequests.get(i).respondsTo(listener)) {
|
||||||
|
removeLocationUpdates(currentRequests.get(i));
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLocationUpdates(PendingIntent intent, String packageName) {
|
||||||
|
for (int i = 0; i < currentRequests.size(); i++) {
|
||||||
|
if (currentRequests.get(i).respondsTo(intent)) {
|
||||||
|
removeLocationUpdates(currentRequests.get(i));
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMockMode(boolean mockMode) {
|
public void setMockMode(boolean mockMode) {
|
||||||
if (!hasMockLocationPermission())
|
if (!hasMockLocationPermission())
|
||||||
return;
|
return;
|
||||||
if (!mockMode)
|
mockProvider.setMockEnabled(mockMode);
|
||||||
lastKnownLocaton.put(MOCK_PROVIDER, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMockLocation(Location mockLocation) {
|
public void setMockLocation(Location mockLocation) {
|
||||||
if (!hasMockLocationPermission())
|
if (!hasMockLocationPermission())
|
||||||
return;
|
return;
|
||||||
if (mockLocation.getExtras() == null) {
|
mockProvider.setLocation(mockLocation);
|
||||||
mockLocation.setExtras(new Bundle());
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLocationChanged() {
|
||||||
|
for (int i = 0; i < currentRequests.size(); i++) {
|
||||||
|
LocationRequestHelper request = currentRequests.get(i);
|
||||||
|
if (!request
|
||||||
|
.report(getLocation(request.hasFinePermission, request.hasCoarsePermission))) {
|
||||||
|
removeLocationUpdates(request);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mockLocation.getExtras().putBoolean(KEY_MOCK_LOCATION, false);
|
|
||||||
lastKnownLocaton.put(MOCK_PROVIDER, mockLocation);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import com.google.android.gms.location.LocationRequest;
|
||||||
import com.google.android.gms.location.LocationStatus;
|
import com.google.android.gms.location.LocationStatus;
|
||||||
import com.google.android.gms.location.internal.IGeofencerCallbacks;
|
import com.google.android.gms.location.internal.IGeofencerCallbacks;
|
||||||
import com.google.android.gms.location.internal.IGoogleLocationManagerService;
|
import com.google.android.gms.location.internal.IGoogleLocationManagerService;
|
||||||
import com.google.android.gms.location.internal.ILocationListener;
|
import com.google.android.gms.location.ILocationListener;
|
||||||
import com.google.android.gms.location.internal.LocationRequestInternal;
|
import com.google.android.gms.location.internal.LocationRequestInternal;
|
||||||
import com.google.android.gms.location.places.*;
|
import com.google.android.gms.location.places.*;
|
||||||
import com.google.android.gms.location.places.internal.IPlacesCallbacks;
|
import com.google.android.gms.location.places.internal.IPlacesCallbacks;
|
||||||
|
@ -89,21 +89,21 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
|
||||||
public void requestLocationUpdatesWithIntent(LocationRequest request,
|
public void requestLocationUpdatesWithIntent(LocationRequest request,
|
||||||
PendingIntent callbackIntent) throws RemoteException {
|
PendingIntent callbackIntent) throws RemoteException {
|
||||||
Log.d(TAG, "requestLocationUpdatesWithIntent: " + request);
|
Log.d(TAG, "requestLocationUpdatesWithIntent: " + request);
|
||||||
getLocationManager().requestLocationUpdates(request, callbackIntent);
|
getLocationManager().requestLocationUpdates(request, callbackIntent, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeLocationUpdatesWithListener(ILocationListener listener)
|
public void removeLocationUpdatesWithListener(ILocationListener listener)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
Log.d(TAG, "removeLocationUpdatesWithListener: " + listener);
|
Log.d(TAG, "removeLocationUpdatesWithListener: " + listener);
|
||||||
getLocationManager().removeLocationUpdates(listener);
|
getLocationManager().removeLocationUpdates(listener, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeLocationUpdatesWithIntent(PendingIntent callbackIntent)
|
public void removeLocationUpdatesWithIntent(PendingIntent callbackIntent)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
Log.d(TAG, "removeLocationUpdatesWithIntent: " + callbackIntent);
|
Log.d(TAG, "removeLocationUpdatesWithIntent: " + callbackIntent);
|
||||||
getLocationManager().removeLocationUpdates(callbackIntent);
|
getLocationManager().removeLocationUpdates(callbackIntent, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -154,9 +154,9 @@ public class GoogleLocationManagerServiceImpl extends IGoogleLocationManagerServ
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestLocationUpdates(LocationRequest request, ILocationListener listener,
|
public void requestLocationUpdatesWithPackage(LocationRequest request, ILocationListener listener,
|
||||||
String packageName) throws RemoteException {
|
String packageName) throws RemoteException {
|
||||||
Log.d(TAG, "requestLocationUpdates: " + request);
|
Log.d(TAG, "requestLocationUpdatesWithPackage: " + request);
|
||||||
getLocationManager().requestLocationUpdates(request, listener, packageName);
|
getLocationManager().requestLocationUpdates(request, listener, packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
src/org/microg/gms/location/LocationChangeListener.java
Normal file
5
src/org/microg/gms/location/LocationChangeListener.java
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package org.microg.gms.location;
|
||||||
|
|
||||||
|
public interface LocationChangeListener {
|
||||||
|
public void onLocationChanged();
|
||||||
|
}
|
102
src/org/microg/gms/location/LocationRequestHelper.java
Normal file
102
src/org/microg/gms/location/LocationRequestHelper.java
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
package org.microg.gms.location;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.location.Location;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.util.Log;
|
||||||
|
import com.google.android.gms.location.ILocationListener;
|
||||||
|
import com.google.android.gms.location.LocationRequest;
|
||||||
|
|
||||||
|
public class LocationRequestHelper {
|
||||||
|
public static final String TAG = "GmsLocationRequestHelper";
|
||||||
|
private final Context context;
|
||||||
|
public final LocationRequest locationRequest;
|
||||||
|
public final boolean hasFinePermission;
|
||||||
|
public final boolean hasCoarsePermission;
|
||||||
|
public final String packageName;
|
||||||
|
private ILocationListener listener;
|
||||||
|
private PendingIntent pendingIntent;
|
||||||
|
|
||||||
|
private Location lastReport;
|
||||||
|
private int numReports = 0;
|
||||||
|
|
||||||
|
public LocationRequestHelper(Context context, LocationRequest locationRequest,
|
||||||
|
boolean hasFinePermission, boolean hasCoarsePermission, String packageName,
|
||||||
|
ILocationListener listener) {
|
||||||
|
this.context = context;
|
||||||
|
this.locationRequest = locationRequest;
|
||||||
|
this.hasFinePermission = hasFinePermission;
|
||||||
|
this.hasCoarsePermission = hasCoarsePermission;
|
||||||
|
this.packageName = packageName;
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocationRequestHelper(Context context, LocationRequest locationRequest,
|
||||||
|
boolean hasFinePermission, boolean hasCoarsePermission, String packageName,
|
||||||
|
PendingIntent pendingIntent) {
|
||||||
|
this.context = context;
|
||||||
|
this.locationRequest = locationRequest;
|
||||||
|
this.hasFinePermission = hasFinePermission;
|
||||||
|
this.hasCoarsePermission = hasCoarsePermission;
|
||||||
|
this.packageName = packageName;
|
||||||
|
this.pendingIntent = pendingIntent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return whether to continue sending reports to this {@link LocationRequestHelper}
|
||||||
|
*/
|
||||||
|
public boolean report(Location location) {
|
||||||
|
if (lastReport != null) {
|
||||||
|
if (location.getTime() - lastReport.getTime() < locationRequest.getFastestInterval()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (location.distanceTo(lastReport) < locationRequest.getSmallestDesplacement()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.d(TAG, "sending Location: " + location);
|
||||||
|
if (listener != null) {
|
||||||
|
try {
|
||||||
|
listener.onLocationChanged(location);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (pendingIntent != null) {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.putExtra("com.google.android.location.LOCATION", location);
|
||||||
|
try {
|
||||||
|
pendingIntent.send(context, 0, intent);
|
||||||
|
} catch (PendingIntent.CanceledException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastReport = location;
|
||||||
|
numReports++;
|
||||||
|
if (numReports >= locationRequest.getNumUpdates()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "LocationRequestHelper{" +
|
||||||
|
"locationRequest=" + locationRequest +
|
||||||
|
", hasFinePermission=" + hasFinePermission +
|
||||||
|
", hasCoarsePermission=" + hasCoarsePermission +
|
||||||
|
", packageName='" + packageName + '\'' +
|
||||||
|
", lastReport=" + lastReport +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean respondsTo(ILocationListener listener) {
|
||||||
|
return this.listener != null && listener != null &&
|
||||||
|
this.listener.asBinder().equals(listener.asBinder());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean respondsTo(PendingIntent pendingIntent) {
|
||||||
|
return this.pendingIntent != null && this.pendingIntent.equals(pendingIntent);
|
||||||
|
}
|
||||||
|
}
|
32
src/org/microg/gms/location/MockLocationProvider.java
Normal file
32
src/org/microg/gms/location/MockLocationProvider.java
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
package org.microg.gms.location;
|
||||||
|
|
||||||
|
import android.location.Location;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import static org.microg.gms.maps.Constants.KEY_MOCK_LOCATION;
|
||||||
|
|
||||||
|
public class MockLocationProvider {
|
||||||
|
private boolean mockEnabled = false;
|
||||||
|
private Location mockLocation = null;
|
||||||
|
private final LocationChangeListener changeListener;
|
||||||
|
|
||||||
|
public MockLocationProvider(LocationChangeListener changeListener) {
|
||||||
|
this.changeListener = changeListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMockEnabled(boolean mockEnabled) {
|
||||||
|
this.mockEnabled = mockEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location getLocation() {
|
||||||
|
return mockEnabled ? mockLocation : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(Location mockLocation) {
|
||||||
|
if (mockLocation.getExtras() == null) {
|
||||||
|
mockLocation.setExtras(new Bundle());
|
||||||
|
}
|
||||||
|
mockLocation.getExtras().putBoolean(KEY_MOCK_LOCATION, false);
|
||||||
|
this.mockLocation = mockLocation;
|
||||||
|
}
|
||||||
|
}
|
110
src/org/microg/gms/location/RealLocationProvider.java
Normal file
110
src/org/microg/gms/location/RealLocationProvider.java
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
package org.microg.gms.location;
|
||||||
|
|
||||||
|
import android.location.Location;
|
||||||
|
import android.location.LocationListener;
|
||||||
|
import android.location.LocationManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
public class RealLocationProvider {
|
||||||
|
|
||||||
|
public static final String TAG = "GmsRealLocationProvider";
|
||||||
|
private Location lastLocation;
|
||||||
|
private LocationManager locationManager;
|
||||||
|
private String name;
|
||||||
|
private final AtomicBoolean connected = new AtomicBoolean(false);
|
||||||
|
private long connectedMinTime;
|
||||||
|
private float connectedMinDistance;
|
||||||
|
private List<LocationRequestHelper> requests = new ArrayList<>();
|
||||||
|
private final LocationChangeListener changeListener;
|
||||||
|
private LocationListener listener = new LocationListener() {
|
||||||
|
@Override
|
||||||
|
public void onLocationChanged(Location location) {
|
||||||
|
lastLocation = location;
|
||||||
|
changeListener.onLocationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStatusChanged(String s, int i, Bundle bundle) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProviderEnabled(String s) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProviderDisabled(String s) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public RealLocationProvider(LocationManager locationManager, String name,
|
||||||
|
LocationChangeListener changeListener) {
|
||||||
|
this.locationManager = locationManager;
|
||||||
|
this.name = name;
|
||||||
|
this.changeListener = changeListener;
|
||||||
|
updateLastLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateLastLocation() {
|
||||||
|
lastLocation = locationManager.getLastKnownLocation(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location getLastLocation() {
|
||||||
|
if (!connected.get()) {
|
||||||
|
updateLastLocation();
|
||||||
|
}
|
||||||
|
return lastLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addRequest(LocationRequestHelper request) {
|
||||||
|
Log.d(TAG, name + ": addRequest " + request);
|
||||||
|
requests.add(request);
|
||||||
|
updateConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeRequest(LocationRequestHelper request) {
|
||||||
|
Log.d(TAG, name + ": removeRequest " + request);
|
||||||
|
requests.remove(request);
|
||||||
|
updateConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void updateConnection() {
|
||||||
|
if (connected.get() && requests.isEmpty()) {
|
||||||
|
Log.d(TAG, name + ": no longer requesting location update");
|
||||||
|
locationManager.removeUpdates(listener);
|
||||||
|
connected.set(false);
|
||||||
|
} else if (!requests.isEmpty()) {
|
||||||
|
long minTime = Long.MAX_VALUE;
|
||||||
|
float minDistance = Float.MAX_VALUE;
|
||||||
|
for (LocationRequestHelper request : requests) {
|
||||||
|
minTime = Math.min(request.locationRequest.getInterval(), minTime);
|
||||||
|
minDistance = Math
|
||||||
|
.min(request.locationRequest.getSmallestDesplacement(), minDistance);
|
||||||
|
}
|
||||||
|
if (connected.get()) {
|
||||||
|
if (connectedMinTime != minTime || connectedMinDistance != minDistance) {
|
||||||
|
locationManager.removeUpdates(listener);
|
||||||
|
locationManager.requestLocationUpdates(name, minTime, minDistance, listener,
|
||||||
|
Looper.getMainLooper());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
locationManager.requestLocationUpdates(name, minTime, minDistance, listener,
|
||||||
|
Looper.getMainLooper());
|
||||||
|
}
|
||||||
|
Log.d(TAG,
|
||||||
|
name + ": requesting location updates. minTime=" + minTime + " minDistance=" +
|
||||||
|
minDistance);
|
||||||
|
connected.set(true);
|
||||||
|
connectedMinTime = minTime;
|
||||||
|
connectedMinDistance = minDistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue