package com.papagiannis.tuberun.fragments; import java.util.Date; import java.util.List; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.LatLngBounds; import com.google.android.gms.maps.model.Marker; import com.google.android.maps.MapController; import com.google.android.maps.Overlay; import com.papagiannis.tuberun.R; /* * A MapActivity that always shows the user's location */ public class MeMapFragment extends Fragment implements LocationListener { protected GoogleMap gMap; protected MapController mapController; protected LocationManager locationManager; protected final LatLng LONDON = new LatLng(51.501496, -0.124240); protected static final int TWO_MINUTES = 1000 * 60 * 2; private static final int LOCATION_SERVICE_FAILED = 0; protected Location lastKnownLocation; protected Date started; protected List<Overlay> mapOverlays; protected Overlay myPushpin; protected Button backButton; protected Button logoButton; protected TextView titleTextView; protected LinearLayout titleLayout; private boolean navigateOnLocationOnce; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View fragment = inflater.inflate(R.layout.me_map_fragment, container, false); gMap = ((SupportMapFragment) getFragmentManager().findFragmentById( R.id.map)).getMap(); if (gMap == null) return fragment; gMap.setMyLocationEnabled(true); gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LONDON, 16)); return fragment; } public void onLocationChanged(Location l) { if (isBetterLocation(l, lastKnownLocation)) { lastKnownLocation = l; if (navigateOnLocationOnce) { navigateOnLocationOnce=false; gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(l.getLatitude(), l.getLongitude()), 16)); } } } public void animateToMarkers(Iterable<Marker> markers) { animateToMarkers(markers, 1, 1); } public void animateToMarkers(Iterable<Marker> markers, double wPercent, double hPercent) { if (markers == null) return; LatLngBounds.Builder bc = new LatLngBounds.Builder(); for (Marker item : markers) { bc.include(item.getPosition()); } gMap.moveCamera(CameraUpdateFactory.newLatLngBounds( bc.build(), (int) (this.getResources().getDisplayMetrics().widthPixels * wPercent), (int) (this.getResources().getDisplayMetrics().heightPixels * hPercent), 50)); } /** * Determines whether one Location reading is better than the current * Location fix * * @param location * The new Location that you want to evaluate * @param currentBestLocation * The current Location fix, to which you want to compare the new * one */ public static boolean isBetterLocation(Location location, Location currentBestLocation) { if (currentBestLocation == null) { // A new location is always better than no location return true; } // Check whether the new location fix is newer or older long timeDelta = location.getTime() - currentBestLocation.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) { return true; // If the new location is more than two minutes older, it must be // worse } else if (isSignificantlyOlder) { return false; } // Check whether the new location fix is more or less accurate int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation .getAccuracy()); boolean isSignificantlyMoreAccurate = accuracyDelta < -10; // Check if the old and new location are from the same provider // boolean isFromSameProvider = isSameProvider(location.getProvider(), // currentBestLocation.getProvider()); float distance = location.distanceTo(currentBestLocation); boolean hasMovedSignificantly = distance > 5; if (isNewer && isSignificantlyMoreAccurate) { return true; } if (isNewer && hasMovedSignificantly) { return true; } return false; } private void requestLocationUpdates() { try { if (locationManager != null) { locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, 2 * 1000, 5, this); locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 3 * 1000, 5, this); } } catch (Exception e) { Log.w("LocationService", e); showDialog(LOCATION_SERVICE_FAILED); } } protected void showDialog(int id) { DialogFragment newFragment; String title = ""; String message = ""; switch (id) { case LOCATION_SERVICE_FAILED: title = "Location Service Failed"; message = "Does you device support location services? Turn them on in the settings."; break; } newFragment = AlertDialogFragment.newInstance(title, message); newFragment.show(getFragmentManager(), "dialog"); } @Override public void onPause() { super.onPause(); if (locationManager != null) locationManager.removeUpdates(this); } @Override public void onResume() { super.onResume(); if (locationManager != null) requestLocationUpdates(); } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } public void setNavigateOnLocationOnce(boolean v) { navigateOnLocationOnce=v; } }