0

How to handle if the user resume from disconnect in android android android-asynctask file-download java io I am working on an Async downloader

I simply using I/O stream to download

try {
        URL url = new URL(myurl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000 /* milliseconds */);
        conn.setConnectTimeout(15000 /* milliseconds */);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        // Starts the query
        conn.connect();
        int response = conn.getResponseCode();
        Log.d(DEBUG_TAG, "The response is: " + response);
        is = conn.getInputStream();

        // Convert the InputStream into a string
        String contentAsString = readIt(is, len);
        return contentAsString;

    // Makes sure that the InputStream is closed after the app is
    // finished using it.
    }

And a try catch to alert the message if there is exception. The problem is, if the user connect back the network , how can I resume the download? or say, just execute download task automatically if re-connected? thanks

user1871516
  • 879
  • 6
  • 14
  • 25
  • I believe you need to implement a DownloadManager class, in which you keep track of current downloads and status. Also you need a BroadcastReceiver to know when the users gets back on-line. From the broadcast receiver, you notify the download manager to resume the downloads in progress. This might not be a proper solution for you, but it's what I can think off right now. – Cristian Holdunu Dec 16 '13 at 23:11
  • Thanks for suggestion. download manager is good to use but i need to make a download queue – user1871516 Dec 16 '13 at 23:17

1 Answers1

1

This has many parts. First, I recommend using droidQuery to handle your network tasks. It is highly configurable and already can handle errors, timeout issues, etc. To get you started, try something like this:

Integer[] statusCodes = new Integer[]{480,522};//request and connection timeout error codes
$.ajax(new AjaxOptions().url(myURL).timeout(1000).dataType("text").statusCode(statusCodes, new Function() {
    @Override
    public void invoke($ d, Object... args) {
        //queue task to run again.
        int statusCode = (Integer) args[0];
        Log.e("Ajax", "Timeout (Error code " + statusCode + ").");
        requeue((AjaxOptions) args[1]);
    }
}).success(new Function() {
    @Override
    public void invoke($ d, Object... args) {
        //since dataType is text, the response is a String
        String response = (String) args[0];
        Log.i("Ajax", "Response String: " + response);
    }
}).error(new Function() {
    @Override
    public void invoke($ d, Object... args) {
        //show error message
        AjaxError error = (AjaxError) args[0];
        Log.e("Ajax", "Error " + error.status + ": " + error.reason);
    }
}));

Your requeue method will check the network status. If the network is up, the request is attempted again. If it is unavailable, it will be queued to run when the network is available. This queue will be used:

public static List<AjaxOptions> queue = new ArrayList<AjaxOptions>();

so the method looks something like this:

private void requeue(AjaxOptions options)
{
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo info = cm.getActiveNetworkInfo();
    if (info == null)
        cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
    if (info == null)
        cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
    if (info != null && info.isConnectedOrConnecting()) 
        $.ajax(options);
    else {
        synchronized(queue) {
            queue.add(options);
        }
    }
}

Finally, to ensure the queued requests are called when the network is available, you need to use a BroadcastReceiver to listen for changes in the network. A good example of this is NetWatcher, but your onReceive method will look more like this:

@Override
public void onReceive(Context context, Intent intent) {
    //here, check that the network connection is available. If yes, start your service. If not, stop your service.
   ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
   NetworkInfo info = cm.getActiveNetworkInfo();
   if (info != null) {
       if (info.isConnected()) {
           synchronized(myActivity.queue) {
               for (AjaxOptions options : myActivity.queue) {
                   $.ajax(options);
               }
               myActivity.queue.clear();
           }
       }
   }
}

If you want the queue variable to be private, you can register the broadcast receiver in code (rather than in the manifest), and make it an inner class of your Activity. Finally, to ensure your BroadcastReceiver works as expected, you need the following permission:

<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>

Also to ensure internet is available, don't forget the INTERNET permission.

Community
  • 1
  • 1
Phil
  • 35,089
  • 23
  • 123
  • 159