【问题标题】:Customize My Location Overlay Update Times自定义我的位置覆盖更新时间
【发布时间】:2010-08-11 16:36:30
【问题描述】:

我正在尝试从谷歌地图实现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
        }

    }

}

【问题讨论】:

    标签: android google-maps overlay


    【解决方案1】:

    我已经弄清了这个问题,在 Google 想要更新他们的代码之前,这是不可能的。

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

    代码在这里。

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

    }

    【讨论】:

    • 感谢您的帖子,但我似乎无法让它工作,它在“GeoPoint leftGeo = new GeoPoint(”周围崩溃。我刚刚创建了一个新的 CenterOverlay 对象,名为 enableMyLocation()在新创建的对象上,然后将该对象添加到叠加层 mapView.getOverlays().add(obj)。我做错了吗?提前谢谢!
    【解决方案2】:

    您不会在代码中的任何位置将叠加层添加到您的 mapView 中。 IE。喜欢mapView.getOverlays().add(centerOverlay);

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

    顺便说一句:类 (CenterOverlay) 的名称与您的构造函数 (TaggstrCenterOverlay) 的名称不同...对吗?

    【讨论】:

    • 没关系——我真的添加了覆盖,就像你在代码中输入的那样mapView.getOverlays().add(centerOverlay) 我不知道为什么当我不调用超级时它不显示方法。有什么方法可以检查 google 地图的 android 代码吗(虽然我不这么认为)。
    • 你的意思是哪个超级方法,super(context, mapView);?上面的类扩展自 MyLocationOverlay,它也是一个自定义类,而不是 SDK 类。而且您在上面发布的课程中的任何地方都没有绘制方法。您能否发布包含绘图方法(MyLocationOverlay)的课程。
    • MyLocationOverlay(bit.ly/dBIVdj) 不是自定义类(至少在我认为你说话的方式上)。它来自 GoogleMaps SDK。
    • 哦,是的,你是对的。从未使用过那个,我使用仅从 Overlay 扩展的类来显示当前位置。那没关系。
    • 无论如何——我需要以某种方式在中心点显示一个点——(最好使用 MyLocationOverlay),然后请求按我想要的频率更新该点。我想我可能不得不使用不同的父类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-13
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多