2015-01-11 11:56:18 +00:00
|
|
|
package org.microg.gms.location;
|
|
|
|
|
|
|
|
import android.Manifest;
|
|
|
|
import android.app.PendingIntent;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.pm.PackageManager;
|
|
|
|
import android.location.Location;
|
|
|
|
import android.location.LocationManager;
|
2015-01-11 15:41:57 +00:00
|
|
|
import com.google.android.gms.location.ILocationListener;
|
2015-01-11 11:56:18 +00:00
|
|
|
import com.google.android.gms.location.LocationRequest;
|
|
|
|
|
2015-01-11 15:41:57 +00:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
2015-01-11 11:56:18 +00:00
|
|
|
|
|
|
|
import static android.location.LocationManager.GPS_PROVIDER;
|
|
|
|
import static android.location.LocationManager.NETWORK_PROVIDER;
|
|
|
|
|
2015-01-11 15:41:57 +00:00
|
|
|
public class GoogleLocationManager implements LocationChangeListener {
|
|
|
|
private static final String MOCK_PROVIDER = "mock";
|
2015-01-11 11:56:18 +00:00
|
|
|
|
|
|
|
private Context context;
|
|
|
|
private LocationManager locationManager;
|
2015-01-11 15:41:57 +00:00
|
|
|
private RealLocationProvider gpsProvider;
|
|
|
|
private RealLocationProvider networkProvider;
|
|
|
|
private MockLocationProvider mockProvider;
|
|
|
|
private List<LocationRequestHelper> currentRequests = new ArrayList<>();
|
2015-01-11 11:56:18 +00:00
|
|
|
|
|
|
|
public GoogleLocationManager(Context context) {
|
|
|
|
this.context = context;
|
|
|
|
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
2015-01-11 15:41:57 +00:00
|
|
|
gpsProvider = new RealLocationProvider(locationManager, GPS_PROVIDER, this);
|
|
|
|
networkProvider = new RealLocationProvider(locationManager, NETWORK_PROVIDER, this);
|
|
|
|
mockProvider = new MockLocationProvider(this);
|
2015-01-11 11:56:18 +00:00
|
|
|
}
|
|
|
|
|
2015-01-11 15:41:57 +00:00
|
|
|
public Location getLastLocation(String packageName) {
|
|
|
|
return getLocation(hasFineLocationPermission(), hasCoarseLocationPermission());
|
2015-01-11 11:56:18 +00:00
|
|
|
}
|
|
|
|
|
2015-01-11 15:41:57 +00:00
|
|
|
public Location getLocation(boolean gpsPermission, boolean networkPermission) {
|
|
|
|
if (mockProvider.getLocation() != null)
|
|
|
|
return mockProvider.getLocation();
|
|
|
|
if (gpsPermission) {
|
|
|
|
Location network = networkProvider.getLastLocation();
|
|
|
|
Location gps = gpsProvider.getLastLocation();
|
2015-01-11 11:56:18 +00:00
|
|
|
if (network == null)
|
|
|
|
return gps;
|
|
|
|
if (gps == null)
|
|
|
|
return network;
|
2015-01-11 15:41:57 +00:00
|
|
|
if (gps.getTime() > network.getTime() - 10000)
|
2015-01-11 11:56:18 +00:00
|
|
|
return gps;
|
|
|
|
return network;
|
2015-01-11 15:41:57 +00:00
|
|
|
} else if (networkPermission) {
|
|
|
|
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;
|
2015-01-11 11:56:18 +00:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean hasCoarseLocationPermission() {
|
|
|
|
return context.checkCallingPermission(Manifest.permission.ACCESS_COARSE_LOCATION) ==
|
2015-01-11 15:41:57 +00:00
|
|
|
PackageManager.PERMISSION_GRANTED || hasFineLocationPermission();
|
2015-01-11 11:56:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private boolean hasFineLocationPermission() {
|
|
|
|
return context.checkCallingPermission(Manifest.permission.ACCESS_FINE_LOCATION) ==
|
|
|
|
PackageManager.PERMISSION_GRANTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean hasMockLocationPermission() {
|
|
|
|
return context.checkCallingPermission(Manifest.permission.ACCESS_MOCK_LOCATION) ==
|
|
|
|
PackageManager.PERMISSION_GRANTED;
|
|
|
|
}
|
|
|
|
|
2015-01-11 15:41:57 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2015-01-11 11:56:18 +00:00
|
|
|
public void requestLocationUpdates(LocationRequest request, ILocationListener listener,
|
|
|
|
String packageName) {
|
2015-01-11 15:41:57 +00:00
|
|
|
requestLocationUpdates(
|
|
|
|
new LocationRequestHelper(context, request, hasFineLocationPermission(),
|
|
|
|
hasCoarseLocationPermission(), packageName, listener));
|
2015-01-11 11:56:18 +00:00
|
|
|
}
|
|
|
|
|
2015-01-11 15:41:57 +00:00
|
|
|
public void requestLocationUpdates(LocationRequest request, PendingIntent intent,
|
|
|
|
String packageName) {
|
|
|
|
requestLocationUpdates(
|
|
|
|
new LocationRequestHelper(context, request, hasFineLocationPermission(),
|
|
|
|
hasCoarseLocationPermission(), packageName, intent));
|
2015-01-11 11:56:18 +00:00
|
|
|
}
|
|
|
|
|
2015-01-11 15:41:57 +00:00
|
|
|
private void removeLocationUpdates(LocationRequestHelper request) {
|
|
|
|
currentRequests.remove(request);
|
|
|
|
gpsProvider.removeRequest(request);
|
|
|
|
networkProvider.removeRequest(request);
|
2015-01-11 11:56:18 +00:00
|
|
|
}
|
|
|
|
|
2015-01-11 15:41:57 +00:00
|
|
|
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--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-01-11 11:56:18 +00:00
|
|
|
|
2015-01-11 15:41:57 +00:00
|
|
|
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--;
|
|
|
|
}
|
|
|
|
}
|
2015-01-11 11:56:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setMockMode(boolean mockMode) {
|
|
|
|
if (!hasMockLocationPermission())
|
|
|
|
return;
|
2015-01-11 15:41:57 +00:00
|
|
|
mockProvider.setMockEnabled(mockMode);
|
2015-01-11 11:56:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setMockLocation(Location mockLocation) {
|
|
|
|
if (!hasMockLocationPermission())
|
|
|
|
return;
|
2015-01-11 15:41:57 +00:00
|
|
|
mockProvider.setLocation(mockLocation);
|
|
|
|
}
|
|
|
|
|
|
|
|
@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--;
|
|
|
|
}
|
2015-01-11 11:56:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|