package org.mtransit.android.ui;
import org.mtransit.android.commons.Constants;
import org.mtransit.android.commons.LocationUtils;
import org.mtransit.android.commons.MTLog;
import org.mtransit.android.ui.fragment.VisibilityAwareFragment;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public abstract class MTActivityWithLocation extends MTActivityWithGoogleAPIClient implements com.google.android.gms.location.LocationListener {
private boolean useLocation = false;
private boolean locationUpdatesEnabled = false;
private LocationRequest locationRequest;
private Location userLocation;
public MTActivityWithLocation(boolean useLocation) {
super(useLocation); // location requires Google Play Services
this.useLocation = useLocation;
}
@Override
protected void addGoogleAPIs(GoogleApiClient.Builder googleApiClientBuilder) {
if (this.useLocation) {
googleApiClientBuilder.addApi(LocationServices.API);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (this.useLocation) {
this.locationRequest = LocationRequest.create();
this.locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // foreground app == high accuracy
this.locationRequest.setInterval(LocationUtils.UPDATE_INTERVAL_IN_MS);
this.locationRequest.setFastestInterval(LocationUtils.FASTEST_INTERVAL_IN_MS);
}
}
@Override
public void onClientConnected() {
if (this.useLocation) {
enableLocationUpdates();
}
}
@Override
protected void onResume() {
super.onResume();
enableLocationUpdates();
}
public void enableLocationUpdates() {
if (this.useLocation && !this.locationUpdatesEnabled) {
GoogleApiClient googleApiClient = getGoogleApiClientOrInit();
if (googleApiClient != null && googleApiClient.isConnected()) {
try {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, this.locationRequest, this);
this.locationUpdatesEnabled = true;
} catch (IllegalStateException ise) { // wrong thread?
MTLog.w(this, ise, "Error while enabling location updates!");
this.locationUpdatesEnabled = false;
}
Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
onLocationChanged(lastLocation);
}
}
}
@Override
protected void onPause() {
super.onPause();
disableLocationUpdates();
}
public void disableLocationUpdates() {
if (this.locationUpdatesEnabled) {
GoogleApiClient googleApiClient = getGoogleApiClientOrInit();
if (googleApiClient != null && googleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
this.locationUpdatesEnabled = false;
}
}
}
@Override
public void onBeforeClientDisconnected() {
disableLocationUpdates();
}
@Override
public void onLocationChanged(Location location) {
if (Constants.LOG_LOCATION) {
MTLog.v(this, "onLocationChanged(%s)", location);
}
this.userLocation = location;
onUserLocationChanged(this.userLocation);
}
public abstract void onUserLocationChanged(Location newLocation);
public Location getUserLocation() {
return this.userLocation;
}
public Location getLastLocation() {
if (!this.locationUpdatesEnabled) {
return null;
}
GoogleApiClient googleApiClient = getGoogleApiClientOrInit();
if (googleApiClient == null) {
return null;
}
Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
onLocationChanged(lastLocation);
return this.userLocation;
}
public static void broadcastUserLocationChanged(MTLog.Loggable loggable, FragmentManager fm, Location newLocation) {
java.util.List<Fragment> fragments = fm.getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
if (fragment == null) {
continue;
}
if (fragment instanceof MTActivityWithLocation.UserLocationListener) {
if (!fragment.isResumed() && !fragment.isVisible()) {
continue;
}
if (fragment instanceof VisibilityAwareFragment) {
VisibilityAwareFragment visibilityAwareFragment = (VisibilityAwareFragment) fragment;
if (!visibilityAwareFragment.isFragmentVisible()) {
continue;
}
}
((MTActivityWithLocation.UserLocationListener) fragment).onUserLocationChanged(newLocation);
}
}
}
}
public interface UserLocationListener {
void onUserLocationChanged(Location location);
}
}