В первой части мы проанализировали наши требования и имеющиеся в нашем распоряжении инструменты, чтобы получить первоначальный дизайн приложения.
![]() |
Во второй части мы реализовали LocatorOverlay . Теперь мы продолжим с классом Location , где будет инкапсулирована большая часть кода, зависящего от местоположения. Интерес представляют следующие классы в пакетах Google Maps и Android Location:
// package statement and other imports
//...
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
/**
* This class encapsulates the location logic
*/
public class Locator{
/** Access to the phone's location services */
LocationManager locManager;
/** Location providers */
List providers;
String bestProvider;
/** Providers are selected based on specified criteria.*/
Criteria criteria;
/** utility class to manage zooming of a map.*/
private MapController mapController;
/** Zoom level we want, between 1 and 21 */
private static final int ZOOM_LEVEL = 16;
/** Overlays */
private LocatorOverlay overlay;
private List mapOverlays;
/** Ctor */
public Locator(Context ctx, MapView mapView, Criteria crit){
mapController = mapView.getController();
mapController.setZoom(ZOOM_LEVEL );
// Acquire a reference to the system Location Manager
locManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
mapOverlays = mapView.getOverlays();
// our locator icon in the res/drawable folder
Drawable drawable = ctx.getResources().getDrawable(R.drawable.icon);
overlay = new LocatorOverlay(drawable, ctx);
// List all providers
providers = locManager.getAllProviders();
if(crit == null) {
// No arg Ctor means The new object will have no requirements on accuracy,
// power, or response time; will not require altitude, speed, or bearing;
// and will not allow monetary cost
criteria = new Criteria();
}
else{
criteria = crit;
}
// get the best provider for the criteria we have
bestProvider = locManager.getBestProvider(criteria, false);
}
/***/
public List listAllProviders(){
return providers;
}
/***/
public String getBestProvider(){
return bestProvider;
}
/***/
public Location getLastKnownLocation(){
return locManager.getLastKnownLocation(bestProvider);
}
//...
}
Здесь нет ничего потрясающего. Мы в основном инициализируем элементы данных, которые нам нужны, в конструкторе и инкапсулируем несколько методов LocationManager . Мы используем наши собственные иконки в ресурсах вытяжки папки ( Icon.jpg ) в качестве маркеров , чтобы точно определить местоположение телефонной трубки:
Мы уже закончили? Конечно нет. Нам все еще нужно обрабатывать обновления местоположения. Поэтому нам нужно добавить следующее:
// add import
import android.location.LocationListener;
// modify class statement
public class Locator implements LocationListener { ...
// add data members
/** Control of the frequency of location update notifications */
private static final long MIN_TIME = 20000L; // millis
private static final float MIN_DISTANCE = 100F; // meters
// add methods
/**
* No updates for MIN_TIME to conserve power.
* No updates if device doesn't move beyond MIN_DISTANCE
*
* The calling thread must be a Looper thread such as
* the main thread of the calling Activity.
*/
public void requestUpdates(){
locManager.requestLocationUpdates(bestProvider,
MIN_TIME,
MIN_DISTANCE,
this); // listener
}
/***/
public void removeUpdates(){
locManager.removeUpdates(this);
}
// add the Listener callbacks
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
/**
* Called when a new location is found by the network location provider.
* */
public void onLocationChanged(Location location) {
//TODO
}
Обратите внимание, что для метода requestUpdates () требуется LocationListener (т.е. текущий объект, теперь, когда он реализует интерфейс). Но самый интересный метод — последний. Здесь мы бы получили новое местоположение, расположили вокруг него карту и добавили несколько наложений. Чтобы перейти от точки android.location к точке Google Map, нам нужно перейти от объекта Location, где координаты имеют тип double , к объекту Google Map GeoPoint , в котором они хранятся в виде целых чисел в микро градусах :
public void onLocationChanged(Location location) {
int lat = (int) (location.getLatitude() * 1E6);
int lng = (int) (location.getLongitude() * 1E6);
GeoPoint point = new GeoPoint(lat, lng);
mapController.setCenter(point);
// overlays
OverlayItem overlayitem = new OverlayItem(point, "Location Provider: "
+ bestProvider, "Accuracy: "
+ getLastKnownLocation().getAccuracy()
+ " meters" );
overlay.addOverlay(overlayitem);
mapOverlays.add(overlay);
}
Здесь мы вводим элементы наложения, которые мы хотим, чтобы класс LocatorOverlay обрабатывал. Здесь мы добавили только один элемент наложения: поставщик местоположения по умолчанию (т. Е. Сеть) вместе с соответствующей точностью. Есть провайдеры с более высокой точностью (например, GPS), за счет увеличения потребления батареи.
![]() |
Это в основном это. Теперь мы готовы заняться последней частью, пользовательским интерфейсом с LocatorActivity … в части 4 .
Из блога Тони

