diff options
author | Kjetil Ørbekk <kjetil.orbekk@gmail.com> | 2012-01-26 15:57:57 +0100 |
---|---|---|
committer | Kjetil Ørbekk <kjetil.orbekk@gmail.com> | 2012-01-26 15:57:57 +0100 |
commit | c2c1e4c5aad74a7fbca5c281f9d8ea2d0ba99ad3 (patch) | |
tree | 03fe8c0a8e3eb1d9d0bac8b3545f08d0d916d8f7 /same-android/src/main/java/com/orbekk/discovery | |
parent | 55beb6df753604996ae61f8a099db40f0906804e (diff) |
Add Discovery service.
DiscoveryService listens to UDP broadcasts.
Diffstat (limited to 'same-android/src/main/java/com/orbekk/discovery')
-rw-r--r-- | same-android/src/main/java/com/orbekk/discovery/Broadcast.java | 82 | ||||
-rw-r--r-- | same-android/src/main/java/com/orbekk/discovery/DiscoveryService.java | 76 |
2 files changed, 158 insertions, 0 deletions
diff --git a/same-android/src/main/java/com/orbekk/discovery/Broadcast.java b/same-android/src/main/java/com/orbekk/discovery/Broadcast.java new file mode 100644 index 0000000..5f592db --- /dev/null +++ b/same-android/src/main/java/com/orbekk/discovery/Broadcast.java @@ -0,0 +1,82 @@ +package com.orbekk.discovery; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import android.content.Context; +import android.net.DhcpInfo; +import android.net.wifi.WifiManager; + +public class Broadcast { + private Context context; + private Logger logger = LoggerFactory.getLogger(getClass()); + private DatagramSocket socket = null; + + public Broadcast(Context context) { + this.context = context; + } + + public synchronized InetAddress getBroadcastAddress() { + WifiManager wifi = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); + DhcpInfo dhcp = wifi.getDhcpInfo(); + + int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask; + byte[] quads = new byte[4]; + for (int k = 0; k < 4; k++) + quads[k] = (byte) ((broadcast >> k * 8) & 0xFF); + try { + return InetAddress.getByAddress(quads); + } catch (UnknownHostException e) { + logger.warn("Failed to find broadcast address."); + return null; + } + } + + public synchronized boolean sendBroadcast(byte[] data, int port) { + try { + socket = new DatagramSocket(port); + socket.setBroadcast(true); + DatagramPacket packet = new DatagramPacket(data, data.length, getBroadcastAddress(), port); + socket.send(packet); + return true; + } catch (SocketException e) { + logger.warn("Failed to send broadcast.", e.fillInStackTrace()); + return false; + } catch (IOException e) { + logger.warn("Error when sending broadcast.", e.fillInStackTrace()); + return false; + } finally { + socket.close(); + socket = null; + } + } + + public synchronized DatagramPacket receiveBroadcast(int port) { + try { + socket = new DatagramSocket(port); + byte[] data = new byte[1024]; + DatagramPacket packet = new DatagramPacket(data, data.length); + socket.receive(packet); + return packet; + } catch (IOException e) { + logger.warn("Failed to receive broadcast.", e); + return null; + } finally { + socket.close(); + socket = null; + } + } + + public void interrupt() { + if (socket != null) { + socket.close(); + } + } +}
\ No newline at end of file diff --git a/same-android/src/main/java/com/orbekk/discovery/DiscoveryService.java b/same-android/src/main/java/com/orbekk/discovery/DiscoveryService.java new file mode 100644 index 0000000..e9aac5f --- /dev/null +++ b/same-android/src/main/java/com/orbekk/discovery/DiscoveryService.java @@ -0,0 +1,76 @@ +package com.orbekk.discovery; + +import java.net.DatagramPacket; + +import android.app.Service; +import android.content.Intent; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.widget.Toast; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DiscoveryService extends Service { + private Logger logger = LoggerFactory.getLogger(getClass()); + private Thread thread = null; + + public final class DiscoveryThread extends Thread { + Broadcast broadcast; + + public DiscoveryThread() { + broadcast = new Broadcast(DiscoveryService.this); + } + + @Override public void run() { + while (!Thread.interrupted()) { + byte[] data = new byte[1024]; + DatagramPacket packet = broadcast.receiveBroadcast(15066); + String content = new String(packet.getData(), 0, packet.getLength()); + Message message = Message.obtain(); + message.obj = content; + toastHandler.sendMessage(message); + } + } + + @Override public void interrupt() { + super.interrupt(); + broadcast.interrupt(); + } + } + + private Handler toastHandler = new Handler() { + @Override public void handleMessage(Message message) { + Toast.makeText(DiscoveryService.this, + (String)message.obj, Toast.LENGTH_SHORT) + .show(); + logger.info("Display toast: {}", (String)message.obj); + } + }; + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Toast.makeText(this, "service start: " + intent.getAction(), + Toast.LENGTH_SHORT).show(); + if (thread == null) { + synchronized (this) { + thread = new DiscoveryThread(); + thread.start(); + } + } + return START_STICKY; + } + + @Override + public void onDestroy() { + Toast.makeText(this, "service stopped", Toast.LENGTH_SHORT).show(); + thread.interrupt(); + } + +} |