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 Plugging in the Data

Jason Tjahja
Jason Tjahja
8,668 Points

Runtime Error

08-22 17:37:37.473 2697-2697/com.example.theodorusjasontjahja.stormy E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                       Process: com.example.theodorusjasontjahja.stormy, PID: 2697
                                                                                       java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.theodorusjasontjahja.stormy/com.example.theodorusjasontjahja.stormy.MainActivity}: java.lang.IllegalStateException: Required view 'timeLabel' with ID 2131492946 for field 'mTimeLabel' was not found. If this view is optional add '@Nullable' (fields) or '@Optional' (methods) annotation.
                                                                                           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                                                                                           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                                                           at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                                                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                                                           at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                           at android.os.Looper.loop(Looper.java:148)
                                                                                           at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                           at java.lang.reflect.Method.invoke(Native Method)
                                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                                        Caused by: java.lang.IllegalStateException: Required view 'timeLabel' with ID 2131492946 for field 'mTimeLabel' was not found. If this view is optional add '@Nullable' (fields) or '@Optional' (methods) annotation.
                                                                                           at butterknife.internal.Finder.findRequiredView(Finder.java:62)
                                                                                           at butterknife.internal.Finder.findRequiredViewAsType(Finder.java:74)
                                                                                           at com.example.theodorusjasontjahja.stormy.MainActivity_ViewBinding.<init>(MainActivity_ViewBinding.java:18)
                                                                                           at com.example.theodorusjasontjahja.stormy.MainActivity_ViewBinder.bind(MainActivity_ViewBinder.java:13)
                                                                                           at com.example.theodorusjasontjahja.stormy.MainActivity_ViewBinder.bind(MainActivity_ViewBinder.java:10)
                                                                                           at butterknife.ButterKnife.bind(ButterKnife.java:125)
                                                                                           at com.example.theodorusjasontjahja.stormy.MainActivity.onCreate(MainActivity.java:43)
                                                                                           at android.app.Activity.performCreate(Activity.java:6237)
                                                                                           at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                                                                                           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                                                           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
                                                                                           at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                                                                                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
                                                                                           at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                           at android.os.Looper.loop(Looper.java:148) 
                                                                                           at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                                           at java.lang.reflect.Method.invoke(Native Method) 
                                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
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.temperatureLabel) TextView mTemperatureLabel;
    @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) {
        ButterKnife.bind(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String apiKey = *** STEVE HID THIS *** ;
        double latitude = 37.8267;
        double longtitude= -122.423;

        String foreCastURL = "https://api.forecast.io/forecast/" + apiKey +
                             "/" + latitude + "," + longtitude;

        if(isNetworkAvailabe()){

            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 e) {
                        Log.e(TAG, "Exception caught: ", e);
                    } catch (JSONException e){
                        Log.e(TAG, "Exception caught: ", e);
                    }
                }
            });
        }else{
            Toast.makeText(this, R.string.network_unavailable_message, Toast.LENGTH_LONG).show();
        }
        Log.d(TAG,"Main UI code is running!");
    }
    private void updateDisplay() {

            // Temperature
            String temperatureFormat = getResources().getString(R.string.integerOutput);
            int currentTemperature = mCurrentWeather.getTemperature();
            String temperatureLabel = String.format(temperatureFormat,currentTemperature);
            mTemperatureLabel.setText(temperatureLabel);

            // Time
            String timeFormat = getString(R.string.timeString);
            String currentTime = mCurrentWeather.getFormattedTime();
            String timeLabel = String.format(timeFormat,currentTime);
            mTimeLabel.setText(timeLabel);

            // Humidity
            String humidityFormat = getString(R.string.percentageOutput);
            int currentHumidity = mCurrentWeather.getHumidity();
            String humidityLabel = String.format(humidityFormat,currentHumidity);
            mHumidityValue.setText(humidityLabel);

            //Precipitation Chance
            String precipitationFormat = getString(R.string.percentageOutput);
            int currentPrecipitationChance = mCurrentWeather.getPrecipitationChance();
            String precipitationLabel = String.format(precipitationFormat, currentPrecipitationChance);
            mPrecipValue.setText(precipitationLabel);

            // Summary Text
            mSummaryLabel.setText(mCurrentWeather.getSummary());

            // Icon Update
            Drawable drawable = ResourcesCompat.getDrawable(getResources(), mCurrentWeather.getIconId(), null);
            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 currentWeather;
    }

    private boolean isNetworkAvailabe() {
        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");
    }
}
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 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 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 int getHumidity() {
        return (int)mHumidity;
    }

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

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

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

    public String getSummary() {
        return mSummary;
    }

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

6 Answers

The above aside, one thing to try is the position of ButterKnife.bind(this);. Try moving it after the call to the superclass and if that doesn't help, move it another line further down, to after the setContentView method.

Worth a try ...

Steve.

Jason Tjahja
Jason Tjahja
8,668 Points

Hello Steve,

