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.