自定义我的位置叠加更新时间

时间:2010-08-11 16:36:30

标签: android google-maps overlay

我正在尝试从谷歌地图实施MyLocationOverlay类。但是,当我尝试使用我自己的locationManager时 - 我无法在地图上实际绘制叠加层。我想知道我做错了什么。

我不想调用MyLocationOverlay类的超级方法(enbaleMyLocation),因为该请求从locationManager方式更新太快,并且会耗尽我的电池。

这是我的代码:

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
        }

    }

}

2 个答案:

答案 0 :(得分:5)

我已经深究这一点,直到谷歌感觉要更新他们的代码才能做到这一点。

相反,我创建了自己的类来为我绘制位置 - 可以随时更新。

代码就在这里。

/**
* 
* @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() {

}

}

答案 1 :(得分:1)

您不会在代码中的任何位置向地图查看添加叠加层。即比如mapView.getOverlays().add(centerOverlay);

这通常发生在您发布的课程之外。您是否可以发布与您相关的活动代码的其余部分。

btw:类(CenterOverlay)的名称与构造函数不同(TaggstrCenterOverlay)......是正确的吗?