Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android Build a Weather App (2015) Hooking Up the Model to the View Setting the Weather Icon

Michael Narvaez
Michael Narvaez
4,182 Points

I'm getting a run time error on my weather app.

I don't know what this error specifies. Any ideas ?

07-16 23:33:11.922 25618-25618/? E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: michaeldnarvaez.com.stormy, PID: 25618 java.lang.NullPointerException at michaeldnarvaez.com.stormy.CurrentWeather.getIconId(CurrentWeather.java:33) at michaeldnarvaez.com.stormy.MainActivity.updateDisplay(MainActivity.java:110) at michaeldnarvaez.com.stormy.MainActivity.access$200(MainActivity.java:32) at michaeldnarvaez.com.stormy.MainActivity$1$1.run(MainActivity.java:80) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:157) at android.app.ActivityThread.main(ActivityThread.java:5356) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081) at dalvik.system.NativeStart.main(Native Method) 07-16 23:33:11.922 813-1374/? W/ActivityManager﹕ Force finishing activity michaeldnarvaez.com.stormy/.MainActivity 07-16 23:38:12.472 813-1451/? I/WindowState﹕ WIN DEATH: Window{45149548 u0 michaeldnarvaez.com.stormy/michaeldnarvaez.com.stormy.MainActivity}

2 Answers

Jon Kussmann
PLUS
Jon Kussmann
Courses Plus Student 7,254 Points

Michael,

Looking at your code it looks like you may have forgotten to call currentWeather.setIcon method inside the getCurrentDetails method of your MainActivity. This would cause a null pointer exception when your getIconId method is "looking for" mIcon.

I hope this helps, if not please let me know,

Jon Kussmann
PLUS
Jon Kussmann
Courses Plus Student 7,254 Points

Hi Michael,

It looks like your code is attempting to run getIconId from your CurrentWeather class but it is returning null. If you need more help, could you post your code?

Michael Narvaez
Michael Narvaez
4,182 Points

package michaeldnarvaez.com.stormy;

import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone;

public class CurrentWeather {

private String mIcon;
private long mTime;
private double mTemperature;
private double mHumidity;
private double mPrecipChance;
private String mSummary;
private String mTimeZone;

public String getTimeZone() {
    return mTimeZone;
}

public void setTimeZone(String timeZone) {
    mTimeZone = timeZone;
}

public String getIcon() {
    return mIcon;
}

public int getIconId() {

    int iconId = R.drawable.clear_day;

    if (mIcon.equals("clear-day")) {
        iconId = R.drawable.clear_day;
    }
    else if (mIcon.equals("clear-night")) {
        iconId = R.drawable.clear_night;
    }
    else if (mIcon.equals("rain")) {
        iconId = R.drawable.rain;
    }
    else if (mIcon.equals("snow")) {
        iconId = R.drawable.snow;
    }
    else if (mIcon.equals("sleet")) {
        iconId = R.drawable.sleet;
    }
    else if (mIcon.equals("wind")) {
        iconId = R.drawable.wind;
    }
    else if (mIcon.equals("fog")) {
        iconId = R.drawable.fog;
    }
    else if (mIcon.equals("cloudy")) {
        iconId = R.drawable.cloudy;
    }
    else if (mIcon.equals("partly-cloudy-day")) {
        iconId = R.drawable.partly_cloudy;
    }
    else if (mIcon.equals("partly-cloudy-night")) {
        iconId = R.drawable.cloudy_night;
    }

    return iconId;
}

public void setIcon(String icon) {
    mIcon = icon;
}

public long getTime() {
    return mTime;
}

public String getFormattedTime() {
    SimpleDateFormat formatter = new SimpleDateFormat("h:mm a");
    formatter.setTimeZone(TimeZone.getTimeZone(getTimeZone()));
    Date dateTime = new Date(getTime() * 1000);
    String timeString = formatter.format(dateTime);

    return timeString;
}

public void setTime(long time) {
    mTime = time;
}

public int getTemperature() {
    return (int)Math.round(mTemperature);
}


public void setTemperature(double temperature) {
    mTemperature = temperature;
}

public double getHumidity() {
    return mHumidity;
}

public void setHumidity(double humidity) {
    mHumidity = humidity;
}

public int getPrecipChance() {
    double precipPercentage = mPrecipChance * 100;
    return (int)Math.round(mPrecipChance);
}

public void setPrecipChance(double precipChance) {
    mPrecipChance = precipChance;
}

public String getSummary() {
    return mSummary;
}

public void setSummary(String summary) {
    mSummary = summary;
}

}

