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

Use City to find longitude and latitude, then use those values to get the weather

I just finished build a weather app track in Android, and I am trying to get the user to input a city, then retrieve the long and lat from that city, then use those values into the URL of the getforecast method. So far, i used the google geocoding API found here: https://developers.google.com/maps/documentation/javascript/geocoding

I have been able to retrieve all of those values, but i would only want to get the long and lat located here.

{ results: [ { address_components: [], formatted_address: "Anaheim, CA, USA", geometry: { bounds: { northeast: { lat: 33.8815471, lng: -117.674604 }, southwest: { lat: 33.788916, lng: -118.017595 } }, location: { lat: 33.8352932, //lat and lng lng: -117.9145036 }, location_type: "APPROXIMATE", viewport: {} }, place_id: "ChIJZ-hVgPnW3IARYLErmquJqwE", types: [] } ], status: "OK" }

I believe the logical error in my code is to retrieve these 2 values, from the results array then the geometry method then the location method and inside the location method would be the lat and lng.

this is my code in mainActivity.java and my getCurrentLocation is where i believe i have a logical error:

package teamtreehouse.stormy;

import android.app.Activity; import android.content.Context; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast;

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.JSONArray; import org.json.JSONException; import org.json.JSONObject;

import java.io.IOException; import java.net.NetworkInterface;

import butterknife.ButterKnife; import butterknife.InjectView;

public class MainActivity extends Activity {

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

private CurrentWeather mCurrentWeather;
private CurrentLocation[] mCurrentLocation;

@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;
@InjectView(R.id.refreshImageView)
ImageView mRefreshImageView;
@InjectView(R.id.progressBar3)
ProgressBar mProgressBar;
@InjectView(R.id.locationEditText)
EditText mNameField;
@InjectView(R.id.goButton)
Button mGoButton;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.inject(this);
    mNameField.setSelection(mNameField.getText().length());

    mGoButton.setOnClickListener(new View.OnClickListener() {
         @Override
     public void onClick(View view) {
             String name = mNameField.getText().toString();
             getLocation(name);

         }
      });

            mProgressBar.setVisibility(View.INVISIBLE);

    //fullerton
    double latitude = 33.8133;
    double longitude = -117.8867;


    mRefreshImageView.setOnClickListener((new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            getForecast(34.049887, -117.814984); //pomona
        }
    }));
}
//end of oncreate



public void getLocation(String name) {
    //get Google api
    String geoLocatingUrl = "https://maps.googleapis.com/maps/api/geocode/json?address="+name+"&key=mykey";

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(geoLocatingUrl)
                .build();

        Call call = client.newCall(request);
        //UI thread executes enqueue, sends to OKHttp Library gets data, response or failure back to UI
        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()) {

                    mCurrentLocation = getCurrentLocation(jsonData);
                    Log.v(TAG, jsonData);

                } else {
                    alertUserAboutError();

                }
            } catch (IOException e) {
                Log.e(TAG, "Exception caught: ", e);

            }
            catch (JSONException e) {
            }
        }
    });
}



//end of own google api code



private void getForecast(double latitude, double longitude) {
    String apiKey = "afcfb37b1d249fcd75c15ce1aa1764ef";

    String forecastUrl =  "https://api.forecast.io/forecast/" + apiKey +
            "/" + latitude + "," + longitude;

    if (isNetworkAvailable()) { //runs if network is there and available
        toggleRefresh();
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(forecastUrl)
                .build();

        Call call = client.newCall(request);
        //UI thread executes enqueue, sends to OKHttp Library gets data, response or failure back to UI
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        toggleRefresh();
                    }
                });
                alertUserAboutError();
            }

            @Override
            public void onResponse(Response response) throws IOException {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        toggleRefresh();
                    }
                });
                try {
                    String jsonData = response.body().string();
                    if (response.isSuccessful()) {

                        mCurrentWeather = getCurrentDetails(jsonData);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                updateDisplay();
                            }
                        });

                    } else {
                        alertUserAboutError();
                    }
                }
                catch (IOException e) {
                }
                catch (JSONException e) {
                }
            }
        });
    }
    else {
        Toast.makeText(this, getString(R.string.
                        network_unavailable_message),
                Toast.LENGTH_LONG
        ).show();
    }
}

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

private void updateLocation() {


}

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 CurrentLocation[] getCurrentLocation(String jsonData) throws JSONException {
    JSONObject object = new JSONObject(jsonData);
    JSONArray results = object.getJSONArray("results");

    CurrentLocation[] currentLocations = new CurrentLocation[1];
    JSONObject data = results.getJSONObject(0);
    JSONObject geometry = data.getJSONObject("geometry");
    JSONObject location = geometry.getJSONObject("location");
    CurrentLocation currentLocation = new CurrentLocation();

    currentLocation.setLatitude(location.getDouble("lat"));
    currentLocation.setLongitude(location.getDouble("lng"));

    currentLocations[0] = currentLocation;
    Log.i(TAG, "FROM JSON: " + currentLocation);
    return currentLocations;

    /*results has all the array info

    currentLocation = results;
    JSONObject result = results.getJSONObject(0);
    JSONObject geometry = result.getJSONObject("geometry");
    JSONObject location = geometry.getJSONObject("location");

    currentLocation.setLatitude(location.getDouble("lat"));
    currentLocation.setLongitude(location.getDouble("lng"));*/


}

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

}

1 Answer

Try to log all the Json object you get, by using something similar below example after each declaration. Than you will be able to understand, which particular event is wrong.

Log.d ("This is JSONarray Result: ", result..body().string());