Issue
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
Solution
This has many parts. First, I recommend using my droidQuery library 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.
Answered By - Phil
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.