package org.r3pek.pharmacies; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; import com.google.android.maps.MapController; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; import org.r3pek.pharmacies.utils.GlobalVars; import org.r3pek.pharmacies.utils.OnPositionChangeListener; import org.r3pek.pharmacies.utils.Positioner; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import android.app.AlertDialog; import android.app.Dialog; import android.app.AlertDialog.Builder; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Handler.Callback; import android.provider.Settings; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.Toast; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class ViewOnMap extends MapActivity implements OnPositionChangeListener { private static final int MENU_REFRESH = 0; private static final int MENU_SETTINGS = 1; private static final int MENU_LIST = 2; private static final int MENU_ABOUT = 3; private static final int MENU_SETMYPOSITION = 4; private static final int MENU_GETPOSITIONFROMGPS = 5; private static final int MENU_MYPOSITION = 6; private static final int DIALOG_ABOUT = 0; private PharmaciesOverlay pharmaciesOverlay; private MyPositionOverlay myPositionOverlay; private MapView map; private ConfigValues configs; private Handler endThreadHandler; private boolean hadFirstFix; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.map); /* Create objects */ map = (MapView)findViewById(R.id.MapView); pharmaciesOverlay = new PharmaciesOverlay(getResources().getDrawable(R.drawable.pin_off), getApplicationContext(), map); GlobalVars.pharmaciesOverlay = pharmaciesOverlay; configs = new ConfigValues(getApplicationContext()); GlobalVars.positioner = new Positioner(getApplicationContext()); myPositionOverlay = new MyPositionOverlay(getApplicationContext(), map, this); GlobalVars.getPharmacies().clear(); pharmaciesOverlay.refresh(); /* Check if we have location providers enabled */ checkLocationProviders(); /* Setup the map */ map.setBuiltInZoomControls(true); map.setClickable(true); map.setEnabled(true); MapController mc = map.getController(); List mapOverlays = map.getOverlays(); mapOverlays.add(pharmaciesOverlay); mapOverlays.add(myPositionOverlay); mc.setZoom(15); /* Center view on ourselfs on first fix */ myPositionOverlay.runOnFirstFix(new Runnable() { @Override public void run() { hadFirstFix = true; GeoPoint p = GlobalVars.positioner.getLastGeoPoint(); populatePharmacies(p); map.getController().animateTo(p); runOnUiThread(new Runnable() { public void run() { Toast.makeText(getApplicationContext(), R.string.location_acquired, Toast.LENGTH_SHORT).show(); } }); } }); /* Create the handler for when we receive the Pharmacy list */ endThreadHandler = new Handler(new Callback() { @Override public boolean handleMessage(Message msg) { if (msg.what == 0) { pharmaciesOverlay.refresh(); map.postInvalidate(); map.setClickable(true); if (GlobalVars.getPharmacies().size() == 0) Toast.makeText(getApplicationContext(), R.string.not_pharmacies_returned, Toast.LENGTH_LONG).show(); } else Toast.makeText(getApplicationContext(), R.string.error_getting_pharmacies, Toast.LENGTH_SHORT).show(); return true; } }); hadFirstFix = false; } private void checkLocationProviders() { if (!GlobalVars.positioner.isLocalizationActive()) buildAlertMessageNoProviders(); } private void buildAlertMessageNoProviders() { final AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(R.string.no_localization_active) .setCancelable(false) .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { public void onClick(final DialogInterface dialog, final int id) { launchGPSOptions(); } }) .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { public void onClick(final DialogInterface dialog, final int id) { dialog.cancel(); } }); final AlertDialog alert = builder.create(); alert.show(); } private void launchGPSOptions() { final Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivity(intent); } public void onPause() { myPositionOverlay.disableMyLocation(); GlobalVars.positioner.unregisterNotification(this); GlobalVars.positioner.cancelUpdates(); super.onPause(); } public void onResume() { myPositionOverlay.enableMyLocation(); GlobalVars.positioner.registerNotification(this); GlobalVars.positioner.requestUpdates(); super.onResume(); } public boolean onCreateOptionsMenu(Menu menu) { menu.add(0, MENU_REFRESH, 0, R.string.menu_refresh).setIcon(R.drawable.refresh); menu.add(0, MENU_GETPOSITIONFROMGPS, 0, R.string.menu_get_gps_pos).setIcon(R.drawable.gps); menu.add(0, MENU_SETMYPOSITION, 0, R.string.menu_set_my_location).setIcon(android.R.drawable.ic_menu_myplaces); menu.add(0, MENU_MYPOSITION, 0, R.string.menu_my_location).setIcon(android.R.drawable.ic_menu_mylocation); menu.add(0, MENU_LIST, 0, R.string.menu_list).setIcon(android.R.drawable.ic_menu_agenda); menu.add(0, MENU_SETTINGS, 0, R.string.menu_settings).setIcon(android.R.drawable.ic_menu_preferences); menu.add(0, MENU_ABOUT, 0, R.string.menu_about).setIcon(android.R.drawable.ic_menu_info_details);; return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { menu.findItem(MENU_REFRESH).setEnabled(hadFirstFix); menu.findItem(MENU_LIST).setEnabled(GlobalVars.getPharmacies().size() > 0); if (GlobalVars.positioner.isFixedLocation()) { menu.findItem(MENU_GETPOSITIONFROMGPS).setVisible(true); menu.findItem(MENU_SETMYPOSITION).setVisible(false); } else { menu.findItem(MENU_GETPOSITIONFROMGPS).setVisible(false); menu.findItem(MENU_SETMYPOSITION).setVisible(true); } menu.findItem(MENU_MYPOSITION).setEnabled(hadFirstFix); return true; } public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case MENU_REFRESH: populatePharmacies(GlobalVars.positioner.getLastGeoPoint()); return true; case MENU_SETTINGS: startActivity(new Intent(getApplicationContext(), MyPreferences.class)); return true; case MENU_LIST: Intent i = new Intent(getApplicationContext(), PharmacyList.class); startActivity(i); return true; case MENU_ABOUT: showDialog(DIALOG_ABOUT); return true; case MENU_SETMYPOSITION: setMyLocation(); return true; case MENU_GETPOSITIONFROMGPS: getLocationFromGPS(); return true; case MENU_MYPOSITION: gotoMyLocation(); return true; } return false; } private void gotoMyLocation() { map.getController().animateTo(GlobalVars.positioner.getLastGeoPoint()); } private void setMyLocation() { List mapOverlays = map.getOverlays(); pharmaciesOverlay.removeBallon(); mapOverlays.clear(); Handler h = new Handler(new Callback() { @Override public boolean handleMessage(Message msg) { hadFirstFix = true; GlobalVars.getPharmacies().clear(); pharmaciesOverlay.refresh(); populatePharmacies(GlobalVars.positioner.getLastGeoPoint()); return true; } }); mapOverlays.add(new GetPositionOverlay(null, pharmaciesOverlay, myPositionOverlay, h)); map.postInvalidate(); Toast.makeText(getApplicationContext(), R.string.tap_on_screen, Toast.LENGTH_LONG).show(); } private void getLocationFromGPS() { hadFirstFix = false; GlobalVars.positioner.cancelFixedLocation(); GlobalVars.getPharmacies().clear(); pharmaciesOverlay.refresh(); map.postInvalidate(); Toast.makeText(getApplicationContext(), R.string.now_from_GPS, Toast.LENGTH_SHORT).show(); } public void populatePharmacies(final GeoPoint curPos) { Runnable r = new Runnable() { @Override public void run() { String service = configs.isOnlyService() ? "GetPharmaciesAtServiceByCoordinates" : "GetPharmaciesByCoordinates"; try { URL url = new URL("http://services.sapo.pt/Pharmacy/" + service + "?latitude=" + (curPos.getLatitudeE6() / 1E6) + "&longitude=" + (curPos.getLongitudeE6() / 1E6) + "&radius=" + configs.getRadius()); /* Get a SAXParser from the SAXPArserFactory. */ SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); /* Get the XMLReader of the SAXParser we created. */ XMLReader xr = sp.getXMLReader(); /* Create a new ContentHandler and apply it to the XML-Reader*/ XMLParserHandler handler = new XMLParserHandler(); xr.setContentHandler(handler); /* Parse the xml-data from our URL. */ xr.parse(new InputSource(url.openStream())); /* Parsing has finished. */ GlobalVars.getPharmacies().clear(); pharmaciesOverlay.refresh(); /* Check if server returned an error */ if (handler.getPharmacies() == null) { endThreadHandler.sendEmptyMessage(1); return; } /* Our XMLParserHandler now provides the parsed data to us. */ for (Pharmacy p : handler.getPharmacies()) { /* Only add the Pharmacy if it was recently updated */ DateFormat format; if (p.getLastupdate().endsWith("Z")) format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); else format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); Date lastupdate = format.parse(p.getLastupdate()); Calendar cal = Calendar.getInstance(); cal.add(Calendar.DATE, -2); if (!lastupdate.before(cal.getTime())) GlobalVars.getPharmacies().add(p); } pharmaciesOverlay.refresh(); endThreadHandler.sendEmptyMessage(0); } catch (Exception e) { endThreadHandler.sendEmptyMessage(1); } } }; Thread t = new Thread(r); t.start(); } @Override protected boolean isRouteDisplayed() { return false; } public Dialog onCreateDialog(int id) { Dialog d; switch (id) { case DIALOG_ABOUT: { LayoutInflater inflater = (LayoutInflater)getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE); View layout = inflater.inflate(R.layout.about, (ViewGroup)findViewById(R.id.aboutRoot)); ImageView image = (ImageView)layout.findViewById(R.id.ImageView01); image.setImageResource(R.drawable.icon); Builder builder = new AlertDialog.Builder(this); builder.setView(layout); d = builder.create(); break; } default: d = null; } return d; } @Override public void onLocationChange(GeoPoint currentPos, float accuracy) { if (!hadFirstFix) { map.getController().animateTo(currentPos); populatePharmacies(currentPos); hadFirstFix = true; } map.postInvalidate(); } }