问题
I am trying to implement the MyLocationOverlay class from google maps. However, when I try and use my own locationManager -- I cannot get the overlay to acutally draw on the map. I am wondering if I am doing something wrong.
I don't want to call the super method(enbaleMyLocation) of the MyLocationOverlay class because that request updates from the locationManager way too quickly and will eat my battery alive.
Here is my code:
private class CenterOverlay extends MyLocationOverlay {
private Context mContext;
private LocationManager mLocManager;
public CenterOverlay(Context context, MapView mapView) {
super(context, mapView);
this.mContext = context;
}
@Override
public void onLocationChanged(Location location) {
super.onLocationChanged(location);
try {
doExternalCenterOverlayTask(location);
} catch (JSONException e) {
e.printStackTrace();
ErrorHandler.serviceException(mContext);
} catch (IOException e) {
e.printStackTrace();
ErrorHandler.IOException(mContext);
} catch (ServiceException e) {
e.printStackTrace();
ErrorHandler.serviceException(mContext);
}
}
@Override
public boolean enableMyLocation() {
mLocManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
mLocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 50, this);
mLocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 25, this);
return mLocManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|| mLocManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
@Override
public void disableMyLocation() {
super.disableMyLocation();
mLocManager.removeUpdates(this);
}
@Override
public void onProviderDisabled(String provider) {
super.onProviderDisabled(provider);
ViewAdapter.createStandardAlertDialog(mContext,
"Your location provider has been disabled, please re-enable it.");
}
@Override
public void onProviderEnabled(String provider) {
super.onProviderEnabled(provider);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
super.onStatusChanged(provider, status, extras);
if (status == 0) {
ViewAdapter.showLongToast(mContext, "Location is not available at this time");
} else if (status == 1) {
//Trying to connect
} else if (status == 2) {
// Available
}
}
}
回答1:
I have gotten to the bottom of this and it is not possible to do until Google feels like updating their code.
Instead, I've created my own class that draws the location for me -- that can be updated whenever you like.
Code for that is here.
/**
*
* @author (hwrdprkns)
* 2010
*
*/
public class CenterOverlay extends ItemizedOverlay<OverlayItem> implements LocationListener {
private static final String TAG = "CenterOverlay: ";
private LocationManager mLocationManager;
private long updateTime = 60000;
private static final int updateDistance = 50;
private GeoPoint lastKnownPoint;
private Location lastKnownLocation;
private Drawable centerDrawable;
private Context mContext;
private final List<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
private Paint accuracyPaint;
private Point center;
private Point left;
private Drawable drawable;
private int width;
private int height;
// San Francisco
private final static double[] DEFAULT_LOCATION = {
37.7749295, -122.4194155
};
private Runnable firstFixRunnable = null;
private boolean firstFixRun = false;
public CenterOverlay(Drawable defaultMarker, MapView mapView, Context c) {
super(boundCenter(defaultMarker));
this.centerDrawable = defaultMarker;
this.mContext = c;
mLocationManager = (LocationManager) c.getSystemService(Context.LOCATION_SERVICE);
if (Constants.DEBUG) {
updateTime = 0;
} else {
updateTime = 60000;
}
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
private void checkFirstRunnable() {
if (!firstFixRun && lastKnownLocation != null && firstFixRunnable != null) {
firstFixRunnable.run();
}
}
private OverlayItem createCenterOverlay(GeoPoint point) {
OverlayItem i = new OverlayItem(point, "Location", null);
i.setMarker(centerDrawable);
return i;
}
private GeoPoint createGeoPoint(Location loc) {
int lat = (int) (loc.getLatitude() * 1E6);
int lng = (int) (loc.getLongitude() * 1E6);
return new GeoPoint(lat, lng);
}
@Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
public void disableLocation() {
mLocationManager.removeUpdates(this);
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
drawMyLocation(canvas, mapView, lastKnownLocation, lastKnownPoint, 0);
}
protected void drawMyLocation(Canvas canvas, MapView mapView, Location lastFix, GeoPoint myLoc,
long when) {
accuracyPaint = new Paint();
accuracyPaint.setAntiAlias(true);
accuracyPaint.setStrokeWidth(2.0f);
drawable = centerDrawable;
width = drawable.getIntrinsicWidth();
height = drawable.getIntrinsicHeight();
center = new Point();
left = new Point();
Projection projection = mapView.getProjection();
double latitude = lastFix.getLatitude();
double longitude = lastFix.getLongitude();
float accuracy = lastFix.getAccuracy();
float[] result = new float[1];
Location.distanceBetween(latitude, longitude, latitude, longitude + 1, result);
float longitudeLineDistance = result[0];
GeoPoint leftGeo = new GeoPoint((int) (latitude * 1e6), (int) ((longitude - accuracy
/ longitudeLineDistance) * 1e6));
projection.toPixels(leftGeo, left);
projection.toPixels(myLoc, center);
int radius = center.x - left.x;
accuracyPaint.setColor(0xff6666ff);
accuracyPaint.setStyle(Style.STROKE);
canvas.drawCircle(center.x, center.y, radius, accuracyPaint);
accuracyPaint.setColor(0x186666ff);
accuracyPaint.setStyle(Style.FILL);
canvas.drawCircle(center.x, center.y, radius, accuracyPaint);
drawable.setBounds(center.x - width / 2, center.y - height / 2, center.x + width / 2,
center.y + height / 2);
drawable.draw(canvas);
}
public void enableMyLocation() {
for (String s : mLocationManager.getProviders(true)) {
mLocationManager.requestLocationUpdates(s, updateTime, updateDistance, this);
}
Location loc = null;
for (String s : mLocationManager.getProviders(true)) {
loc = mLocationManager.getLastKnownLocation(s);
if (loc != null) {
loc.setLatitude(DEFAULT_LOCATION[0]);
loc.setLongitude(DEFAULT_LOCATION[1]);
lastKnownLocation = loc;
lastKnownPoint = createGeoPoint(loc);
return;
}
}
loc = new Location(LocationManager.GPS_PROVIDER);
loc.setLatitude(DEFAULT_LOCATION[0]);
loc.setLongitude(DEFAULT_LOCATION[1]);
lastKnownLocation = loc;
lastKnownPoint = createGeoPoint(loc);
}
public Location getLastKnownLocation() {
return lastKnownLocation;
}
public GeoPoint getLastKnownPoint() {
return lastKnownPoint;
}
public void onLocationChanged(Location location) {
checkFirstRunnable();
this.lastKnownLocation = location;
this.lastKnownPoint = createGeoPoint(location);
replaceOverlay(createCenterOverlay(lastKnownPoint));
}
public void onProviderDisabled(String provider) {
ViewAdapter.showLongToast(mContext,
"Your location provider has been disabled -- please reenable it");
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
if (status == LocationProvider.AVAILABLE) {
}
if (status == LocationProvider.OUT_OF_SERVICE) {
ViewAdapter.showShortToast(mContext, "Location is temporarily out of service.");
}
if (status == LocationProvider.TEMPORARILY_UNAVAILABLE) {
}
}
private void replaceOverlay(OverlayItem overlay) {
mOverlays.clear();
mOverlays.add(overlay);
populate();
}
public boolean runOnFirstFix(Runnable runnable) {
if (lastKnownLocation != null) {
runnable.run();
return true;
}
firstFixRunnable = runnable;
return false;
}
@Override
public int size() {
return mOverlays.size();
}
public void updateLocation() {
}
}
回答2:
You're not adding the overlays to your mapView anywhere in your code. I.e. like mapView.getOverlays().add(centerOverlay);
That would usually happen outside the class you posted. Can you post the rest of the code of your activity that's relevant.
btw: The class (CenterOverlay) has a different name than your constructor (TaggstrCenterOverlay)... is that correct?
来源:https://stackoverflow.com/questions/3460661/customize-my-location-overlay-update-times