java - App Keeps Crashing -


my app i've created using android studio keeps crashing , don't know why. weather app , i'm following google's developing android app course, here's logcat:

    07-20 18:19:45.740  16410-16434/com.alexander.sunshine e/activitythread﹕ failed find provider info com.alexander.android.sunshine.app 07-20 18:19:45.748  16410-16434/com.alexander.sunshine e/androidruntime﹕ fatal exception: asynctask #1     process: com.alexander.sunshine, pid: 16410     java.lang.runtimeexception: error occured while executing doinbackground()             @ android.os.asynctask$3.done(asynctask.java:304)             @ java.util.concurrent.futuretask.finishcompletion(futuretask.java:355)             @ java.util.concurrent.futuretask.setexception(futuretask.java:222)             @ java.util.concurrent.futuretask.run(futuretask.java:242)             @ android.os.asynctask$serialexecutor$1.run(asynctask.java:231)             @ java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1112)             @ java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:587)             @ java.lang.thread.run(thread.java:818)      caused by: java.lang.nullpointerexception: attempt invoke interface method 'boolean android.database.cursor.movetofirst()' on null object reference             @ com.alexander.sunshine.app.fetchweathertask.addlocation(fetchweathertask.java:109)             @ com.alexander.sunshine.app.fetchweathertask.getweatherdatafromjson(fetchweathertask.java:214)             @ com.alexander.sunshine.app.fetchweathertask.doinbackground(fetchweathertask.java:414)             @ com.alexander.sunshine.app.fetchweathertask.doinbackground(fetchweathertask.java:34)             @ android.os.asynctask$2.call(asynctask.java:292)             @ java.util.concurrent.futuretask.run(futuretask.java:237)             at android.os.asynctask$serialexecutor$1.run(asynctask.java:231)             at java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1112)             at java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:587)             at java.lang.thread.run(thread.java:818) 

and here's fetchweathertask.java:

