Gastón Saillén
Gastón Saillén

Reputation: 13129

How to set a fixed time if AsyncTask is not finished

I have an asynctask and I'm looking to do a wait if the async is taking too long, I'm downloading some data of the database , but I don't want to have the user looping around the progressdialog, I want to set a fixed time, lets say I'm downloading a file but is taking forever, so I tell the user, "hey, check your internet connection and try again" I'm looking to do this with a timer, but I'm kinda stuck, this is where I do my asynctask

private class DownloadFilesTask extends AsyncTask<Void, Void, Void> {
             String s;
             public DownloadFilesTask(String s){
                 this.s = s;
             }

             @Override
             protected Void doInBackground(Void... voids) {
                 DownloadMethod(s);
                 return null;
             }
         }

so let's say I want to execute that downloadmethod for a fixed time, 10 or 20 seconds, if the file is not downloaded at that time I return a message to the user saying that he needs to check for hes internet.

Upvotes: 2

Views: 563

Answers (5)

karandeep singh
karandeep singh

Reputation: 2334

You can use handler to run after a definite amount time and maintain a boolean flag which you can update in postExecute function of async task.

In your activity/fragment class:

new Handler().postDelayed(new Runnable(){
          public void run(){
                   //Check whether the flag has been updated or not
             },1000)

Upvotes: 1

vikas kumar
vikas kumar

Reputation: 11018

Here is a basic idea you can try if it works

private class DownloadFilesTask extends AsyncTask<Void, Integer, Void> implements TimerTask{
    String s;
    Timer timer;
    Object objectResult;

    public DownloadFilesTask(String s){
        this.s = s;
        timer = new Timer();
    }

    @Override
    protected Void doInBackground(Void... voids) {
        objectResult = DownloadMethod();
        return null;
    }

    private Object DownloadMethod() {
        //here implement the download logic and return the object
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        // your code to update progress
    }

    public void checkProgress(){
       timer.schedule(this,2000);
    }

    @Override
    public void run() {
        if (objectResult!=null){
            //download completed 
        }else{
            //show dialog here and schedule a task again
            timer.schedule(this,2000);
        }
    }
}

Upvotes: 1

Aditya
Aditya

Reputation: 3673

First thing I want to say that is, while running downloading task it's not a good practice, to message a user that check your internet connection or no internet connection. Because in this condition, if user do switch off then on network connection then your downloading task restarts again and takes whole time again. So, avoid this types of messages.

Now about solution, after execute background task you can check your task is running or completed. If it takes too much time then show a message. For example,

YourBackgroundTask task = new YourBackgroundTask();
task.execute();

new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            if (task.getStatus == AsyncTask.Status.RUNNING){
                Toast.makeText(this, "Please wait...", Toast.LENGTH_SHORT).show();
            }
        }
},20000);    // time in milisecond

And if you want to repeat this, you can easily re-run handler.

Upvotes: 1

Subrata Mondal
Subrata Mondal

Reputation: 852

If you are using HttpURLConnection to download the file then you can do something like this:

private class DownloadFilesTask extends AsyncTask<String, Integer, Integer> {


    @Override
    protected Integer doInBackground(String... ulr) {
        URL url = null;
        try {
            url = new URL(ulr[0]);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setConnectTimeout(2000); //Timeout
            //...Other codes for downloading
            return 101;
        } catch (java.net.SocketTimeoutException e) {
            return 102;
        } catch (MalformedURLException e) {
            return 103;
        } catch (IOException e) {
            return 104;
        }
    }

    @Override
    protected void onPostExecute(Integer result) {
        if(result == 102) {
            Toast.makeText(getApplicationContext(), "Connection Timeout.", Toast.LENGTH_LONG).show();
        }
    }
}

Upvotes: 1

Cagri Yalcin
Cagri Yalcin

Reputation: 402

You can use BroadcastReceiver to listen your internet connection. Here is an example:

public class NetworkControl extends BroadcastReceiver {

static boolean isConnected = false;

@Override
public void onReceive(final Context context, final Intent intent) {
    isNetworkAvailable(context);
}

private boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivity != null) {
        NetworkInfo[] info = connectivity.getAllNetworkInfo();
        if (info != null) {
            for (int i = 0; i < info.length; i++) {
                if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                    if(!isConnected){
                        isConnected = true;
                        Toast.makeText(context, "You're online!!", Toast.LENGTH_LONG).show();
                    }
                    return true;
                }
            }
        }
    }
    isConnected = false;
    Toast.makeText(context, "Connection interrupted.", Toast.LENGTH_LONG).show();
    return false;
}
}

Also you need some permissions in AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

Then start the service in your activity.

    IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
    receiver = new NetworkControl();
    registerReceiver(receiver, filter);

Upvotes: 1

Related Questions