package org.r3pek.pharmacies; import java.util.Timer; import java.util.TimerTask; import org.r3pek.pharmacies.utils.GeoUtils; import org.r3pek.pharmacies.utils.GlobalVars; import org.r3pek.pharmacies.utils.OnPositionChangeListener; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Point; import android.graphics.Paint.Style; import android.graphics.drawable.Drawable; import android.graphics.drawable.LevelListDrawable; import android.os.Handler; import android.os.Message; import android.os.Handler.Callback; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; import com.google.android.maps.Projection; import com.google.android.maps.MapView.LayoutParams; public class MyPositionOverlay extends Overlay implements OnPositionChangeListener { private static final float dotScale = 0.6f; private MapView map; private Runnable runOnFirstFix; private boolean isFirstFix; private LevelListDrawable netLocationImage; private LevelListDrawable gpsLocationImage; private Timer updateDotTask; private Context context; private View shownView; private Activity mapActivity; public MyPositionOverlay(Context ctx, MapView mapView, Activity mapActivity) { super(); map = mapView; this.mapActivity = mapActivity; GlobalVars.positioner.registerNotification(this); isFirstFix = true; context = ctx; netLocationImage = (LevelListDrawable) ctx.getResources().getDrawable(R.drawable.network_fix); gpsLocationImage = (LevelListDrawable) ctx.getResources().getDrawable(R.drawable.gps_fix); updateDotTask = new Timer(); TimerTask tt = new TimerTask() { @Override public void run() { if (GlobalVars.positioner.isGPSFix()) return; int current = netLocationImage.getLevel(); current = (current + 1) % 4; netLocationImage.setLevel(current); map.postInvalidate(); } }; updateDotTask.scheduleAtFixedRate(tt, 100, 500); } @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { if (shadow || isFirstFix) return; if (GlobalVars.positioner.getLastGeoPoint() == null) return; Projection projection = mapView.getProjection(); Point point = new Point(); projection.toPixels(GlobalVars.positioner.getLastGeoPoint(), point); // Draw the accuracy circle float radius = projection.metersToEquatorPixels(GlobalVars.positioner.getLastAccuracy()); canvas.save(); Paint circlePaint = new Paint(); circlePaint.setStyle(Style.FILL); circlePaint.setARGB(10, 0, 0, 255); canvas.drawCircle(point.x, point.y, radius, circlePaint); circlePaint.setARGB(200, 0, 0, 255); circlePaint.setStyle(Style.STROKE); canvas.drawCircle(point.x, point.y, radius, circlePaint); canvas.restore(); // Draw in the right spot Drawable d = GlobalVars.positioner.isGPSFix() ? gpsLocationImage.getCurrent() : netLocationImage.getCurrent(); int scaledImageWidth = (int)(d.getIntrinsicWidth() * dotScale); int scaledImageHeight = (int)(d.getIntrinsicHeight() * dotScale); float scaledImageCenterX = scaledImageWidth / 2; float scaledImageCenterY = scaledImageHeight / 2; canvas.save(); canvas.translate(-(scaledImageCenterX - point.x), -(scaledImageCenterY - point.y)); d.setBounds(0, 0, scaledImageWidth, scaledImageHeight); d.getCurrent().draw(canvas); canvas.restore(); super.draw(canvas, mapView, shadow); } @Override public void onLocationChange(GeoPoint currentPos, float accuracy) { if (isFirstFix) { isFirstFix = false; runOnFirstFix.run(); } map.postInvalidate(); } public void disableMyLocation() { GlobalVars.positioner.unregisterNotification(this); } public void enableMyLocation() { GlobalVars.positioner.registerNotification(this); } public void runOnFirstFix(Runnable r) { runOnFirstFix = r; } @Override public boolean onTap(GeoPoint p, MapView map) { Point pointTap = map.getProjection().toPixels(p, null); Point pointMap = map.getProjection().toPixels(GlobalVars.positioner.getLastGeoPoint(), null); if (Math.abs(pointTap.x - pointMap.x) <= 20 && Math.abs(pointMap.y - pointTap.y) <= 20 && shownView == null) { LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); LinearLayout ll = (LinearLayout)inflater.inflate(R.layout.mylocation_balloon, null); LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, GlobalVars.positioner.getLastGeoPoint(), 0, -35, LayoutParams.MODE_MAP | LayoutParams.CENTER); final TextView tvLocation = (TextView)ll.findViewById(R.id.tvLocation); tvLocation.setText(context.getString(R.string.loading)); map.getController().animateTo(GlobalVars.positioner.getLastGeoPoint()); map.addView(ll, lp); shownView = ll; GeoUtils.getLocationName(context, new Handler(new Callback() { @Override public boolean handleMessage(Message msg) { final String location = msg.getData().getString("location"); mapActivity.runOnUiThread(new Runnable() { @Override public void run() { tvLocation.setText(location); } }); return true; } })); } else if (shownView != null) { map.removeView(shownView); shownView = null; } return super.onTap(p, map); } }