package com.theostriches.amaretto.android.location; import android.content.Context; import android.location.Criteria; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import com.theostriches.amaretto.android.util.Log; /** * Thread que se encarga de obtener la geolocalizacion * * @author Antonio Prada */ public class GpsThread extends Thread { public static final int GEOCODE_OK = 111; public static final int GEOCODE_OK_FIRST = 112; public static final int GEOCODE_OFF = 114; public static final int GEOCODE_GPS_FAILED = 113; private LocationManager mManager; private Context mContext; private Handler mHandler; private CustomLocationListener mListener; private boolean mIsFirstUpdate; private boolean mCancelled = false; /** * Crea el hilo de ejecucion, guardando el handler para la comunicacin con * la hebra grfica y tambien si es o no la primera vez que se le llama (al * inicio de la aplicacion es necesario obtener la localizacion rapidamente, * y esto se puede hacer usando la ultima conocida). * * @param handler * Handler para comunicarse con la hebra grfica. * @param context * Contexto de la aplicacin. * @param isFirstUpdate * Si estamos en el inicio de la aplicacin. */ public GpsThread(Handler handler, Context context, boolean isFirstUpdate) { mContext = context; mHandler = handler; mIsFirstUpdate = isFirstUpdate; if (mManager == null) { mManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); } if (mListener == null) { mListener = new CustomLocationListener(); } } /** * Obtiene el mejor network provider posible de entre los activados, segun * si se esta llamando al hilo desde el inicio de la aplicacin o no. * * @return String con el mejor network provider para esta situacion */ private String getBestProvider() { Criteria criteria = new Criteria(); criteria.setPowerRequirement(Criteria.NO_REQUIREMENT); criteria.setAltitudeRequired(false); criteria.setSpeedRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(true); if (mIsFirstUpdate) { // TODO fine o coarse? rapidez vs exactitud... criteria.setAccuracy(Criteria.ACCURACY_COARSE); } else { criteria.setAccuracy(Criteria.ACCURACY_COARSE); } return mManager.getBestProvider(criteria, true); } /** * Enva la localizacin a la hebra grfica. * * @param location * Localizacin actual. */ private void setLocation(Location location) { int code; // if (mIsFirstUpdate) { // code = GEOCODE_OK_FIRST; // } else { code = GEOCODE_OK; // } Message msg = Message.obtain(mHandler, code, location); mHandler.sendMessage(msg); } /** * Inicia el hilo de ejecucin. */ @Override public void run() { if (mIsFirstUpdate) { Log.d("Initial location update"); String provider = getBestProvider(); if (provider != null && !provider.equals("")) { Location location = mManager.getLastKnownLocation(provider); if (location != null) { setLocation(location); } } } else { Log.d("Normal location update"); String provider = getBestProvider(); if (provider != null && !provider.equals("")) { Looper.prepare(); mManager.requestLocationUpdates(provider, 1000L, 500.0f, mListener); Looper.loop(); Looper.myLooper().quit(); } else { mHandler.sendEmptyMessage(GEOCODE_OFF); } } } /** * Listener de las actualizaciones de la localizacin. Solo nos interesa la * primera actualizacin y entonces dejaremos de escuchar. * * @author Antonio Prada */ public class CustomLocationListener implements LocationListener { /** * Cuando tengamos una nueva localizacin. */ public void onLocationChanged(Location location) { Log.i("We have the location"); mManager.removeUpdates(mListener); if (!interrupted() && !mCancelled) { if (location != null) { setLocation(location); } else { mHandler.sendEmptyMessage(GEOCODE_GPS_FAILED); } } else { Log.d("Cancelled while listening for a location"); return; } } public void onProviderDisabled(String provider) { } public void onProviderEnabled(String provider) { } public void onStatusChanged(String provider, int status, Bundle extras) { } } /** * Cancelar la busqueda de la localizacin. */ public void cancel() { mCancelled = true; mManager.removeUpdates(mListener); } }