package com.alexander.sunshine.app;  import android.content.contenturis; import android.content.contentvalues; import android.content.context; import android.content.sharedpreferences; import android.database.cursor; import android.database.databaseutils; import android.net.uri; import android.os.asynctask; import android.preference.preferencemanager; import android.text.format.time; import android.util.log; import android.widget.arrayadapter;  import com.alexander.sunshine.r; import com.alexander.sunshine.app.data.weathercontract; import com.alexander.sunshine.app.data.weathercontract.weatherentry;  import org.json.jsonarray; import org.json.jsonexception; import org.json.jsonobject;  import java.io.bufferedreader; import java.io.ioexception; import java.io.inputstream; import java.io.inputstreamreader; import java.net.httpurlconnection; import java.net.url; import java.text.simpledateformat; import java.util.date; import java.util.vector;  public class fetchweathertask extends asynctask<string, void, string[]> {      private final string log_tag = fetchweathertask.class.getsimplename();      private arrayadapter<string> mforecastadapter;     private final context mcontext;      public fetchweathertask(context context, arrayadapter<string> forecastadapter) {         mcontext = context;         mforecastadapter = forecastadapter;     }      private boolean debug = true;      /* date/time conversion code going moved outside asynctask later,      * convenience we're breaking out own method now.      */     private string getreadabledatestring(long time){         // because api returns unix timestamp (measured in seconds),         // must converted milliseconds in order converted valid date.         date date = new date(time);         simpledateformat format = new simpledateformat("e, mmm d");         return format.format(date).tostring();     }      /**      * prepare weather high/lows presentation.      */     private string formathighlows(double high, double low) {         // data fetched in celsius default.         // if user prefers see in fahrenheit, convert values here.         // rather fetching in fahrenheit user can         // change option without having re-fetch data once         // start storing values in database.         sharedpreferences sharedprefs =                 preferencemanager.getdefaultsharedpreferences(mcontext);         string unittype = sharedprefs.getstring(                 mcontext.getstring(r.string.pref_units_key),                 mcontext.getstring(r.string.pref_units_metric));          if (unittype.equals(mcontext.getstring(r.string.pref_units_imperial))) {             high = (high * 1.8) + 32;             low = (low * 1.8) + 32;         } else if (!unittype.equals(mcontext.getstring(r.string.pref_units_metric))) {             log.d(log_tag, "unit type not found: " + unittype);         }          // presentation, assume user doesn't care tenths of degree.         long roundedhigh = math.round(high);         long roundedlow = math.round(low);          string highlowstr = roundedhigh + "/" + roundedlow;         return highlowstr;     }      /**      * helper method handle insertion of new location in weather database.      *      * @param locationsetting location string used request updates server.      * @param cityname human-readable city name, e.g "mountain view"      * @param lat latitude of city      * @param lon longitude of city      * @return row id of added location.      */     long addlocation(string locationsetting, string cityname, double lat, double lon) {         long locationid;          // first, check if location city name exists in db         cursor locationcursor = mcontext.getcontentresolver().query(                 weathercontract.locationentry.content_uri,                 new string[]{weathercontract.locationentry._id},                 weathercontract.locationentry.column_location_setting + " = ?",                 new string[]{locationsetting},                 null);          if (locationcursor.movetofirst()) {             int locationidindex = locationcursor.getcolumnindex(weathercontract.locationentry._id);             locationid = locationcursor.getlong(locationidindex);         } else {             // content provider set up, inserting rows of data pretty simple.             // first create contentvalues object hold data want insert.             contentvalues locationvalues = new contentvalues();              // add data, along corresponding name of data type,             // content provider knows kind of value being inserted.             locationvalues.put(weathercontract.locationentry.column_city_name, cityname);             locationvalues.put(weathercontract.locationentry.column_location_setting, locationsetting);             locationvalues.put(weathercontract.locationentry.column_coord_lat, lat);             locationvalues.put(weathercontract.locationentry.column_coord_long, lon);              // finally, insert location data database.             uri inserteduri = mcontext.getcontentresolver().insert(                     weathercontract.locationentry.content_uri,                     locationvalues             );              // resulting uri contains id row.  extract locationid uri.             locationid = contenturis.parseid(inserteduri);         }          locationcursor.close();         // wait, worked?  yes!         return locationid;     }      /*         students: code allow fetchweathertask continue return strings         ux expects can continue test application once begin using         database.      */     string[] convertcontentvaluestouxformat(vector<contentvalues> cvv) {         // return strings keep ui functional         string[] resultstrs = new string[cvv.size()];         ( int = 0; < cvv.size(); i++ ) {             contentvalues weathervalues = cvv.elementat(i);             string highandlow = formathighlows(                     weathervalues.getasdouble(weatherentry.column_max_temp),                     weathervalues.getasdouble(weatherentry.column_min_temp));             resultstrs[i] = getreadabledatestring(                     weathervalues.getaslong(weatherentry.column_date)) +                     " - " + weathervalues.getasstring(weatherentry.column_short_desc) +                     " - " + highandlow;         }         return resultstrs;     }      /**      * take string representing complete forecast in json format ,      * pull out data need construct strings needed wireframes.      *      * fortunately parsing easy:  constructor takes json string , converts      * object hierarchy us.      */     private string[] getweatherdatafromjson(string forecastjsonstr,                                             string locationsetting)             throws jsonexception {          // have string representing complete forecast in json format.         // fortunately parsing easy:  constructor takes json string , converts         // object hierarchy us.          // these names of json objects need extracted.          // location information         final string owm_city = "city";         final string owm_city_name = "name";         final string owm_coord = "coord";          // location coordinate         final string owm_latitude = "lat";         final string owm_longitude = "lon";          // weather information.  each day's forecast info element of "list" array.         final string owm_list = "list";          final string owm_pressure = "pressure";         final string owm_humidity = "humidity";         final string owm_windspeed = "speed";         final string owm_wind_direction = "deg";          // temperatures children of "temp" object.         final string owm_temperature = "temp";         final string owm_max = "max";         final string owm_min = "min";          final string owm_weather = "weather";         final string owm_description = "main";         final string owm_weather_id = "id";          try {             jsonobject forecastjson = new jsonobject(forecastjsonstr);             jsonarray weatherarray = forecastjson.getjsonarray(owm_list);              jsonobject cityjson = forecastjson.getjsonobject(owm_city);             string cityname = cityjson.getstring(owm_city_name);              jsonobject citycoord = cityjson.getjsonobject(owm_coord);             double citylatitude = citycoord.getdouble(owm_latitude);             double citylongitude = citycoord.getdouble(owm_longitude);              long locationid = addlocation(locationsetting, cityname, citylatitude, citylongitude);              // insert new weather information database             vector<contentvalues> cvvector = new vector<contentvalues>(weatherarray.length());              // owm returns daily forecasts based upon local time of city being             // asked for, means need know gmt offset translate data             // properly.              // since data sent in-order , first day             // current day, we're going take advantage of nice             // normalized utc date of our weather.              time daytime = new time();             daytime.settonow();              // start @ day returned local time. otherwise mess.             int julianstartday = time.getjulianday(system.currenttimemillis(), daytime.gmtoff);              // work exclusively in utc             daytime = new time();              for(int = 0; < weatherarray.length(); i++) {                 // these values collected.                 long datetime;                 double pressure;                 int humidity;                 double windspeed;                 double winddirection;                  double high;                 double low;                  string description;                 int weatherid;                  // json object representing day                 jsonobject dayforecast = weatherarray.getjsonobject(i);                  // cheating convert utc time, want anyhow                 datetime = daytime.setjulianday(julianstartday+i);                  pressure = dayforecast.getdouble(owm_pressure);                 humidity = dayforecast.getint(owm_humidity);                 windspeed = dayforecast.getdouble(owm_windspeed);                 winddirection = dayforecast.getdouble(owm_wind_direction);                  // description in child array called "weather", 1 element long.                 // element contains weather code.                 jsonobject weatherobject =                         dayforecast.getjsonarray(owm_weather).getjsonobject(0);                 description = weatherobject.getstring(owm_description);                 weatherid = weatherobject.getint(owm_weather_id);                  // temperatures in child object called "temp".  try not name variables                 // "temp" when working temperature.  confuses everybody.                 jsonobject temperatureobject = dayforecast.getjsonobject(owm_temperature);                 high = temperatureobject.getdouble(owm_max);                 low = temperatureobject.getdouble(owm_min);                  contentvalues weathervalues = new contentvalues();                  weathervalues.put(weatherentry.column_loc_key, locationid);                 weathervalues.put(weatherentry.column_date, datetime);                 weathervalues.put(weatherentry.column_humidity, humidity);                 weathervalues.put(weatherentry.column_pressure, pressure);                 weathervalues.put(weatherentry.column_wind_speed, windspeed);                 weathervalues.put(weatherentry.column_degrees, winddirection);                 weathervalues.put(weatherentry.column_max_temp, high);                 weathervalues.put(weatherentry.column_min_temp, low);                 weathervalues.put(weatherentry.column_short_desc, description);                 weathervalues.put(weatherentry.column_weather_id, weatherid);                  cvvector.add(weathervalues);             }              // add database             if ( cvvector.size() > 0 ) {                 contentvalues[] cvarray = new contentvalues[cvvector.size()];                 cvvector.toarray(cvarray);                 mcontext.getcontentresolver().bulkinsert(weatherentry.content_uri, cvarray);             }              // sort order:  ascending, date.             string sortorder = weatherentry.column_date + " asc";             uri weatherforlocationuri = weatherentry.buildweatherlocationwithstartdate(                     locationsetting, system.currenttimemillis());              // students: uncomment next lines display what stored in bulkinsert             cursor cur = mcontext.getcontentresolver().query(weatherforlocationuri,                     null, null, null, sortorder);              cvvector = new vector<contentvalues>(cur.getcount());             if ( cur.movetofirst() ) {                 {                     contentvalues cv = new contentvalues();                     databaseutils.cursorrowtocontentvalues(cur, cv);                     cvvector.add(cv);                 } while (cur.movetonext());             }              log.d(log_tag, "fetchweathertask complete. " + cvvector.size() + " inserted");              string[] resultstrs = convertcontentvaluestouxformat(cvvector);             return resultstrs;          } catch (jsonexception e) {             log.e(log_tag, e.getmessage(), e);             e.printstacktrace();         }         return null;     }      @override     protected string[] doinbackground(string... params) {          // if there's no zip code, there's nothing up.  verify size of params.         if (params.length == 0) {             return null;         }         string locationquery = params[0];          // these 2 need declared outside try/catch         // can closed in block.         httpurlconnection urlconnection = null;         bufferedreader reader = null;          // contain raw json response string.         string forecastjsonstr = null;          string format = "json";         string units = "metric";         int numdays = 14;          try {             // construct url openweathermap query             // possible parameters avaiable @ owm's forecast api page, @             // http://openweathermap.org/api#forecast             final string forecast_base_url =                     "http://api.openweathermap.org/data/2.5/forecast/daily?";             final string query_param = "q";             final string format_param = "mode";             final string units_param = "units";             final string days_param = "cnt";              uri builturi = uri.parse(forecast_base_url).buildupon()                     .appendqueryparameter(query_param, params[0])                     .appendqueryparameter(format_param, format)                     .appendqueryparameter(units_param, units)                     .appendqueryparameter(days_param, integer.tostring(numdays))                     .build();              url url = new url(builturi.tostring());              // create request openweathermap, , open connection             urlconnection = (httpurlconnection) url.openconnection();             urlconnection.setrequestmethod("get");             urlconnection.connect();              // read input stream string             inputstream inputstream = urlconnection.getinputstream();             stringbuffer buffer = new stringbuffer();             if (inputstream == null) {                 // nothing do.                 return null;             }             reader = new bufferedreader(new inputstreamreader(inputstream));              string line;             while ((line = reader.readline()) != null) {                 // since it's json, adding newline isn't necessary (it won't affect parsing)                 // make debugging *lot* easier if print out completed                 // buffer debugging.                 buffer.append(line + "\n");             }              if (buffer.length() == 0) {                 // stream empty.  no point in parsing.                 return null;             }             forecastjsonstr = buffer.tostring();         } catch (ioexception e) {             log.e(log_tag, "error ", e);             // if code didn't weather data, there's no point in attemping             // parse it.             return null;         } {             if (urlconnection != null) {                 urlconnection.disconnect();             }             if (reader != null) {                 try {                     reader.close();                 } catch (final ioexception e) {                     log.e(log_tag, "error closing stream", e);                 }             }         }          try {             return getweatherdatafromjson(forecastjsonstr, locationquery);         } catch (jsonexception e) {             log.e(log_tag, e.getmessage(), e);             e.printstacktrace();         }         // happen if there error getting or parsing forecast.         return null;     }      @override     protected void onpostexecute(string[] result) {         if (result != null && mforecastadapter != null) {             mforecastadapter.clear();             for(string dayforecaststr : result) {                 mforecastadapter.add(dayforecaststr);             }             // new data server.  hooray!         }     } } 

as stack trace says, you're trying call movetofirst() on null reference. locationcursor object you're calling method on, must null.

the docs query() can return null, you'll should null check object, , should check invocation of query() try understand why it's returning null.


Comments