-
-
Save finnjohnsen/3654994 to your computer and use it in GitHub Desktop.
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; | |
} | |
} |
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
What IP should i give here if i am running this service in Android.
InetAddress broadcastIP = InetAddress.getByName("172.16.238.255");
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.
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?
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?
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
@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)