Skip to content

Instantly share code, notes, and snippets.

@finnjohnsen
Created September 6, 2012 11:18
Show Gist options
  • Save finnjohnsen/3654994 to your computer and use it in GitHub Desktop.
Save finnjohnsen/3654994 to your computer and use it in GitHub Desktop.
Android UDP Broadcast listener service
package no.nsb.ombord;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import org.apache.http.util.ExceptionUtils;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
/*
* Linux command to send UDP:
* #socat - UDP-DATAGRAM:192.168.1.255:11111,broadcast,sp=11111
*/
public class UDPListenerService extends Service {
static String UDP_BROADCAST = "UDPBroadcast";
//Boolean shouldListenForUDPBroadcast = false;
DatagramSocket socket;
private void listenAndWaitAndThrowIntent(InetAddress broadcastIP, Integer port) throws Exception {
byte[] recvBuf = new byte[15000];
if (socket == null || socket.isClosed()) {
socket = new DatagramSocket(port, broadcastIP);
socket.setBroadcast(true);
}
//socket.setSoTimeout(1000);
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
Log.e("UDP", "Waiting for UDP broadcast");
socket.receive(packet);
String senderIP = packet.getAddress().getHostAddress();
String message = new String(packet.getData()).trim();
Log.e("UDP", "Got UDB broadcast from " + senderIP + ", message: " + message);
broadcastIntent(senderIP, message);
socket.close();
}
private void broadcastIntent(String senderIP, String message) {
Intent intent = new Intent(UDPListenerService.UDP_BROADCAST);
intent.putExtra("sender", senderIP);
intent.putExtra("message", message);
sendBroadcast(intent);
}
Thread UDPBroadcastThread;
void startListenForUDPBroadcast() {
UDPBroadcastThread = new Thread(new Runnable() {
public void run() {
try {
InetAddress broadcastIP = InetAddress.getByName("172.16.238.255"); //172.16.238.42 //192.168.1.255
Integer port = 11111;
while (shouldRestartSocketListen) {
listenAndWaitAndThrowIntent(broadcastIP, port);
}
//if (!shouldListenForUDPBroadcast) throw new ThreadDeath();
} catch (Exception e) {
Log.i("UDP", "no longer listening for UDP broadcasts cause of error " + e.getMessage());
}
}
});
UDPBroadcastThread.start();
}
private Boolean shouldRestartSocketListen=true;
void stopListen() {
shouldRestartSocketListen = false;
socket.close();
}
@Override
public void onCreate() {
};
@Override
public void onDestroy() {
stopListen();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
shouldRestartSocketListen = true;
startListenForUDPBroadcast();
Log.i("UDP", "Service started");
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
@yasiralijaved
Copy link

@sudam-chavan: in phone's idle state (i.e: when phone is locked), the Thread stops execution. If you want to keep running in the background, you need to grab a wakelock (http://developer.android.com/reference/android/os/PowerManager.html)

@pwalther
Copy link

pwalther commented Sep 5, 2013

I think you shouldn't close the socket while listening to broadcast packets.
http://stackoverflow.com/questions/18546771/udp-server-running-on-android-for-lan :-)

Thanks for sharing

@RamanWalia
Copy link

What IP should i give here if i am running this service in Android.
InetAddress broadcastIP = InetAddress.getByName("172.16.238.255");

@abhay-singh
Copy link

http://stackoverflow.com/a/32475076/1687045
UDP data cannot be received while you App is running in the background. Because your client which is sending data as multicast. While you Mobile device screen locked and App is running in the background, in this case mobile hardware there is mac filter and ip filter which only can accept data which point to a particular IP which belongs to device . In simple word is you need to do unicast. For example : There is client which sends data on a particular socket and ip( in your case you may be sending data on 255.255.255.255) and your data is broadcast on a particular port if there is any device ready to receive data on that port which is acting like a server for instance you App is acting like a server and if your app is running on foreground it received data. and When you app in the background App will not.

So that , what you have to do is you have to get the device IP Address and you have to send data on your device IP Address it means you are going to do unicast . In this your app will receive data either running the background or foreground and your mobile screen locked.

@georgethms10
Copy link

georgethms10 commented Sep 1, 2016

Udp broadcast is received, with the above code. In my case i am receiving packets mainly strings from a server at quick constant intervals, all works fine apart from some packet loss(UDP signals are not reliable) my actual problem is after using the service for a long time i am not receiving any signal from the server. Is this because android is killing our service or Thread, or is it because of the the system buffer overflow. I have no insight in network programming and i am stuck. Is there any way we could detect that the thread is stoped and we are not receiving any signals from the server any more and thus restart the whole process?

@spspider
Copy link

spspider commented Dec 14, 2017

bind failed: EADDRNOTAVAIL (Cannot assign requested address) - answer:
socket = new DatagramSocket(port, broadcastIP); change to this ---> socket = new DatagramSocket(port);
how i can send message with that service active? port is busy? can u help?

@alilaldin
Copy link

Hi can anyone help me please . I want to listen on port number 15000 for a UDP packet .
I don't know if the IP is necessary as well . I'm trying to listen to a UDP packet sent from infinite flight app on my device and I don't know what IP address the app is sending the UDP port# is 15000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment