android - WeatherApp, setting an image inside and AsyncTask while parsing XML using setImageResource() -


so i'm working on basic weather application pulls xml yahoo weather api, parses it, , displays information. have async task in doinbackground method pulls xml , uses stringbuilder save xml, , in onpostexecute parses xml in format need. trying set image in mcondimg imageview in post execute, put can't seem working. want have condimg change per codes in xml

public api call: https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3d%22warrensburg%2c%20mo%22)&format=xml&env=store%3a%2f%2fdatatables.org%2falltableswithkeys

weatherfragment.java (the fragment contains of actual parsed axml , asynctask classes.)

import android.app.progressdialog; import android.content.context; import android.net.uri; import android.os.asynctask; import android.os.bundle; import android.os.handler; import android.support.v4.app.fragment; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.imageview; import android.widget.textview;  import org.xmlpull.v1.xmlpullparser; import org.xmlpull.v1.xmlpullparserfactory;  import java.io.bufferedreader; import java.io.inputstreamreader; import java.io.stringreader; import java.net.httpurlconnection; import java.net.url;        public class weatherfragment extends fragment {          static textview mlocation, mcondition, mforecast1, mforecast2, mforecast3, mforecast4, mforecast5;         handler handler;         imageview mcondimg;        private onfragmentinteractionlistener mlistener;      public weatherfragment() {         handler = new handler();     }      public static weatherfragment newinstance(string param1, string param2) {         weatherfragment fragment = new weatherfragment();         bundle args = new bundle();         fragment.setarguments(args);         return fragment;     }      @override     public void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);     }      @override     public view oncreateview(layoutinflater inflater, viewgroup container,                              bundle savedinstancestate) {         view rootview = inflater.inflate(r.layout.fragment_weather, container, false);         mlocation = (textview)  rootview.findviewbyid(r.id.location);         mcondition = (textview) rootview.findviewbyid(r.id.condition);         mforecast1 = (textview) rootview.findviewbyid(r.id.forecast1);         mforecast2 = (textview) rootview.findviewbyid(r.id.forecast2);         mforecast3 = (textview) rootview.findviewbyid(r.id.forecast3);         mforecast4 = (textview) rootview.findviewbyid(r.id.forecast4);         mforecast5 = (textview) rootview.findviewbyid(r.id.forecast5);         mcondimg = (imageview) rootview.findviewbyid(r.id.condimg);         new retrievedata().execute();         return rootview;     }      // todo: rename method, update argument , hook method ui event     public void onbuttonpressed(uri uri) {         if (mlistener != null) {             mlistener.onfragmentinteraction(uri);         }     }      @override     public void ondetach() {         super.ondetach();         mlistener = null;     }      public interface onfragmentinteractionlistener {         void onfragmentinteraction(uri uri);     }      public void changecity(string city){         //updateweatherdata(city);     } }  class retrievedata extends asynctask<void, void, string> {      public static string str;      @override     protected void onpreexecute() {         super.onpreexecute();     }      @override     protected string doinbackground(void... urls) {         try {             url url = new url("https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3d%22warrensburg%2c%20mo%22)&format=xml&env=store%3a%2f%2fdatatables.org%2falltableswithkeys");             httpurlconnection urlconnection = (httpurlconnection) url.openconnection();             try {                 bufferedreader bufferedreader = new bufferedreader(new inputstreamreader(urlconnection.getinputstream()));                 stringbuilder stringbuilder = new stringbuilder();                 string line;                 while ((line = bufferedreader.readline()) != null) {                     stringbuilder.append(line).append("\n");                 }                 bufferedreader.close();                 str = stringbuilder.tostring();                  return stringbuilder.tostring();             } catch (exception e) {                 e.printstacktrace();             }         } catch (exception e) {             e.printstacktrace();         }         return "error getting weather data";     }       protected void onpostexecute(string response) {         if (response == null) {             response = "error";         }          // parse xml         try {             int forecastcounter = 1;             xmlpullparserfactory factory = xmlpullparserfactory.newinstance();             xmlpullparser parser = factory.newpullparser();             parser.setinput(new stringreader(str));             string tagname = null;             int event = parser.geteventtype();              while (event != xmlpullparser.end_document) {                 tagname = parser.getname();                 if (event == xmlpullparser.start_tag) {                      if (tagname.equals("yweather:location")) {                         weatherfragment.mlocation.settext(parser.getattributevalue(null, "city"));                         weatherfragment.mlocation.append(", " + parser.getattributevalue(null, "region"));                      }                     else if (tagname.equals("yweather:condition")) {                         weatherfragment.mcondition.settext("current temperature: " + parser.getattributevalue(null, "temp") + "\ncurrent conditions: " + parser.getattributevalue(null, "text"));                         if (tagname.equals("yweather:code")) {                             mcondimg.setimageresource(r.drawable.ic_snow);                         }                     }                     else if (tagname.equals("yweather:forecast")) {                         switch (forecastcounter) {                             case 1:                                 weatherfragment.mforecast1.settext(parser.getattributevalue(null, "day") + " - high: " + parser.getattributevalue(null, "high") + " - low: " + parser.getattributevalue(null, "low") + " - " + parser.getattributevalue(null, "text"));                                 forecastcounter++;                                 if (weatherfragment.mcondition.gettext().equals("28")) {                                     //weatherfragment.mcondimg.setimageresource(r.drawable.ic_sunny);//this works                                 }                                 break;                             case 2:                                 weatherfragment.mforecast2.settext(parser.getattributevalue(null, "day") + " - high: " + parser.getattributevalue(null, "high") + " - low: " + parser.getattributevalue(null, "low") + " - " + parser.getattributevalue(null, "text"));                                 forecastcounter++;                                 break;                             case 3:                                 weatherfragment.mforecast3.settext(parser.getattributevalue(null, "day") + " - high: " + parser.getattributevalue(null, "high") + " - low: " + parser.getattributevalue(null, "low") + " - " + parser.getattributevalue(null, "text"));                                 forecastcounter++;                                 break;                             case 4:                                 weatherfragment.mforecast4.settext(parser.getattributevalue(null, "day") + " - high: " + parser.getattributevalue(null, "high") + " - low: " + parser.getattributevalue(null, "low") + " - " + parser.getattributevalue(null, "text"));                                 forecastcounter++;                                 break;                             case 5:                                 weatherfragment.mforecast5.settext(parser.getattributevalue(null, "day") + " - high: " + parser.getattributevalue(null, "high") + " - low: " + parser.getattributevalue(null, "low") + " - " + parser.getattributevalue(null, "text"));                                 forecastcounter++;                                 break;                         }                      }                 }                 event = parser.next();             }         }         catch (exception e) {             e.printstacktrace();         }         //mweatherdata.settext(str);      }  } 

weatherfragment.xml (used styling fragment)

    <linearlayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:gravity="center"     android:orientation="vertical" >       <textview         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_margintop="-140sp"         android:textsize="30sp"         android:id="@+id/location"/>      <imageview         android:layout_width="300px"         android:layout_height="300px"         android:src="@drawable/ic_sunny"         android:id="@+id/condimg"         />      <textview         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="left"         android:layout_marginleft="15sp"         android:layout_marginbottom="7sp"         android:id="@+id/condition"/>      <textview         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="center"         android:layout_marginbottom="10sp"         android:textsize="20sp"         android:text="@string/multiforecast" />      <textview         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="left"         android:layout_marginleft="15sp"         android:layout_marginbottom="7sp"         android:id="@+id/forecast1" />       <textview         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="left"         android:layout_marginleft="15sp"         android:layout_marginbottom="7sp"         android:id="@+id/forecast2" />        <textview         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="left"         android:layout_marginleft="15sp"         android:layout_marginbottom="7sp"         android:id="@+id/forecast3" />       <textview         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="left"         android:layout_marginleft="15sp"         android:layout_marginbottom="7sp"         android:id="@+id/forecast4" />        <textview         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="left"         android:layout_marginleft="15sp"         android:layout_marginbottom="7sp"         android:id="@+id/forecast5" />      <!--<scrollview         android:layout_width="match_parent"         android:layout_height="match_parent">       <textview         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:id="@+id/weather_data"         />      </scrollview>-->  </linearlayout> 

the problem adding namespaces tag names in code. example, given tag:

<yweather:condition     xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0"     code="29"      date="sun, 24 apr 2016 09:00 pm cdt"     temp="68"     text="partly cloudy" /> 

the tag name "condition", not "yweather:condition". namespace "yweather". check proper tag should this:

if ("condition".equals(tagname)) 

if want check namespace matches, can this:

if ("condition".equals(tagname) && "yweather".equals(parser.getnamespace()) 

it's worth mentioning code doing xml parsing on main (ui) thread because doing inside of onpostexecute(). should doing parsing inside of doinbackground() instead; onpostexecute() should reserved smallest amount of code modifies ui.

you can take advantage of fact asynctask parameterized , have doinbackground() return class define hold results of parsing, so:

private static class weatherresults {     private int conditionimage;     private string condition;     private string location;     ... }  class retrievedata extends asynctask<void, void, weatherresults> {     @override     protected string doinbackground(void... params) {         weatherresults weatherresults = new weatherresults();         // make web call         // parse xml , set results, e.g.         //    weatherresults.conditionimage = r.drawable.ic_snow;          return weatherresults;         // can return null instead if there's error     }      @override     protected void onpostexecute(weatherresults result) {         if (result == null) {             // show error state             return;         }          // update ui         mcondimg.setimageresource(result.conditionimage);         // etc.     } } 

Comments

Popular posts from this blog

javascript - How to get current YouTube IDs via iMacros? -

c# - Maintaining a program folder in program files out of date? -

emulation - Android map show my location didn't work -