2

I've been following the book "Head First Android", and I'm stuck in Chapter 3.

This little app is a really basic layout; 3 text views and 1 image view, that should update after reading from NASA RSS daily image.

I've completed the chapter but now when running the app only shows a Blank screen.

Any help appreciated. This is the code:

public class MainActivity extends Activity {

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        IotdHandler handler = new IotdHandler ();
        handler.processFeed();
        resetDisplay (handler.getTitle(), handler.getDate(), handler.getImage(), handler.getDescription());
    }

    public class IotdHandler extends DefaultHandler {
        private String url = "http://www.nasa.gov/rss/dyn/image_of_the_day.rss";
        private boolean inUrl = false;
        private boolean inTitle = false;
        private boolean inDescription = false;
        private boolean inItem = false;
        private boolean inDate = false;
        private Bitmap image = null;
        private String title = null;
        private StringBuffer description = new StringBuffer();
        private String date = null;


        public void processFeed() {
            try {
            SAXParserFactory factory =
            SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            XMLReader reader = parser.getXMLReader();
            reader.setContentHandler(this);
            InputStream inputStream = new URL(url).openStream();
            reader.parse(new InputSource(inputStream));
            } catch (Exception e) {  }
        }

            private Bitmap getBitmap(String url) {
                try {
                HttpURLConnection connection = (HttpURLConnection)new URL(url).openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                Bitmap bilde = BitmapFactory.decodeStream(input);
                input.close();
                return bilde;
                } catch (IOException ioe) { return null; }
                }

            public void startElement(String url, String localName, String qName, Attributes attributes) throws SAXException {
                    if (localName.endsWith(".jpg")) { inUrl = true; }
                    else { inUrl = false; }

                    if (localName.startsWith("item")) { inItem = true; }
                    else if (inItem) {

                        if (localName.equals("title")) { inTitle = true; }
                        else { inTitle = false; }

                        if (localName.equals("description")) { inDescription = true; }
                        else { inDescription = false; }

                        if (localName.equals("pubDate")) { inDate = true; }
                        else { inDate = false; }
                        }
                    }


            public void characters(char ch[], int start, int length) { String chars = new String(ch).substring(start, start + length);
                if (inUrl && url == null) { image = getBitmap(chars); }
                if (inTitle && title == null) { title = chars; }
                if (inDescription) { description.append(chars); }
                if (inDate && date == null) { date = chars; }
         }

        public Bitmap getImage() { return image; }
        public String getTitle() { return title; }
        public StringBuffer getDescription() { return description; }
        public String getDate() { return date; }
}

    private void resetDisplay (String title, String date, Bitmap image, StringBuffer description) {

        TextView titleView = (TextView) findViewById (R.id.imageTitle);
        titleView.setText(title);

        TextView dateView = (TextView) findViewById(R.id.imageDate);
        dateView.setText(date);

        ImageView imageView = (ImageView) findViewById (R.id.imageDisplay);
        imageView.setImageBitmap(image);

        TextView descriptionView = (TextView) findViewById (R.id.imageDescription);
        descriptionView.setText(description);
    }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
   // Inflate the menu; this adds items to the action bar if it is present.
   getMenuInflater().inflate(R.menu.main, menu);
   return true;
}
}
Ram kiran Pachigolla
  • 20,897
  • 15
  • 57
  • 78
Violin Nz
  • 297
  • 1
  • 5
  • 15

4 Answers4

3

You should use AsyncTask as an inner class.

 @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    IotdHandler handler = new IotdHandler ();
    new MyTask().execute();
}

and then parse document in doInBackground() and call resetDisplay in onPostExecute().

public class MyTask extends AsyncTask<Void, Void, Void>{

@Override
protected Void doInBackground(Void... params) {
    handler.processFeed();
    return null;
}

@Override
protected void onPostExecute(Void result) {
    resetDisplay (handler.getTitle(), handler.getDate(), handler.getImage(), handler.getDescription());
    super.onPostExecute(result);
}
}

For more info how to pass parameter,return result etc.. AsyncTask Document

Ketan Ahir
  • 6,678
  • 1
  • 23
  • 45
0

There will be more errors you will be facing if you go ahead from this book and that's why head first has took this book from the amazon.So if u are beginners then try Boston, Marcana ,vogella tutorils or u can try Android tutorials from google and the same question you can refer to Recommend a good Android tutorial with Step by Step examples

Community
  • 1
  • 1
mohsin
  • 530
  • 5
  • 24
0

One of the other problems with this is that the RSS feed as of the time of the writing of the book was a single post, and now it is a list of the most recent thirty days of the Daily image feed. This brought me to the same issue. So updating the XML processing and using the AsyncTask was required to get a working app.

0

The two clases solved:

1 - IotdHandler:

    package com.headfirstlab.nasadailyimage;

     import android.support.v7.app.ActionBarActivity;
     import android.os.Bundle;
     import android.view.Menu;
     import android.view.MenuItem;
     import android.widget.ImageView;
     import android.widget.TextView;

    public class NasaDailyImage extends ActionBarActivity {

    IotdHandler iotdHandler = new IotdHandler();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_nasa_daily_image);

    IotdHandler handler = new IotdHandler();

    handler.processFeed();
    resetDisplay(iotdHandler.getTitle(), iotdHandler.getDate(),
            iotdHandler.getUrl(), iotdHandler.getDescription());
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.nasa_daily_image, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

private void resetDisplay(String title, String date,
        String imageUrl, String description) {

    TextView titleView = (TextView)findViewById(R.id.imageTitle);

    titleView.setText(title);

    TextView dateView = (TextView)findViewById(R.id.imageDate);

    dateView.setText(date);

    ImageView imageView =(ImageView)findViewById(R.id.imageDisplay);

    imageView.setImageBitmap(iotdHandler.getUrl());
    imageView.setImageBitmap(IotdHandler.getBitmap(iotdHandler.getUrl()));
    TextView descriptionView = (TextView)findViewById(R.id.imageDescription);

    descriptionView.setText(description);


    }
 }

2 - NasaDailyImage:

 package com.headfirstlab.nasadailyimage;

 import android.support.v7.app.ActionBarActivity;
 import android.os.Bundle;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.widget.ImageView;
 import android.widget.TextView;

 public class NasaDailyImage extends ActionBarActivity {

 IotdHandler iotdHandler = new IotdHandler();

   @Override
   protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_nasa_daily_image);

    IotdHandler handler = new IotdHandler();

    handler.processFeed();
    resetDisplay(iotdHandler.getTitle(), iotdHandler.getDate(),
            iotdHandler.getUrl(), iotdHandler.getDescription());
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.nasa_daily_image, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

private void resetDisplay(String title, String date,
        String imageUrl, String description) {

    TextView titleView = (TextView)findViewById(R.id.imageTitle);

    titleView.setText(title);

    TextView dateView = (TextView)findViewById(R.id.imageDate);

    dateView.setText(date);

    ImageView imageView =(ImageView)findViewById(R.id.imageDisplay);

    imageView.setImageBitmap(IotdHandler.getBitmap(iotdHandler.getUrl()));
    TextView descriptionView = (TextView)findViewById(R.id.imageDescription);

    descriptionView.setText(description);


     }
}

hope you find it useful : )