views:

150

answers:

2

Hello,

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  A: 

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?

Mathias Lin
It shouldn't matter -- I literally add the overlay just like you put in your code `mapView.getOverlays().add(centerOverlay)` I don't know why it doesn't show up when I don't call the super method.Is there some way I can examine the google maps for android code (although I think not).
hwrdprkns
which super method you mean, super(context, mapView);? The class above extends from MyLocationOverlay, which is a custom class as well,not the SDK one. And you don't have the draw-method anywhere in your above posted class. Can you please post the class the includes the draw method (MyLocationOverlay).
Mathias Lin
`MyLocationOverlay`(http://bit.ly/dBIVdj) is not a custom class(at least in the way I think your speaking). Its from the GoogleMaps SDK.
hwrdprkns
oh yes, you're right. Never used that one, I use a class extended only from Overlay for the current location display. nevermind then.
Mathias Lin
Regardless -- I need someway to display a dot at a centerPoint -- (preferably with MyLocationOverlay) and then request that that dot be updated as often as I want it to. I think I might have to use a different parent class.
hwrdprkns
A: 

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() {

}

}

hwrdprkns