views:

42

answers:

2

I have a service on Android that listens and responds to packets it receives via multicast.

This works most of the time, but unfortunately, I'm finding that every now and again it'll just stop receiving packets. The thread remains blocked on the call to MulticastSocket.receive(), but nothing comes out. I've been slowly trying to track down what triggers this, and I've discovered that turning the wireless off and on again, or changing wireless connection will do it.

In order to successfully continue to listen for my packets I need to close the MulticastSocket and recreate it again. However, I haven't found any way of doing this --- I don't appear to get any notification that something's happened: no intents, no Java exceptions, nothing. I would expect the receive to throw an IOException if the socket became invalid, but this appears not to be happening.

Can anyone offer any insight as to (a) what's actually going on, and (b) how to work around it? Right now my best guess is to continually destroy and recreate the socket every ten seconds or so, and that's just evil.

A: 

Are you acquiring a multicast lock?

WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
MulticastLock lock = manager.createMulticastLock("lock name");
lock.setReferenceCounted(true);
lock.acquire();

It also seems like certain devices block multicast:

http://stackoverflow.com/questions/3623143/multicast-on-android-2-2

Erich Douglass
Yes, I'm acquiring the lock, and I've verified that my device does actually implement multicast.
David Given
+1  A: 

I would think that changing wireless networks is pretty much akin to disabling and re-enabling the network (likely with a different IP and routing), so no surprise that things break.

Perhaps registering for changes in the network info would give you the needed warning?

http://developer.android.com/reference/androi/net/ConnectivityManager.html#CONNECTIVITY_ACTION

and associated pages

Chris Stratton
Yes, that did it. However, it turns out that your multicast lock is destroyed when the connectivity goes away (the long delay was me rewriting my code three times before I figured this out). So, you have to reacquire the lock every time the connection comes back.
David Given