Really thanks for your answer, the app launched perfectly, thanks for your time to notice it. Spending hours just for mention a mistake is very annoying. Really big thanks, actually I already completed this challenge few days ago, I didn't use Butterknife, instead changed it to just using findViewById. But now I start using ButterKnife again and it runs.

Jason.

Hi Jason,

The app didn't find a view called timeLabel which you have bound mTimeLabel to.

Show us the XML file for your CurrentWeather. The error is Required view 'timeLabel' with ID 2131492946 for field 'mTimeLabel' was not found - which is what makes me think this might be a naming error in your XML file.

Steve.

I updated/reformatted your code blocks and hid your API key too! :smile: :+1:

I can't see anything immediately in your XML that might cause a problem.

I have noticed a significant difference between my code and yours, though. This may be due to my code being old and out of date, though.

For my ButterKnife commands, my code has @InjectView where yours has @BindView and inside onCreate, mine has ButterKnife.inject(this); rather than .bind(this);. As I say, this is probably either due to my code being old, or maybe that get changed later in the project, I don't know.

Steve.

I just had a look at the video and both my points seem valid - here's a grab of Ben's code:

ButterKnife

I might be worth switching the command to reflect what Ben has and seeing if that works from there.

Steve.

Jason Tjahja
Jason Tjahja
8,668 Points

here's my xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.theodorusjasontjahja.stormy.MainActivity"
    android:background="#fc970b">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="--"
        android:id="@+id/temperatureLabel"
        android:textColor="@android:color/white"
        android:textSize="150sp"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/degreeImageView"
        android:layout_alignTop="@+id/temperatureLabel"
        android:layout_toRightOf="@+id/temperatureLabel"
        android:layout_toEndOf="@+id/temperatureLabel"
        android:src="@drawable/degree"
        android:paddingTop="50dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="..."
        android:id="@+id/timeLabel"
        android:textColor="#80ffffff"
        android:textSize="18sp"
        android:layout_above="@+id/temperatureLabel"
        android:layout_centerHorizontal="true"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Alcatraz Island, CA"
        android:id="@+id/locationLabel"
        android:layout_above="@+id/temperatureLabel"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="60dp"
        android:textColor="@android:color/white"
        android:textSize="24sp"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/iconImageView"
        android:src="@drawable/cloudy_night"
        android:layout_alignBottom="@+id/locationLabel"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"/>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/temperatureLabel"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:weightSum="100"
        android:id="@+id/linearLayout">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="50"
            >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="HUMIDITY"
                android:id="@+id/humidityLabel"
                android:textColor="#80ffffff"
                android:gravity="center_horizontal"/>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="--"
                android:id="@+id/humidityValue"
                android:textColor="@android:color/white"
                android:textSize="24sp"
                android:gravity="center_horizontal"/>
        </LinearLayout>

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="50">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="RAIN/SNOW?"
                android:id="@+id/precipLabel"
                android:textColor="#80ffffff"
                android:gravity="center_horizontal"/>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="--"
                android:id="@+id/precipValue"
                android:textColor="@android:color/white"
                android:textSize="24sp"
                android:gravity="center_horizontal"/>
        </LinearLayout>
    </LinearLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Getting current weather..."
        android:id="@+id/summaryLabel"
        android:layout_below="@+id/linearLayout"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="40dp"
        android:textColor="@android:color/white"
        android:textSize="18sp"
        android:gravity="center_horizontal"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/refreshImageView"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:src="@drawable/refresh"/>

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/progressBar"
        android:layout_alignBottom="@+id/refreshImageView"
        android:layout_centerHorizontal="true"/>
</RelativeLayout>
Jason Tjahja
Jason Tjahja
8,668 Points

For everyone who had an error in this course, try to compare your codes with mine (this is for Butterknife 8.2.1)

build.gradle for module-level

apply plugin:'com.android.application'
apply plugin: 'android-apt'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.examp.theodorusjasontjahja.stormy"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.squareup.okhttp3:okhttp:3.4.1'
    compile 'com.jakewharton:butterknife:8.2.1'
    apt 'com.jakewharton:butterknife-compiler:8.2.1'

}

