Coding for a mobile platform has always been a frustrating experience ever since J2ME. Right now I really hope, that Jolla Mobile will succeed and roll their thingie to the market, since both iOS and android are smoking crap. But for now – I choose droid as a lesser evil.
So, a few days ago I needed to ping the internets from my app, to check if the connection is live. It’s been less than a week since a friend told me of all the ‘fun’ he had with SCNetworkCheckReachabilityByName
on iOS for that purpose.
So, after giving the specs a read, I quickly threw up an activity, a broadcast receiver, moved the actual pings to a different thread placed in a service, to keep render thread clean responsive. I ended up with the following code.
(Please note, that despite I write apps in java for droid, used to write J2ME apps quite a few times, I’m NOT a java coder, so it may look like crap)
/* proper way. works on local ips, sucks on 8.8.8.8 */ public int doInAvaliable(int count, int delay, String host) { InetAddress in; in = null; int ok = 0; int i; for (i = 0; i < count; i++) { if (!active) return ok; try { in = InetAddress.getByName(host); } catch (UnknownHostException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try { if (in.isReachable(delay)) { Log.d(TAG, "Network looks fine"); doBroadcast(scanResultsReceiver.action_ping_ok); ok++; } else { Log.d(TAG, "Timeout, it's dead"); doBroadcast(scanResultsReceiver.action_ping_fail); } try { Thread.sleep(delay); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (IOException e) { Log.d(TAG, "Caught an exception: " + e.toString()); } } return ok; } |
So, it’s simple, ping a few times, send results in broadcasts to the GUI. However, it worked when pinging a router IP, but failed with google’s 8.8.8.8. Just fail.
Thinking for a while, reading more specs, stackoverflow, calling {Google, Oracle, Sun} and others retarted… You know, usual ‘hate-driven development’… I managed to squeeze this code:
/* Is crappy, doesn't work at all */ public int doSocket(int count, int delay, String host) { Socket socket = null; boolean reachable = false; int i, ok = 0; for (i = 0; i < count; i++) { if (!active) return ok; try { Thread.sleep(delay); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { socket = new Socket(host, 80); ok++; doBroadcast(scanResultsReceiver.action_ping_ok); } catch (IOException e) { doBroadcast(scanResultsReceiver.action_ping_fail); } finally { if (socket != null) try { socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } return ok; } |
And got another fail. After trying a few more solutions, I ended up with the most ugly and dumb way that actually worked for me.
public int doPing(int count, int delay, String host) { int i, r; int ok = 0; for (i = 0; i < count; i++) { r = 3; if (!active) return 0; try { Thread.sleep(delay); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try { r = pingHost(host, delay); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (r == 0) { doBroadcast(scanResultsReceiver.action_ping_ok); ok++; } else doBroadcast(scanResultsReceiver.action_ping_fail); } return ok; } /** * Ping a host and return an int value of 0 or 1 or 2 0=success, 1=fail, * 2=error * * Does not work in Android emulator and also delay by '1' second if host * not pingable In the Android emulator only ping to 127.0.0.1 works * * @param String * host in dotted IP address format * @return * @throws IOException * @throws InterruptedException */ public static int pingHost(String host, int timeout) throws IOException, InterruptedException { Runtime runtime = Runtime.getRuntime(); timeout /= 1000; String cmd = "ping -c 1 -W " + timeout + " " + host; Process proc = runtime.exec(cmd); Log.d(TAG, cmd); proc.waitFor(); int exit = proc.exitValue(); return exit; } |
And despite being a dirty hack, it worked like a charm.
It would be helpful if you could post a full java class or a better tutorial.. for example the function of dobroadcast is not clear.. or if you could provide a source code to this
After a few hours of going thru the same things you went thru this saved me…THANKS!
Thank you very much for your good sources.
That are very helful for me.
Thanks again.