Статьи

Расположение Android с помощью Google Maps – часть 3

В первой части мы проанализировали наши требования и имеющиеся в нашем распоряжении инструменты, чтобы получить первоначальный дизайн приложения.

 

 

 Во второй части мы реализовали  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 .

 

Из блога Тони