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) Concurrency and Error Handling What To Do When the Network is Down

jenyufu
jenyufu
3,311 Points

Why is the dialog "Oops! Sorry!" still showing for me but not for Ben in the lesson?

I have been at this bug for hours and I can't figure it out: Everything else works fine but whenever I run the app and open it, the dialog shows up. -_-'

Here is my source code:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.teamtreehouse.stormy" >

    <!--add this. It solves the MainNetwork Permission error by requesting permission to use the internet -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <!--permission for getActiveNetwork method -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

AlertDialogFragment.java

package com.teamtreehouse.stormy;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.os.Bundle;


public class AlertDialogFragment extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Context context = getActivity();
        AlertDialog.Builder builder = new AlertDialog.Builder(context)
                .setTitle(context.getString(R.string.error_title)) //change all the text messages to String resources. Steps: 1. Alt+Enter. 2. give the resource a name 3. then hit ESC key when CONTEXT is highlighted in red.
                .setMessage(context.getString(R.string.error_message))
                .setPositiveButton(context.getString(R.string.error_ok_button_text), null);

    AlertDialog dialog  = builder.create();
        return dialog;
    }
}

MainActivity.java

package com.teamtreehouse.stormy;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
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 java.io.IOException;


public class MainActivity extends ActionBarActivity {

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

    //create new method to check for network connectivity

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

        String apiKey = "d5faf0cb201f103df4dde0b8b0a4f490";
        double latitude = 37.8267;
        double longitude = -122.423;
        String forecastUrl = "https://api.forecast.io/forecast/" + apiKey +
                "/" + latitude + "/" + "," + longitude;

        if (isNetworkAvailable()) {  // [**]   //create new method to check for network connectivity and wrap requesting HTTP in it.
            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 {
                        Log.v(TAG, response.body().string());
                        if (response.isSuccessful()) {
                        } else {
                            alertUserAboutError();
                        }
                    } catch (IOException e) {
                        Log.e(TAG, "Exception caught: ", e);
                    }
                }
            });
        }
            else { //[***if network unavailable]
                Toast.makeText(this, getString(R.string.network_unavailable_message), Toast.LENGTH_LONG).show(); //extract String resource from "Network is unavailable!"
        }

        Log.d(TAG, "Main UI code is running!");
    }

    private boolean isNetworkAvailable() { // We'll set a return value based on the network availability. [**]
        //We are going to use an Android Class called ConnectivityManager
        ConnectivityManager manager = (ConnectivityManager)
                getSystemService(Context.CONNECTIVITY_SERVICE);

        //  now we need to substantiate a NetworkInfo object. Lets call it 'networkInfo'
        NetworkInfo networkInfo = manager.getActiveNetworkInfo(); //now we can analyze the network info to see if it is both present and active
        // ^ to use .getActiveNetworkInfo method, we need to add another permission to manifest*

        boolean isAvailable = false;    //initialize boolean variable = is network present: true or false // Let's set it to false initially and then we'll only set it to true if the network is actually available.
        if (networkInfo != null && networkInfo.isConnected()) { // check the network using an 'if' statement //if ("network is not null" aka network is present AND network is connected to the web)
            isAvailable = true; //[**]
        }
        return isAvailable; //now we have a condition that will check if the network is presented and connected!!!!
        // But what if this returns false?
        // We should let the user know that the network is unavailable.
        // Then they can check their network status, disable airplane mode. [***]
    }
    private void alertUserAboutError() {
        AlertDialogFragment dialog = new AlertDialogFragment();
        dialog.show(getFragmentManager(), "error_dialog");
    }
}

2 Answers

jenyufu
jenyufu
3,311 Points

turns out this is the problem:

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

suppose to be this:

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

the extra + "/" caused the error which caused the alertUserAboutError to be launched. Normally, if there isn't a problem the dialog would not be launched. No idea why an extra "/" would cause that problem but oh well.

Jacob Bergdahl
Jacob Bergdahl
29,119 Points

Remove alertUserAboutError() from your if/else-statement in oneResponse().

jenyufu
jenyufu
3,311 Points

Yeah but we are suppose to keep the dialog in there in case of error.

Someone told me to use https://www.diffchecker.com/diff diff checker to check the difference between my code and Ben's code.

it turns out this is the problem:

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

suppose to be this:

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

the extra + "/" caused the error which caused the alertUserAboutError to be launched. Normally, if there isn't a problem the dialog would not be launched. No idea why an extra "/" would cause that problem but oh well.