A while ago I posted an article discussing how to handle offline and online events in Cordova/PhoneGap (PhoneGap Offline/Online Tip). While working on my book I came across some differences to this behavior that I wanted to document.
As a reminder, the idea is simple. Your PhoneGap/Cordova app should be network aware if it makes any use of remote resources. While the Network Information plugin isn't perfect (and I'll be showing an example of that in a second), there really is no excuse to not add some type of support for this in your application. Having an application that just silently fails is unprofessional - especially considering how easy it is to fix.
Read the earlier entry first - I'll wait.
Now that you've seen an example, there are a few changes you should be aware of.
At the time I wrote the entry, I recommended putting the event listeners in the document ready block if you were using jQuery. Now the recommendation (and this is documented) is to place them in the deviceready listener.
The good news is that the handlers still works as my other blog entry says. They will fire automatically on application startup. The bad news though is that your code needs to be a bit more intelligent about any warnings it may use. What do I mean? My sample code alerted the user when they went offline and online. It makes sense to warn the user immediately if the application starts up offline. It does not make sense to do the same if the application is online. So you need a work around for that. The good news is that the workaround also meshes nicely with a bug.
Cordova issues 7787 describes a bug where in Android, the event listeners may fire multiple times. What that means is that when you test putting your device offline, the event may fire twice or more. If you are using an alert, then that's a problem.
To get around this I used a simple hack. It is harmless on iOS and actually addresses the "starting up online" issue as well. Consider this pseudo-code:
document.addEventListener("deviceready", init, false);
var lastStatus = "";
function init() {
//listen for changes
document.addEventListener("offline", disableForm, false);
document.addEventListener("online", enableForm, false);
}
// stuff
function disableForm() {
$("#searchButton").attr("disabled", "disabled");
if(lastStatus != 'disconnected') {
lastStatus = 'disconnected';
navigator.notification.alert(
"Search is disabled while you are offline.",
null,
"Offline!");
}
}
function enableForm() {
$("#searchButton").removeAttr("disabled");
if(lastStatus != 'connected' && lastStatus != '') {
lastStatus = 'connected';
navigator.notification.alert(
"Search is now enabled.",
null,
"Online!");
}
}
Basically, I set a global variable to see if I've switched from one state to another. That handles the Android issue and like I said is harmless on iOS. Notice the enableForm method called in online. This will fire if the application starts online, but we add a check (lastStatus != ''
) that handles the good startup case and suppresses the alert. (The line removing disabled is harmless too.)
Anyway, I hope this helps!
Archived Comments
This is really helpful! Seriously saved my butt.
It was like few minutes to implement this in my project. Great! Thank you!
I have a problem, in my Cordova app the listener "online/offline" doesn't work.
What device are you testing with?
many versions of Android, but none worked
When you remote debug, do you see an error? Did you use *exactly* my code?
no errors. I use just the listeners.
document.addEventListener('online', function() {alert('ON LISTENER');});
document.addEventListener('offline', function() {alert('OFF LISTENER');});
Did you add the plugin? Is your code the exact same as mine?
No. I didn't know that the listener need the plugin. I add the plugin network and worked fine. Thanks for your help
Do you have a complete working example of this? I can't seem to get it to alert me on app load, only if I start on wifi and then disconnect.
I replied on Twitter, but want to reply here too for folks reading: I have a full example in my Cordova book, available via the 'About Me' link above.
I have the similar problem in my two apps: JQM and Ionic. In many situations this plugin says that the device is offline and never gets online. Only if I manually change the state then it works.
Brilliant!!! works like a charm. tested on android 4.2.2 and ios9. thumbs up.
Good Work. Was really having a bad day until i came across this. Thank a lot.
You are welcome!