Fatal Exception Main Android Null Pointer Exception

436 views Asked by At

I am having an issue with this weather app that I am making with TreeHouse I have asked a question on their forums, but no avail.

Here are my two files in question...

MainActivity

package com.megliosolutions.stormy;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;

import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import butterknife.ButterKnife;
import butterknife.InjectView;


public class MainActivity extends ActionBarActivity {

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 = "baab1393443251119f2e1e8fdf55f46d";
    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, "JSON Exception caught: ", e);
                }
            }
        });
    }
    else {
       // Toast.makeText(this, getString(R.string.network_unavailable_message)
         //       , Toast.LENGTH_LONG).show();

        alertUserNoNetwork();
    }

    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 = getResources().getDrawable(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.setIcon(currently.getString("icon"));
    currentWeather.setPrecipChance(currently.getDouble("precipProbability"));
    currentWeather.setSummary(currently.getString("summary"));
    currentWeather.setTemperature(currently.getDouble("temperature"));
    currentWeather.setTimeZone(timezone);

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


    return new CurrentWeather();

}


private boolean isNetworkAvailable() {
    ConnectivityManager manager = (ConnectivityManager)
            getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = manager.getActiveNetworkInfo();
    boolean isAvailable = false;
    if (networkInfo != null && networkInfo.isConnected()) {
        isAvailable = true;
    }
        return isAvailable;

}

private void alertUserNoNetwork() {
    NoNetworkAlertDialogFragment NoNetworkdialog = new NoNetworkAlertDialogFragment();
    NoNetworkdialog.show(getFragmentManager(), "no_network_dialog");
}

private void alertUserAboutError() {
    AlertDialogFragment dialog = new AlertDialogFragment();
    dialog.show(getFragmentManager(), "error_dialog");
}


}

Here is CurrentWeather.java

 package com.megliosolutions.stormy;

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

 /**
  * Created by Jarvis on 6/10/15.
   */
  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 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 String getIcon() {
    return mIcon;
    }

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

    public int getIconId(){
    // clear-day, clear-night, rain, snow, sleet, wind, fog, cloudy,           partly-cloudy-day, or partly-cloudy-night
    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 long getTime() {
    return mTime;
    }

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

    public int getTemperature() {
    //returns long value so either turn to long or cast int
    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(precipPercentage);
    }

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

    public String getSummary() {
    return mSummary;
    }

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

Having an issue with a Null pointer exception

06-17 00:30:14.013    6766-6766/com.megliosolutions.stormy E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.megliosolutions.stormy, PID: 6766
    java.lang.NullPointerException: id == null
            at java.util.TimeZone.getTimeZone(TimeZone.java:349)
            at com.megliosolutions.stormy.CurrentWeather.getFormattedTime(CurrentWeather.java:30)
            at com.megliosolutions.stormy.MainActivity.updateDisplay(MainActivity.java:108)
            at com.megliosolutions.stormy.MainActivity.access$200(MainActivity.java:28)
            at com.megliosolutions.stormy.MainActivity$1$1.run(MainActivity.java:77)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

Above is the error I get. Not sure where to start on this.

Any help??

1

There are 1 answers

5
Thyen Hong Guedes Chang On BEST ANSWER

The error is in this function

public String getTimeZone() {
    return mTimeZone;
}

The mTimeZone variable in returning null, and so, the following code raiser an exception:

TimeZone.getTimeZone(getTimeZone())

Also, in this function:

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.setIcon(currently.getString("icon"));
    currentWeather.setPrecipChance(currently.getDouble("precipProbability"));
    currentWeather.setSummary(currently.getString("summary"));
    currentWeather.setTemperature(currently.getDouble("temperature"));
    currentWeather.setTimeZone(timezone);

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


    return new CurrentWeather();

}

You are returning a new CurrentWeather() object. Change it to:

return currentWeather;