В первой части мы проанализировали наши требования и имеющиеся в нашем распоряжении инструменты, чтобы получить первоначальный дизайн приложения.
Во второй части мы реализовали 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 .
Из блога Тони