2010-08-11 85 views
0

我正試圖從谷歌地圖實現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 
     } 

    } 

} 

回答

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

} 

}

+0

謝謝你的帖子,我似乎無法讓它工作,但它崩潰了「GeoPoint leftGeo = new GeoPoint(」。我剛創建一個新的CenterOverlay對象,在新創建的對象上調用enableMyLocation(),然後將對象添加到疊加層mapView.getOverlays()。add(obj)。我做錯了什麼?提前謝謝! – Dr1Ku 2010-11-24 00:33:01

1

你不添加覆蓋到你的MapView在你的代碼的任何地方。即像mapView.getOverlays().add(centerOverlay);

這通常會發生在您發佈的課程之外。你可以發佈你的活動相關的其他代碼嗎?

btw:類(CenterOverlay)與您的構造函數(TaggstrCenterOverlay)具有不同的名稱...是否正確?

+0

它不應該的問題 - 我從字面上添加就像你把你的代碼覆蓋'調用MapView.getOverlays()加(centerOverlay)'我不知道爲什麼它不當我沒有打電話給超級方法的時候沒有出現。 是否有某種方式可以檢查Android代碼的Google地圖(儘管我認爲不是)。 – hwrdprkns 2010-08-11 21:13:44

+0

你的意思是超級方法,super(context,mapView);?上面的類繼承自MyLocationOverlay,它也是一個自定義類,而不是SDK。而且你在上面發佈的課程中沒有任何繪製方法。您可以請發佈課程包括繪製方法(MyLocationOverlay)。 – 2010-08-12 01:04:03

+0

'MyLocationOverlay'(http://bit.ly/dBIVdj)不是一個自定義類(至少在我認爲你說的方式)。它來自GoogleMaps SDK。 – hwrdprkns 2010-08-13 01:31:31