title: Android - Multilevel Listviews
body: <p>I am relatively new to Android and working with an online API. I have two activities. The first activity is bringing up a list of search results and placing them into a ListView. This is not a problem. I am trying to select an item from this ListView and pass it to the next activity and fill another ListView in this new activity with information from the selected item. This is where the problem is. The second activity never loads. What is a good way to get the second activity to work? I have been doing research and not getting the desired results. The code for the two activities and helper class are below.
  Thank you</p>
  
  <p>The first activity</p>
  
  <pre><code>import helper.ArtistCalendarHelper;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.w3c.dom.NodeList;
  
  import services.XMLParser;
  
  import android.app.ListActivity;
  import android.app.ProgressDialog;
  import android.content.Intent;
  import android.os.AsyncTask;
  import android.os.Bundle;
  import android.util.Log;
  import android.view.View;
  import android.widget.AdapterView;
  import android.widget.ListAdapter;
  import android.widget.ListView;
  import android.widget.SimpleAdapter;
  import android.widget.TextView;
  import android.widget.AdapterView.OnItemClickListener;
  
  public class ArtistsSearchActivity extends ListActivity {
  
  public static final String TAG = "ArtistsSearchActivity";
  public static final String INTENT_EXTRAS_XML = "XML";
  
  static final String KEY_ARTISTS = "artist";
  static final String KEY_ID = "id";
  static final String KEY_DISPLAY_NAME = "displayName";
  static final String KEY_URI = "uri";
  static final String KEY_ON_TOUR_UNTIL = "onTourUntil";
  String onTourUntil ;
  String displayName;
  String identification;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_artists_search);
  
      String xml = getIntent().getStringExtra(HomeActivity.INTENT_EXTRAS_XML);
  
      List&lt;HashMap&lt;String, String&gt;&gt; menuItems = new ArrayList&lt;HashMap&lt;String, String&gt;&gt;();
  
      addArtistsToHashmap(menuItems, xml);
      addItemsToList(menuItems);
  }
  
  private void addItemsToList(List&lt;HashMap&lt;String, String&gt;&gt; menuItems) {
      ListAdapter adapter = new SimpleAdapter(this, menuItems,
              R.layout.list_item_artist_search, new String[] { KEY_ID, KEY_DISPLAY_NAME,
                      KEY_URI, KEY_ON_TOUR_UNTIL }, new int[] { R.id.tvId,
                      R.id.tvDisplayName, R.id.tvUri, R.id.tvOnTourUntil });
  
      setListAdapter(adapter);
  }
  
  private void addArtistsToHashmap(List&lt;HashMap&lt;String, String&gt;&gt; menuItems,
          String xml) {
      XMLParser parser = new XMLParser();
  
      Document doc = parser.getDomElement(xml);
  
      NodeList nl = doc.getElementsByTagName(KEY_ARTISTS);
      for (int i = 0; i &lt; nl.getLength(); i++) {
          HashMap&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();
          Element e = (Element) nl.item(i);
  
          map.put(KEY_ID, e.getAttribute(KEY_ID));
          map.put(KEY_DISPLAY_NAME, e.getAttribute(KEY_DISPLAY_NAME));
          map.put(KEY_URI, e.getAttribute(KEY_URI));
          map.put(KEY_ON_TOUR_UNTIL, e.getAttribute(KEY_ON_TOUR_UNTIL));
  
          menuItems.add(map);
      }
  
  // selecting single ListView item
          ListView lv = getListView();
  
          lv.setOnItemClickListener(new OnItemClickListener() {
  
              @Override
              public void onItemClick(AdapterView&lt;?&gt; parent, View view,
                      int position, long id) {
                  // getting values from selected ListItem
                  displayName = ((TextView) view.findViewById(R.id.tvDisplayName)).getText().toString();
                  onTourUntil = ((TextView) view.findViewById(R.id.tvOnTourUntil)).getText().toString();
                  identification = ((TextView) view.findViewById(R.id.tvId)).getText().toString();
  
                  new AsyncDownload().execute(identification);
              }
          });
  }
  
  private class AsyncDownload extends AsyncTask&lt;String, String, String&gt; {
  
      ProgressDialog pDialog;
  
      @Override
      protected void onPreExecute() {
          super.onPreExecute();
          pDialog = new ProgressDialog(ArtistsSearchActivity.this);
          pDialog.setMessage("Please Wait...");
  
          pDialog.setCancelable(false);
          pDialog.show();
      }
  
      @Override
      protected String doInBackground(String... params) {
  
          Log.v(TAG, "query is" +  params[0]);
          String result = new ArtistCalendarHelper().getXml(params[0]);
          return result;
      }
  
      @Override
      protected void onCancelled() {
          super.onCancelled();
          pDialog.dismiss();
      }
  
      @Override
      protected void onPostExecute(String result) {
          super.onPostExecute(result);
          pDialog.dismiss();
          Log.v(TAG, "result=" + result);
          Intent intent = new Intent();
          intent.setClass(ArtistsSearchActivity.this, SingleArtistActivity.class);
          intent.putExtra(KEY_DISPLAY_NAME, displayName);
          intent.putExtra(KEY_ID, identification);
          intent.putExtra(KEY_ON_TOUR_UNTIL, onTourUntil);
          intent.putExtra(INTENT_EXTRAS_XML, result);
          startActivity(intent);
      }
  }
  }
  </code></pre>
  
  <p>The second activity</p>
  
  <pre><code>import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  
  import org.w3c.dom.Document;
  import org.w3c.dom.Element;
  import org.w3c.dom.NodeList;
  
  import services.XMLParser;
  
  import android.os.Bundle;
  import android.app.Activity;
  import android.app.ListActivity;
  import android.content.Intent;
  import android.widget.ListAdapter;
  import android.widget.SimpleAdapter;
  import android.widget.TextView;
  
  
  public class SingleArtistActivity extends ListActivity {
  
  public static final String TAG = "SingleArtistActivity";
  public static final String INTENT_EXTRAS_XML = "XML";
  
  static final String KEY_VENUE = "event";
  static final String KEY_VENUE_NAME = "displayName";
  
      static final String KEY_DISPLAY_NAME = "displayName";
      static final String KEY_ON_TOUR_UNTIL = "onTourUntil";
      static final String KEY_ID = "id";
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_single_artist);
  
          // getting intent data
          Intent in = getIntent();
  
          // Get XML values from previous intent
          String displayName = in.getStringExtra(KEY_DISPLAY_NAME);
          String onTourUntil = in.getStringExtra(KEY_ON_TOUR_UNTIL);
          String id = in.getStringExtra(KEY_ID);
  
          // Displaying all values on the screen
          TextView lblDisplayName = (TextView) findViewById(R.id.display_name_label);
          TextView lblOnTourUntil = (TextView) findViewById(R.id.on_tour_until_label);
          TextView lblID = (TextView) findViewById(R.id.id_label);
  
          lblDisplayName.setText(displayName);
          lblOnTourUntil.setText(onTourUntil);
          lblID.setText(id);
  
          String xml = getIntent().getStringExtra(HomeActivity.INTENT_EXTRAS_XML);
  
          List&lt;HashMap&lt;String, String&gt;&gt; menuItems = new ArrayList&lt;HashMap&lt;String, String&gt;&gt;();
  
  
          addItemsToList(menuItems);   
          addCalendarToHashmap(menuItems, xml);
      }
  
      private void addItemsToList(List&lt;HashMap&lt;String, String&gt;&gt; menuItems) {
          ListAdapter adapter = new SimpleAdapter(this, menuItems,
                  R.layout.list_item_artist_calendar, new String[] { KEY_VENUE_NAME }, new int[] { R.id.calendarDisplayName });
  
          setListAdapter(adapter);
      }
  
      private void addCalendarToHashmap(List&lt;HashMap&lt;String, String&gt;&gt; menuItems,
              String xml) {
          XMLParser parser = new XMLParser();
  
          Document doc = parser.getDomElement(xml);
  
          NodeList nl = doc.getElementsByTagName(KEY_VENUE);
          for (int i = 0; i &lt; nl.getLength(); i++) {
              HashMap&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();
              Element e = (Element) nl.item(i);
  
              map.put(KEY_VENUE_NAME, e.getAttribute(KEY_VENUE_NAME));
  
              menuItems.add(map);
          }
      }
  }
  </code></pre>
  
  <p>And the my helper class</p>
  
  <pre><code>import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.io.UnsupportedEncodingException;
  import java.net.URLEncoder;
  
  import org.apache.http.HttpEntity;
  import org.apache.http.HttpResponse;
  import org.apache.http.client.HttpClient;
  import org.apache.http.client.methods.HttpGet;
  import org.apache.http.impl.client.DefaultHttpClient;
  
  import android.util.Log;
  
  public class LocationCalendarHelper {
  private static final String TAG = "LocationCalendarHelper";
  private static final String SONGKICK_URL = "http://api.songkick.com/api/3.0/metro_areas/";
  private static final String API_KEY = "yIekMi1hQzcFheKc";
  
  public String getXml(String searchQuery) {
  
      HttpClient httpclient = new DefaultHttpClient();
  
      String getParameters = "";
      try {
          getParameters =  URLEncoder.encode(searchQuery, "UTF-8")
                  + "/calendar.xml?apikey=" + URLEncoder.encode(API_KEY, "UTF-8");
      } catch (UnsupportedEncodingException e1) {
          // TODO Auto-generated catch block
          e1.printStackTrace();
      }
  
      String url = SONGKICK_URL + getParameters;
      // Prepare a request object
      HttpGet httpget = new HttpGet(url);
  
      // Execute the request
      HttpResponse response;
      try {
          response = httpclient.execute(httpget);
          // Examine the response status
          Log.i(TAG, response.getStatusLine().toString());
  
          // Get hold of the response entity
          HttpEntity entity = response.getEntity();
          // If the response does not enclose an entity, there is no need
          // to worry about connection release
  
          if (entity != null) {
  
              // A Simple JSON Response Read
              InputStream instream = entity.getContent();
              String result = convertStreamToString(instream);
  
              // now you have the string representation of the HTML request
              instream.close();
              return result;
          }
  
      } catch (Exception e) {
  
          e.printStackTrace();
          return null;
      }
      return null;
  }
  
  private static String convertStreamToString(InputStream is) {
  
      BufferedReader reader = new BufferedReader(new InputStreamReader(is));
      StringBuilder sb = new StringBuilder();
  
      String line = null;
      try {
          while ((line = reader.readLine()) != null) {
              sb.append(line + "\n");
          }
      } catch (IOException e) {
          e.printStackTrace();
      } finally {
          try {
              is.close();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
      return sb.toString();
  }
  
  }
  </code></pre>
  
  <p>My log cat errors. It starts with a bunch of xml so the activity is pulling in the information then ends with an error</p>
  
  <pre><code>05-10 07:09:41.587: V/ArtistsSearchActivity(796):           &lt;identifier mbid="eb558587-e7a1-4f2b-9fda-b6ff5e137ed1" href="http://api.songkick.com/api/3.0/artists/mbid:eb558587-e7a1-4f2b-9fda-b6ff5e137ed1.xml"/&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):         &lt;/artist&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):       &lt;/performance&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):       &lt;performance billingIndex="3" displayName="Love And Death" billing="support" id="32720419"&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):         &lt;artist displayName="Love And Death" uri="http://www.songkick.com/artists/286472-love-and-death?utm_source=19089&amp;amp;utm_medium=partner" id="286472"&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):           &lt;identifier mbid="27796970-8f7a-4196-9f7d-87f091af4412" href="http://api.songkick.com/api/3.0/artists/mbid:27796970-8f7a-4196-9f7d-87f091af4412.xml"/&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):           &lt;identifier mbid="c29b667e-9895-41d2-b5a5-1817050ce0bc" href="http://api.songkick.com/api/3.0/artists/mbid:c29b667e-9895-41d2-b5a5-1817050ce0bc.xml"/&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):         &lt;/artist&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):       &lt;/performance&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):       &lt;venue displayName="Rostraver Ice Garden Arena" lat="40.1981235" lng="-79.8294916" uri="http://www.songkick.com/venues/51599-rostraver-ice-garden-arena?utm_source=19089&amp;amp;utm_medium=partner" id="51599"&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):         &lt;metroArea displayName="Belle Vernon" uri="http://www.songkick.com/metro_areas/56020-us-belle-vernon?utm_source=19089&amp;amp;utm_medium=partner" id="56020"&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):           &lt;state displayName="PA"/&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):           &lt;country displayName="US"/&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):         &lt;/metroArea&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):       &lt;/venue&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):       &lt;start time="19:30:00" datetime="2013-05-15T19:30:00-0500" date="2013-05-15"/&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):       &lt;location lat="40.1981235" lng="-79.8294916" city="Belle Vernon, PA, US"/&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):     &lt;/event&gt;
  05-10 07:09:41.587: V/ArtistsSearchActivity(796):     &lt;event type="Festival" status="ok" displayName="Rock on the Range 2013" uri="http://www.songkick.com/festivals/8261/id/14745014-rock-on-the-range-2013?utm_source=19089&amp;amp;utm_medium=partner" popularity="0
  05-10 07:09:41.637: I/Choreographer(796): Skipped 49 frames!  The application may be doing too much work on its main thread.
  05-10 07:09:43.807: E/Trace(871): error opening trace file: No such file or directory (2)
  05-10 07:09:45.357: E/Trace(910): error opening trace file: No such file or directory (2)
  05-10 07:09:45.687: E/Trace(923): error opening trace file: No such file or directory (2)
  05-10 07:09:46.307: E/Trace(936): error opening trace file: No such file or directory (2)
  05-10 07:09:47.167: E/Trace(949): error opening trace file: No such file or directory (2)
  05-10 07:09:48.337: E/Trace(975): error opening trace file: No such file or directory (2)
  </code></pre>
  
  <p>I have an update. The above code works! I will leave it for those that need it. The problem I am having is that if the xml string is too long the search times out. So how do I give Android more time to do its search?</p>