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

Redoing stormy but not quite working

Hi everyone,

Im not getting a successful response when the onResponse() method is called and im not sure why

Code.java
package com.example.kevin.weatherweatherweather;

import android.app.FragmentManager;
import android.content.Context;
import android.content.IntentSender;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
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 org.w3c.dom.Text;

import java.io.IOException;

import butterknife.Bind;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener {

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

    private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;

    private CurrentWeather mCurrentWeather;

    GoogleApiClient mApiClient;
    private String mLongitude;
    private String mLatitude;
    private String apiKey = "https://api.forecast.io/forecast/82d13a33d173a4194740ca6fb9bc0b9b/" + mLatitude + "," + mLongitude;
    private LocationRequest mLocationRequest;

    @Bind(R.id.timeLabel)
    TextView mTimeLabel;
    @Bind(R.id.temperatureLabel)
    TextView mTemperatureLabel;
    @Bind(R.id.humidityValue)
    TextView mHumidityValue;
    @Bind(R.id.precipValue)
    TextView mPrecipValue;
    @Bind(R.id.summaryLabel)
    TextView mSummaryLabel;
    @Bind(R.id.iconImageView)
    ImageView mIconImageView;
    @Bind(R.id.refreshImageView)
    ImageView mRefreshImageView;
    @Bind(R.id.progressBar)
    ProgressBar mProgressBar;


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

        ButterKnife.bind(this);

        mProgressBar.setVisibility(View.INVISIBLE);


        if (isConnected()) {
            toggleRefresh();

            if (!isGoogleServicesAvaiable()) {
                finish();
                Log.d(TAG, "google services not available");
            }
            buildGoogleApiClient();
            locationRequestCreator();


        } else {
            Toast.makeText(this, "No Internet Connection", Toast.LENGTH_SHORT);
        }
    }

    private boolean isGoogleServicesAvaiable() {
        GoogleApiAvailability availability = GoogleApiAvailability.getInstance(); //check if we have google play services on device
        int status = availability.isGooglePlayServicesAvailable(this);
        if (status == ConnectionResult.SUCCESS) {
            return true;
        } else {
            String error = availability.getErrorString(status);
            Toast.makeText(this, error, Toast.LENGTH_LONG);
            return false;
        }
    }

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

    private void buildGoogleApiClient() {
        mApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    private void locationRequestCreator() {
        mLocationRequest = LocationRequest.create()
                .setPriority(LocationRequest.PRIORITY_LOW_POWER)
                .setInterval(3600 * 1000)
                .setFastestInterval(1 * 1000);
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "RESUMING");
        mApiClient.connect();
    }

    public void onPause() {
        super.onPause();
        if (mApiClient.isConnected()) {
            Log.d(TAG, "DISCONNECTING");
            LocationServices.FusedLocationApi.removeLocationUpdates(mApiClient, this);
            mApiClient.disconnect();
        }
    }


    @Override
    public void onConnected(Bundle bundle) {
        Location location = LocationServices.FusedLocationApi.getLastLocation(mApiClient);
        if (location != null) {
            mLongitude = String.valueOf(location.getLongitude());
            mLatitude = String.valueOf(location.getLatitude());
            createOkHttpClient();


        } else {
            Log.d(TAG, "Location is null");
            LocationServices.FusedLocationApi.requestLocationUpdates(mApiClient, mLocationRequest, this);

        }
    }

    private void createOkHttpClient() {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(apiKey)
                .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();
                    if (response.isSuccessful()) {
                        mCurrentWeather = getCurrentDetails(jsonData);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                updateDisplay();
                            }
                        });
                    } else {
                        errorBox();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    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");

        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;
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        if (connectionResult.hasResolution()) {
            try {
                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
            } catch (IntentSender.SendIntentException e) {
                e.printStackTrace();
            }
        } else {
            Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.d(TAG, location.toString());
    }

    public void errorBox() {
        AlertDialogFragment box = new AlertDialogFragment();
        box.show(getFragmentManager(), "error");
    }

    private void toggleRefresh() {

        if (mProgressBar.getVisibility() == View.INVISIBLE) {
            mProgressBar.setVisibility(View.VISIBLE);
            mRefreshImageView.setVisibility(View.INVISIBLE);
        } else {
            mProgressBar.setVisibility(View.INVISIBLE);
            mRefreshImageView.setVisibility(View.VISIBLE);
        }
    }
}

Thank you

1 Answer

Here...

    private void createOkHttpClient() {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(apiKey)
                .build();

You're forgetting to add the latitude and longitude to the URL.

Hey Seth,

The onConnected() method before that method gets called. So in the code below, I set the mLongitude and mLatitude. Then once that is done, I run the createOkHttpClient() method

    @Override
    public void onConnected(Bundle bundle) {
        Location location = LocationServices.FusedLocationApi.getLastLocation(mApiClient);
        if (location != null) {
            mLongitude = String.valueOf(location.getLongitude());
            mLatitude = String.valueOf(location.getLatitude());
            createOkHttpClient();

By this point I believe that this apiKey will have been successfully updated with the appropriate latitude and longitude

private String apiKey = "https://api.forecast.io/forecast/82d13a33d173a4194740ca6fb9bc0b9b/" + mLatitude + "," + mLongitude;

Didn't see the whole line where you initialize apiKey due to length, but that will only use the values of mLatitude and mLongitude when the activity is created, which are null. When you do concatenation (or any other operation) it will use only the values of any variable at that moment in the result. So you will need to add the current latitude and longitude to the url with every new request.

i finally got it working. thanks!