build.gradle project-level

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.2'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'


        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.theodorusjasontjahja.stormy.MainActivity"
    android:background="#fc970b">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="--"
        android:id="@+id/temperatureLabel"
        android:textColor="@android:color/white"
        android:textSize="150sp"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/degreeImageView"
        android:layout_alignTop="@+id/temperatureLabel"
        android:layout_toRightOf="@+id/temperatureLabel"
        android:layout_toEndOf="@+id/temperatureLabel"
        android:src="@drawable/degree"
        android:paddingTop="50dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="..."
        android:id="@+id/timeLabel"
        android:textColor="#80ffffff"
        android:textSize="18sp"
        android:layout_above="@+id/temperatureLabel"
        android:layout_centerHorizontal="true"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Alcatraz Island, CA"
        android:id="@+id/locationLabel"
        android:layout_above="@+id/temperatureLabel"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="60dp"
        android:textColor="@android:color/white"
        android:textSize="24sp"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/iconImageView"
        android:src="@drawable/cloudy_night"
        android:layout_alignBottom="@+id/locationLabel"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"/>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/temperatureLabel"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:weightSum="100"
        android:id="@+id/linearLayout">

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="50"
            >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="HUMIDITY"
                android:id="@+id/humidityLabel"
                android:textColor="#80ffffff"
                android:gravity="center_horizontal"/>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="--"
                android:id="@+id/humidityValue"
                android:textColor="@android:color/white"
                android:textSize="24sp"
                android:gravity="center_horizontal"/>
        </LinearLayout>

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="50">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="RAIN/SNOW?"
                android:id="@+id/precipLabel"
                android:textColor="#80ffffff"
                android:gravity="center_horizontal"/>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="--"
                android:id="@+id/precipValue"
                android:textColor="@android:color/white"
                android:textSize="24sp"
                android:gravity="center_horizontal"/>
        </LinearLayout>
    </LinearLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Getting current weather..."
        android:id="@+id/summaryLabel"
        android:layout_below="@+id/linearLayout"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="40dp"
        android:textColor="@android:color/white"
        android:textSize="18sp"
        android:gravity="center_horizontal"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/refreshImageView"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:src="@drawable/refresh"/>

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/progressBar"
        android:layout_alignBottom="@+id/refreshImageView"
        android:layout_centerHorizontal="true"/>
</RelativeLayout>

Main

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.temperatureLabel) TextView mTemperatureLabel;
    @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 = ****** ;
        double latitude = 37.8267;
        double longtitude= -122.423;

        String foreCastURL = "https://api.forecast.io/forecast/" + apiKey +
                             "/" + latitude + "," + longtitude;

        if(isNetworkAvailabe()){

            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 e) {
                        Log.e(TAG, "Exception caught: ", e);
                    } catch (JSONException e){
                        Log.e(TAG, "Exception caught: ", e);
                    }
                }
            });
        }else{
            Toast.makeText(this, R.string.network_unavailable_message, Toast.LENGTH_LONG).show();
        }
        Log.d(TAG,"Main UI code is running!");
    }
    private void updateDisplay() {

            // Temperature
            String temperatureFormat = getResources().getString(R.string.integerOutput);
            int currentTemperature = mCurrentWeather.getTemperature();
            String temperatureLabel = String.format(temperatureFormat,currentTemperature);
            mTemperatureLabel.setText(temperatureLabel);

            // Time
            String timeFormat = getString(R.string.timeString);
            String currentTime = mCurrentWeather.getFormattedTime();
            String timeLabel = String.format(timeFormat,currentTime);
            mTimeLabel.setText(timeLabel);

            // Humidity
            String humidityFormat = getString(R.string.percentageOutput);
            int currentHumidity = mCurrentWeather.getHumidity();
            String humidityLabel = String.format(humidityFormat,currentHumidity);
            mHumidityValue.setText(humidityLabel);

            //Precipitation Chance
            String precipitationFormat = getString(R.string.percentageOutput);
            int currentPrecipitationChance = mCurrentWeather.getPrecipitationChance();
            String precipitationLabel = String.format(precipitationFormat, currentPrecipitationChance);
            mPrecipValue.setText(precipitationLabel);

            // Summary Text
            mSummaryLabel.setText(mCurrentWeather.getSummary());

            // Icon Update
            Drawable drawable = ResourcesCompat.getDrawable(getResources(), mCurrentWeather.getIconId(), null);
            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 currentWeather;
    }

    private boolean isNetworkAvailabe() {
        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");
    }
}

mCurrentWeather

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 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 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 int getHumidity() {
        return (int)mHumidity;
    }

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

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

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

    public String getSummary() {
        return mSummary;
    }

    public void setSummary(String summary) {
        mSummary = summary;
    }
<resources>
    <string name="app_name">Stormy</string>
    <string name="error_title">Oops! Sorry!</string>
    <string name="error_message">There was an error. Please try again.</string>
    <string name="error_ok_button_text">OK</string>
    <string name="network_unavailable_message">Network is unavailable !</string>
    <string name="tempPreview">--</string>
    <string name="degree_symbol">Degree Symbol</string>
    <string name="timePreview"></string>
    <string name="defaultLocation">Alcatraz Island, CA</string>
    <string name="defaultLocationForScreenReaders">Current Weather Location</string>
    <string name="humidityColumnHeader">HUMIDITY</string>
    <string name="humidityPreview">--</string>
    <string name="precipColumnHeader">RAIN/SNOW?</string>
    <string name="precipPreview">--</string>
    <string name="summaryPreview">Getting Current Weather…</string>
    <string name="timeString">At %1$s it will be</string>
    <string name="percentageOutput">%d%%</string>
    <string name="integerOutput">%d</string>
</resources>