Java tutorial
/* * This file is subject to the terms and conditions defined in * file 'LICENSE', which is part of this source code package. */ package com.eyekabob; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.Toast; import com.eyekabob.adapters.EventListAdapter; import com.eyekabob.models.Event; import com.eyekabob.models.Venue; import com.eyekabob.util.EyekabobHelper; import com.eyekabob.util.JSONTask; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; public class EventList extends EyekabobActivity { // A map whose keys are zip codes and values are lat/long values delimited by "|" // An example entry would be: {"50210":"42.5239|83.2233"} private static final Map<String, String> zipToGeoMap = new HashMap<String, String>(); EventListAdapter adapter; private OnItemClickListener listItemListener = new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Event event = (Event) parent.getAdapter().getItem(position); Intent intent = new Intent(getApplicationContext(), EventInfo.class); intent.putExtra("event", event); startActivity(intent); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.adlistactivity); adapter = new EventListAdapter(getApplicationContext()); ListView lv = (ListView) findViewById(R.id.adList); lv.setAdapter(adapter); Uri uri = this.getIntent().getData(); if (getIntent().hasExtra("zip")) { // Search by zip. String zip = getIntent().getExtras().getString("zip"); if (zip != null) { zip = zip.trim(); } if (zipToGeoMap.containsKey(zip)) { Log.d(getClass().getName(), "Using cached zip"); String[] latLong = zipToGeoMap.get(zip).split("\\|"); Uri lastFMURI = getLastFMURI(latLong[0], latLong[1]); sendLastFMRequest(lastFMURI.toString()); } else { Log.d(getClass().getName(), "Getting zip from geonames service"); sendJSONRequest(uri.toString()); } } else if (getIntent().hasExtra("city")) { // Search by city/state. String city = getIntent().getExtras().getString("city"); String encodedCity; try { encodedCity = URLEncoder.encode(city, "UTF-8"); } catch (UnsupportedEncodingException e) { Log.e(getClass().getName(), "Problem with city", e); return; } String state = getIntent().getExtras().getString("state"); Map<String, String> params = new HashMap<String, String>(); params.put("address", encodedCity + "," + state); Uri googleURI = EyekabobHelper.GoogleMaps.getURI(params); sendMapsRequest(googleURI.toString()); } else { Log.d(getClass().getName(), "Searching for events using current location"); sendLastFMRequest(uri.toString()); } lv.setOnItemClickListener(listItemListener); } @Override public void onDestroy() { adapter.clearCache(); super.onDestroy(); } protected void loadEvents(JSONObject response) { try { JSONObject jsonEvents = response.optJSONObject("events"); if (jsonEvents == null) { Toast.makeText(getApplicationContext(), R.string.no_results, Toast.LENGTH_LONG).show(); return; } Object eventsObj = jsonEvents.get("event"); JSONArray events; if (eventsObj instanceof JSONArray) { events = (JSONArray) eventsObj; } else { // For some incredibly stupid reason, a one item list is not a list. // So create a list and stick the one item in it. events = new JSONArray(); events.put(eventsObj); } for (int i = 0; i < events.length(); i++) { Event event = new Event(); Venue venue = new Venue(); event.setVenue(venue); JSONObject jsonEvent = events.getJSONObject(i); JSONObject jsonVenue = jsonEvent.getJSONObject("venue"); JSONObject jsonLocation = jsonVenue.getJSONObject("location"); JSONObject jsonGeo = jsonLocation.optJSONObject("geo:point"); event.setId(jsonEvent.getString("id")); event.setName(jsonEvent.getString("title")); event.setDate(EyekabobHelper.LastFM.toReadableDate(jsonEvent.getString("startDate"))); JSONObject jsonImage = EyekabobHelper.LastFM.getJSONImage("large", jsonEvent.getJSONArray("image")); event.addImageURL("large", jsonImage.getString("#text")); venue.setName(jsonVenue.getString("name")); venue.setCity(jsonLocation.getString("city")); if (jsonGeo != null) { venue.setLat(jsonGeo.optString("geo:lat")); venue.setLon(jsonGeo.getString("geo:long")); } adapter.add(event); } } catch (JSONException e) { Log.e(getClass().getName(), "", e); } } protected void sendJSONRequest(String uri) { new GeoNamesJSONRequestTask().execute(uri); } protected void sendLastFMRequest(String uri) { new LastFMRequestTask().execute(uri); } protected void sendMapsRequest(String uri) { new GoogleRequest().execute(uri); } protected Uri getLastFMURI(String latitude, String longitude) { Map<String, String> params = new HashMap<String, String>(); params.put("lat", latitude); params.put("long", longitude); String distance = getIntent().getExtras().getString("distance"); if (distance != null) { params.put("distance", distance); } return EyekabobHelper.LastFM.getUri("geo.getEvents", params); } public void adHandler(View v) { EyekabobHelper.launchEmail(this); } /** * Sends request to the GeoNames service to get information about * a given ZIP code. The pieces of information this app uses are * latitude and longitude of a given zip. */ private class GeoNamesJSONRequestTask extends JSONTask { protected void onPreExecute() { EventList.this.createDialog(R.string.searching); EventList.this.showDialog(); } protected void onPostExecute(JSONObject result) { String latitude; String longitude; try { JSONArray locations = (JSONArray) result.get("postalcodes"); JSONObject jsonLocation = (JSONObject) locations.get(0); latitude = jsonLocation.getString("lat"); longitude = jsonLocation.getString("lng"); String zip = jsonLocation.getString("postalcode"); zipToGeoMap.put(zip, latitude + "|" + longitude); } catch (JSONException e) { Log.e(getClass().getName(), "Unable to get geo information for zip", e); Toast.makeText(EventList.this, R.string.zip_error, Toast.LENGTH_LONG).show(); return; } Uri uri = EventList.this.getLastFMURI(latitude, longitude); EventList.this.sendLastFMRequest(uri.toString()); } } // Handles the asynchronous request, away from the UI thread. private class LastFMRequestTask extends JSONTask { protected void onPreExecute() { EventList.this.createDialog(R.string.searching); EventList.this.showDialog(); } protected void onPostExecute(JSONObject result) { EventList.this.dismissDialog(); EventList.this.loadEvents(result); } } private class GoogleRequest extends JSONTask { protected void onPreExecute() { EventList.this.createDialog(R.string.searching); EventList.this.showDialog(); } protected void onPostExecute(JSONObject result) { String latitude; String longitude; try { JSONArray results = result.getJSONArray("results"); // Assume only one result. JSONObject firstResult = results.getJSONObject(0); JSONObject geometry = firstResult.getJSONObject("geometry"); JSONObject location = geometry.getJSONObject("location"); latitude = location.getString("lat"); longitude = location.getString("lng"); } catch (JSONException e) { Log.e(getClass().getName(), "Unable to get lat/lon for city", e); Toast.makeText(EventList.this, R.string.city_error, Toast.LENGTH_LONG).show(); return; } Uri uri = EventList.this.getLastFMURI(latitude, longitude); EventList.this.sendLastFMRequest(uri.toString()); } } }