-1

Everything appears correctly on the screen until I fill in updateDisplay() method with code to update my textViews using setText/get.

The app does not crash prior to entering the setText/get code to update from the DarkSky API, but once entered the app crashes and tells me to try again.

I believe everything is entered correctly, but for some reason the app won't take the information. ALSO, I am using the recent version of OkHTTP in cradle, so the issue doesn't lie there. (Permissions are also used)

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

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

import java.io.IOException;

import butterknife.BindView;
import butterknife.ButterKnife;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

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

private CurrentWeather mCurrentWeather;

@BindView(R.id.timeLabel) TextView mTimeLabel;
@BindView(R.id.tempLabel) TextView mTempLabel;
@BindView(R.id.humidityValue) TextView mHumidityValue;
@BindView(R.id.precipValue) TextView mPrecipValue;
@BindView(R.id.summaryLabel) TextView mSummaryLabel;
@BindView(R.id.iconImageView) ImageView mIconImageView;

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

    String apiKey = "MY KEY";
    double latitude = 37.8267;
    double longitude = -122.4233;
    String forecastURL = ("https://api.darksky.net/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(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, 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 | JSONException e) {
                    Log.e(TAG, "Exception caught: ", e);
                }
            }
        });
    }

    else {
        Toast.makeText(this, R.string.network_unavailable_message,
                Toast.LENGTH_LONG).show(); // CHALLENGE: Turn into dialog
    }
    Log.d(TAG, "Main UI code is running!");
}

private void updateDisplay() {
    mSummaryLabel.setText(mCurrentWeather.getSummary());
    mTempLabel.setText(mCurrentWeather.getTemperature() + "");
}

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.getInt("temperature"));
    currentWeather.setTimeZone(timezone);

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

    return 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 alertUserAboutError() {
    AlertDialogFragment dialog = new AlertDialogFragment();
    dialog.show(getFragmentManager(), "error_dialog");
}
}

package tricksterantics.com.catsndogs;

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;


public String getTimeZone() {
    return mTimeZone;
}

public void setTimeZone(String timeZone) {

    mTimeZone = timeZone;
}

private String mTimeZone;

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 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 double 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(precipPercentage);
}

public void setPrecipChance(double precipChance) {

    mPrecipChance = precipChance;
}

public String getSummary() {

    return mSummary;
}

public void setSummary(String summary) {

    mSummary = summary;
}

}

Edit: Added an image of the stack trace Stack trace

duhhsnail
  • 1
  • 2
  • 2
    Post the stacktrace from the crash. – codeMagic Dec 12 '17 at 16:08
  • Also, go ahead and check at in that method that nothing is null. That's likely the issue from what we are shown so far. – codeMagic Dec 12 '17 at 16:21
  • I've added a screenshot of the stack trace. I don't think it's null? I'm not quite sure – duhhsnail Dec 12 '17 at 16:38
  • 1
    The stack trace makes it pretty clear - you are trying to reference a null object - probably with the settext – Elemental Dec 12 '17 at 16:45
  • I'm pretty new to app development so I'm not sure what I should do from there since it's null? – duhhsnail Dec 12 '17 at 16:52
  • My point doesnt relate to the error u r getting but please put `String jsonData` declaration inside `if (response.isSuccessfull())` as if response is not successful then `.string()` method will throw `nullpointer` as you wont have `response.body()`.. – Aalap Patel Dec 12 '17 at 16:52
  • I went back to look at the code and got setText to work. I changed my original format from using Butterknife (BindView) and decided to use mTimeLabel = (TextView) findViewById(R.id.timeLabel); for all of my textViews. Everything is functioning now and am retrieving updated data from the API. Thanks for your inputs :) – duhhsnail Dec 12 '17 at 17:50

1 Answers1

0

Got rid of the Butterknife format I was using (BindVIew) and opted for this, everything now works and is retrieving updated information from the API:

public class MainActivity extends AppCompatActivity {

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

private CurrentWeather mCurrentWeather;

private TextView mTimeLabel;

private TextView mTempLabel;

private TextView mHumidityValue;

private TextView mPrecipValue;

private TextView mSummaryLabel;

private ImageView mIconImageView;



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

    mTimeLabel = (TextView) findViewById(R.id.timeLabel);
    mTempLabel = (TextView) findViewById(R.id.tempLabel);
    mHumidityValue = (TextView) findViewById(R.id.humidityValue);
    mPrecipValue = (TextView) findViewById(R.id.precipValue);
    mSummaryLabel = (TextView) findViewById(R.id.summaryLabel);
duhhsnail
  • 1
  • 2