Note that there are some explanatory texts on larger screens.

plurals
  1. POIs Multicast broken for Android 2.0.1 (currently on the DROID) or am I missing something?
    primarykey
    data
    text
    <p>This code works perfectly in Ubuntu, Windows, and Mac OS X. It also works fine with a Nexus One running Android 2.1.1.</p> <p>I start sending and listening multicast datagrams, and all the computers and the Nexus One will see each other perfectly. Then I <strong>run the same code on a Droid</strong> (Firmware 2.0.1), and <strong>everybody will get the packets sent by the Droid, but the droid will listen only to its own packets</strong>.</p> <p>This is the <code>run()</code> method of a thread that's constantly listening on a Multicast group for incoming packets sent to that group.</p> <p>I'm running my tests on a local network where I have multicast support enabled in the router. My goal is to have devices meet each other as they come online by broadcasting packages to a multicast group.</p> <pre><code>public void run() { byte[] buffer = new byte[65535]; DatagramPacket dp = new DatagramPacket(buffer, buffer.length); try { MulticastSocket ms = new MulticastSocket(_port); ms.setNetworkInterface(_ni); //non loopback network interface passed ms.joinGroup(_ia); //the multicast address, currently 224.0.1.16 Log.v(TAG,"Joined Group " + _ia); while (true) { ms.receive(dp); String s = new String(dp.getData(),0,dp.getLength()); Log.v(TAG,"Received Package on "+ _ni.getName() +": " + s); Message m = new Message(); Bundle b = new Bundle(); b.putString("event", "Listener ("+_ni.getName()+"): \"" + s + "\""); m.setData(b); dispatchMessage(m); //send to ui thread } } catch (SocketException se) { System.err.println(se); } catch (IOException ie) { System.err.println(ie); } } </code></pre> <p>This is the code that sends the Multicast Datagram out of every valid network interface available (that's not the loopback interface).</p> <pre><code>public void sendPing() { MulticastSocket ms = null; try { ms = new MulticastSocket(_port); ms.setTimeToLive(TTL_GLOBAL); List&lt;NetworkInterface&gt; interfaces = getMulticastNonLoopbackNetworkInterfaces(); for (NetworkInterface iface : interfaces) { //skip loopback if (iface.getName().equals("lo")) continue; ms.setNetworkInterface(iface); _buffer = ("FW-"+ _name +" PING ("+iface.getName()+":"+iface.getInetAddresses().nextElement()+")").getBytes(); DatagramPacket dp = new DatagramPacket(_buffer, _buffer.length,_ia,_port); ms.send(dp); Log.v(TAG,"Announcer: Sent packet - " + new String(_buffer) + " from " + iface.getDisplayName()); } } catch (IOException e) { e.printStackTrace(); } catch (Exception e2) { e2.printStackTrace(); } } </code></pre> <p><strong>Update (April 2nd 2010)</strong> I found a way to have the Droid's network interface to communicate using Multicast: <a href="http://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock.html" rel="nofollow noreferrer">WifiManager.MulticastLock</a>.</p> <pre><code>MulticastLock _wifiMulticastLock = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE)).createMulticastLock("multicastLockNameHere"); _wifiMulticastLock.acquire(); </code></pre> <p>Then when you're done...</p> <pre><code>if (_wifiMulticastLock != null &amp;&amp; _wifiMulticastLock.isHeld()) _wifiMulticastLock.release(); </code></pre> <p>After I did this, the Droid started sending and receiving UDP Datagrams on a Multicast group.</p> <p><strong>Update Jul-6-2010</strong></p> <p>Per request, here's my current code, the next method exists on an abstract class that can be used for both Broadcast and Multicast receivers.</p> <pre><code>public void run() { onInit(); try { byte[] data = new byte[65535]; while (isProcessing()) { try { DatagramPacket receivedDatagram = new DatagramPacket(data, data.length); _socket.receive(receivedDatagram); onDatagramReceived(receivedDatagram); data = new byte[65535]; // This pattern is for saving memory allocation. } catch (InterruptedIOException e) { if (!isProcessing()) break; } } // while } catch (Exception e) { Log.e(TAG, e.getMessage(), e); } finally { onStop(); _socket.close(); _socket.disconnect(); } } </code></pre> <p>Your extending classes should implement <code>onInit()</code> and <code>onDatagramReceived()</code></p> <p>For a <strong>Multicast</strong> receiver, <code>onInit()</code> <strong>looks something</strong> like this:</p> <pre><code>_socket = new MulticastSocket(PORT_MULTICAST); InetAddress groupAddress = InetAddress.getByAddress(MULTICAST_GROUP_ADDRESS); InetAddress groupInetAddress = FrostWireUtils.fastResolveAddress(groupAddress); //reflection hack to not resolve ips try { _socket.setSoTimeout(500); _socket.setTimeToLive(MULTICAST_TTL_GLOBAL); _socket.setReuseAddress(true); _socket.setNetworkInterface( WifiUtils.getWifiNetworkInterface()); _socket.joinGroup(groupInetAddress); WifiUtils.lockMulticast(); } catch (Exception e) { Log.e(TAG, e.getMessage(), e); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload