Question

I'm trying to check connection to the internet on Android (an actual connection, as opposed to network access) which causes NetworkOnMainThreadException. Because of this I'm trying to move it into an AsyncTask.

This is my isConnected() method:

if(!checkNetwork(parent)){
    return false;
}
if(!checkConnection(url)){
    return false;
}
return true;

Now, I check the connection by just using if(isConnected()) but I'm getting the exception. So what I need to do is move the above method into an AsyncTask and retrieve the value it returns.

I thought perhaps I could make a global variable that'd keep track of it, but then I'm not sure if my value would be returned before or after the AsyncTask had set it.

I'm sure there are ways to do this, so I'm looking for ideas on how to do it. Any advice is appreciated!

EDIT: I've updated my code to use an AsyncTask, let me know if this looks better:

ConnectUtils.java:

public class ConnectUtils {

    private static boolean hasConnected, hasChecked;

    public boolean isConnected(Context parent, String url){ 
        hasChecked = false;
        this.new CheckURL(parent, url).execute();
        while(!hasChecked){ }
        return hasConnected;
    }

    private class CheckURL extends AsyncTask<Void, Void, Boolean>{

        private Context parent;
        private String url;

        public CheckURL(Context parent, String url){
            this.parent = parent;
            this.url = url;
        }

        @Override
        protected Boolean doInBackground(Void... params){
            if(!checkNetwork(parent)){
                return false;
            }
            if(!checkConnection(url)){
                return false;
            }
            return true;
        }

        @Override
        protected void onPostExecute(Boolean result){
            super.onPostExecute(result);
            hasConnected = result;
            hasChecked = true;
        }
    }

    private static boolean checkNetwork(Context parent){
        ConnectivityManager conMgr = (ConnectivityManager)parent.getSystemService(Context.CONNECTIVITY_SERVICE);
        if(conMgr.getActiveNetworkInfo() != null){
            NetworkInfo activeInfo = conMgr.getActiveNetworkInfo();
            if(!activeInfo.isConnected() || !activeInfo.isAvailable()){
                return false;
            }
            return true;
        }
        return false;
    }

    private static boolean checkConnection(String url){
        boolean responded = false;
        HttpGet requestTest = new HttpGet(url);
        HttpParams params = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(params, 3000);
        HttpConnectionParams.setSoTimeout(params, 5000);
        DefaultHttpClient client = new DefaultHttpClient(params);
        try {
            client.execute(requestTest);
            responded = true;
        } catch (Exception e){
            e.printStackTrace();
        }
        return responded;
    }
}

called via if(!new ConnectUtils().isConnected(this, "http://google.com"))

Was it helpful?

Solution

here's a sample code:

new AsyncTask<Void, Void, Boolean>()
{
    @Override
    protected Boolean doInBackground(Void... p)
    {
        return isConnected();
    }

    @Override
    protected void onPostExecute(Boolean result)
    {
        //this is code for the UI thread, now that it knows what is the result.
    }
}.execute();

OTHER TIPS

In your AsyncTask's onPostExecute method, call a function in your activity to process the (now known) state of the connection. Until that method executes, your UI and/or internal logic should reflect that the state of the connection is unknown.

Check the connection in the doInBackground() method of AsyncTask<Url, Void, Boolean> Params = url, progress = void (nothing) and result is a boolean.

The onPostExecute() will return to the main thread of your application

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top