Jon Kussmann
Jon Kussmann
Courses Plus Student 7,254 Points

Hi, could you also post the code where you are calling that method?

Michael Narvaez
Michael Narvaez
4,182 Points

Sure thanks for your help, I'm still in the learning process...

public class MainActivity extends AppCompatActivity {

public static final String TAG = MainActivity.class.getSimpleName();

private CurrentWeather mCurrentWeather;

@InjectView(R.id.timeLabel) TextView mTimeLabel;
@InjectView(R.id.temperatureLabel) TextView mTemperatureLabel;
@InjectView(R.id.humidityValue) TextView mHumidityValue;
@InjectView(R.id.precipValue) TextView mPrecipValue;
@InjectView(R.id.summaryLabel) TextView mSummaryLabel;
@InjectView(R.id.iconImageView) ImageView mIconImageView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.inject(this);

    String apiKey = "18e4ee183959a025876f867b12eeea41";
    double latitude = 37.8267;
    double longitude = -122.423;
    String forecastUrl = "https://api.forecast.io/forecast/" + apiKey +
            "/" + latitude + "," + longitude ;

    if (isNetworkAvailable()) {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(forecastUrl)
                .build();

        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {

            }

            @Override
            public void onResponse(Response response) throws IOException {
                try {
                    String jsonData = response.body().string();
                    Log.v(TAG, jsonData);
                    if (response.isSuccessful()) {
                        mCurrentWeather = getCurrentDetails(jsonData);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                updateDisplay();
                            }
                        });
                    } else {
                        alertUserAboutError();
                    }
                } catch (IOException e) {
                    Log.e(TAG, "Exception caught: ", e);
                }
                catch (JSONException e) {
                    Log.e(TAG, "Exception caught: ", e);
                }
            }
        });

    }
    else {
        Toast.makeText(this, getString(R.string.network_unavailable_message), Toast.LENGTH_LONG).show();
    }

    Log.d(TAG, "Main UI code is running");
}

private void updateDisplay() {
    mTemperatureLabel.setText(mCurrentWeather.getTemperature() + "");
    mTimeLabel.setText("At" + mCurrentWeather.getFormattedTime() + "it will be");
    mHumidityValue.setText(mCurrentWeather.getHumidity() + "");
    mPrecipValue.setText(mCurrentWeather.getPrecipChance() + "%");
    mSummaryLabel.setText(mCurrentWeather.getSummary());

    Drawable drawable = ContextCompat.getDrawable(this, mCurrentWeather.getIconId());
    mIconImageView.setImageDrawable(drawable);

}

private CurrentWeather getCurrentDetails(String jsonData) throws JSONException {
    JSONObject forecast = new JSONObject(jsonData);
    String timezone = forecast.getString("timezone");
    Log.i(TAG, "from JSON: " + timezone);

    JSONObject currently = forecast.getJSONObject("currently");

    CurrentWeather currentWeather = new CurrentWeather();
    currentWeather.setHumidity(currently.getDouble("humidity"));
    currentWeather.setTime(currently.getLong("time"));
    currentWeather.setPrecipChance(currently.getDouble("precipProbability"));
    currentWeather.setSummary(currently.getString("summary"));
    currentWeather.setTemperature(currently.getDouble("temperature"));
    currentWeather.setTimeZone(timezone);

    Log.d(TAG, currentWeather.getFormattedTime());

    return currentWeather;
}
Michael Narvaez
Michael Narvaez
4,182 Points

Thanks !! I was pretty close... I'm really starting to love coding.

Jon Kussmann
Jon Kussmann
Courses Plus Student 7,254 Points

Glad I could help! It sure is a lot of fun, but spending hours an a single error can get pretty annoying, haha.

Michael Narvaez
Michael Narvaez
4,182 Points

haha, yes it can sir ! But I actually enjoy it sometimes. thanks again