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) Working with JSON Cleaning Up the Date and Time

How do I fix this error?

For some reason I keep on having this error even though I followed the instructions.

Here is the code:

public class MainActivity extends ActionBarActivity {

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

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

        String apiKey = "***my_API_key****";
        double apiLat = 37.8267;
        double apiLong = -122.423;
        String forecastURL = "https://api.forecast.io/forecast/" + apiKey + "/" + apiLat + "," + apiLong;
        if (isNetworkOnline()) {
            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().toString();
                        Log.v(TAG, response.body().string());
                        if (response.isSuccessful()) {
                            mCurrentWeather = getCurrentDetails(JsonData);
                        } else {
                            alertUserAboutError();
                        }
                    } catch (IOException | JSONException e) {
                        Log.e(TAG, "Caught exception: ", e);
                    }
                }
            });
        } else {
            Toast.makeText(this, getString(R.string.network_not_available), Toast.LENGTH_LONG).show();
        }
        Log.d(TAG, "Main UI code is running.");
    }

    private CurrentWeather getCurrentDetails(String jsonData) throws JSONException {
        // getting the first JSON object in the json formatted link.
        JSONObject forecast = new JSONObject(jsonData);
        String timeZone = forecast.getString("timezone");

        // getting the second JSON object in the json format by looking for the
        // keyword "currently"
        JSONObject currently = forecast.getJSONObject("currently");
        CurrentWeather currentWeather = new CurrentWeather();
        currentWeather.setHumidity(currently.getDouble("humidity"));
        currentWeather.setIcon(currently.getString("icon"));
        currentWeather.setPrecipChance(currently.getDouble("precipProbability"));
        currentWeather.setSummary(currently.getString("summary"));
        currentWeather.setTemperature(currently.getDouble("temperature"));
        currentWeather.setTime(currently.getLong("time"));
        currentWeather.setTimeZone(timeZone);
        // Displaying the formatted time from seconds to the format we
        // specified.
        Toast.makeText(MainActivity.this, currentWeather.getFormattedTime(), Toast.LENGTH_LONG).show();
        return currentWeather;
    }

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

here's the error: 07-21 01:37:10.644 20859-20908/com.example.android.stormy E/MainActivityοΉ• Caught exception: org.json.JSONException: Value com.squareup.okhttp.internal.http.RealResponseBody@423e87e0 of type java.lang.String cannot be converted to JSONObject at org.json.JSON.typeMismatch(JSON.java:111) at org.json.JSONObject.<init>(JSONObject.java:158) at org.json.JSONObject.<init>(JSONObject.java:171) at com.example.android.stormy.MainActivity.getCurrentDetails(MainActivity.java:73) at com.example.android.stormy.MainActivity.access$100(MainActivity.java:22) at com.example.android.stormy.MainActivity$1.onResponse(MainActivity.java:54) at com.squareup.okhttp.Call$AsyncCall.execute(Call.java:170) at com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) at java.lang.Thread.run(Thread.java:856)

Edited to hide your API key & to highlight the code block.

Wait im not sure what you mean, do you want me to highlight the place where the error is occuring?

2 Answers

No - I amended your post so that the code block looks like it does now and I also removed your API key from your post as this is private to you and your app.

The error itself is an odd one. Something is being treated as a JSON Object when it is in fact a String.

If I had this code working in my environment, I would be questioning this line:

String JsonData = response.body().toString();

... as I think the last method should be .string() making the line look alternatively like:

String JsonData = response.body().string();

But I don't have it running so I can't test that little hunch.

Steve.

I'd also amend the variable name to jsonData to comply with naming conventions.

Ah, yes! If you look at your Log below that line, you've not been D.R.Y. but have used the different method there.

I think that's the correct method, so the first line should use string() not toString() and then you can use the variable jsonData (as amended) in the Log so as not to have that code repeated.

But why would those things cause an error? aren't they just preference?

The toString() method returns your object in string format - not the response, the whole object. Where string() returns your response as a string, which is what you're after.

But if i am only calling toString() on a response then wouldnt it just return the response in string format? or does toString() specifically for converting objects to string format?