How to receive Multicast packets on Android - android

I'm trying to receive data from a multicast address, but the call to MulticastSocket.receive() blocks until a timeout takes place.
I did some network sniffing and found out that my device (and the emulator) never send a MulticastSocket.joinGroup request.
I tried running the same Java code from my PC as a standalone application and it worked well. Could it be that the Android platform blocks IGMP join requests?
Has anyone succeeded with Multicast on Android before?
My manifest file contains the following permission:
I am running my application on 2.1 (Both emulator & device).
Any ideas anyone?
Thanks,

Lukas gives the best explanation and examples that I've seen on his blog: http://codeisland.org/2012/udp-multicast-on-android
In summary:
1. You need the permissions:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
2. You need a lock:
WifiManager wifi = (WifiManager)getSystemService(Context.WIFI_SERVICE);
if (wifi != null){
WifiManager.MulticastLock lock = wifi.createMulticastLock("mylock");
lock.acquire();
}
3. You have to have a device that supports receiving multicast. Or you can follow his work around for rooted devices.

As it seems, there is no proper multicast support in the emulator.
Here's a bug report and related thread. It is being fixed for froyo.

You need to do something like this
WifiManager wifi = (WifiManager)getSystemService( Context.WIFI_SERVICE );
if(wifi != null)
{
MulticastLock mcLock = wifi.createMulticastLock("mylock");
mcLock.acquire();
}
Reference:
http://developer.android.com/reference/android/net/wifi/WifiManager.MulticastLock.html

I read all 2.1 devices not supporting IGMP stack.
IGMP was missing on different HTC, Samsung, and Motorola devices of all android version from 2.1 up to 3.2.
Link in which i read http://www.programmingmobile.com/2012/01/multicast-and-android-big-headache.html

Related

Bluetooth Scanfilter UUID in android 7.1.1 Not working but works in 6.0.1

Have an app that is trying to connect to a Laird Bluetooth BLE chip but when using the Scanfilter it cannot be found. In fact I cannot seem to see any bluetooth devices when using a ScanFilter.
If I comment out adding the filter //filters.add(filter); I can see the devices I wish to connect to and can use them as expected on the 7.1.1 device.
Works on a Nexus 5 with android 6.0.1 with the scanfilter
Does not work on an Asus Zoom 3 7.1.1
I suspect there is some sort of android/os bug at this point but cannot figure out why simply using the filter (that works on an earlier version of android)
Note: App has location permission and bluetooth permissions and requests them in the activity that is scanning for bluetooth
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
Code:
ScanFilter filter = new ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString("6e400002-b5a3-f393-e0a9-e50e24dcca9e"), ParcelUuid.fromString("000000000-1000-0000-0000-000000000000")).build();
List<ScanFilter> filters = new ArrayList<ScanFilter>();
filters.add(filter);
ScanSettings scanSettings =
new ScanSettings.Builder().build();
bluetoothLeScanner.startScan(filters, scanSettings, mLeScanCallback);
cancelButton.setText(R.string.cancel);
When using the above code it works, on 6.0.1 but not on 7.1.1 I even reduced the mask to a single digit, and can confirm the device UUID in the callback method when debugging and it should be matched.
Asked for permission, even followed
This question and answer
But it was just a different way of asking for permissions I had already requested. But tried the methods described here anyways. Still would not list devices using the Scanfilter, but works fine if I remove the filters.add(filter); line

Why does multicast reception not work on some Android devices?

It seems multicast reception does not work on some Android devices. I can not receive multicast with 4 out of 13 test devices. On those 4 devices it seems the app does not send the IGMP request to join the multicast group.
The code to receive the multicast looks like so:
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
WifiManager.WifiLock wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, TAG);
WifiManager.MulticastLock multicastLock = wifiManager.createMulticastLock(TAG);
multicastLock.setReferenceCounted(true);
wifiLock.acquire();
multicastLock.acquire();
try {
MulticastSocket socket = new MulticastSocket(32123);
InetAddress group = InetAddress.getByName("224.1.2.3");
socket.joinGroup(group);
DatagramPacket packet;
byte[] buf = new byte[256];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
socket.leaveGroup(group);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
multicastLock.release();
wifiLock.release();
The app has the following permissions:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
To demonstrate the problem I created a little test project using the above code on GitHub: MulticastTest.
Is there a problem with my code? Do I miss a permission?
EDIT 1: This problem does not seem to relate to a specific Android version. I can reproduce the behaviour on Android 4.x, 5.x, and 6.x.
EDIT 2: There is a related question.
Bad news: This seems to be related to the affected devices. There is no /proc/net/igmp available exactly on those devices that can not receive the multicast traffic. As already expected this very likely leads to the missing join group request (IP_ADD_MEMBERSHIP).
We tried with the Android Java API, BSD sockets, and Boost.Asio. Same result with all three options.
We verified the problem with an app called Multicast Tester. This app has the same problem on the same devices as our app. No IGMP request is send by the device and of course no multicast traffic is received.
There are some open and closed (with statuses Obsolete and WrongForum) issues in the Android issue tracker. I think the closed issues are marked as Obsolete/WrongForum because it is not a problem in Android but specific to the affected devices (setup).
It seems the kernel on the affected devices was built with
CONFIG_IP_MULTICAST=n
in the kernel configuration file. That's also why /proc/net/igmp is not available on the affected devices. It obviously is only created when CONFIG_IP_MULTICAST is set as can be seen in the Linux kernel code.

Enabling Wifi direct in Android 4.0

I have bought a new android 4.0.3 tablet- Micromax Funbook P300 to learn developing android applications.
I started with Wifi Direct, so that the tablet could be used as a remote for robotic platform.
To my disappointment the stock OS doesn't provide this function in the settings menu.
Is it possible to check if we can programatically start wifi direct feature?
If not can someone direct to some tutorials which addresses this?
Thanks.
The Android SDK contains a sample application for using the DirectWiFi mode:
WiFiDirectDemo - Wi-Fi Direct Demo
The used API itself is located in android.net.wifi.p2p
WiFi Direct should be supported by Android 4.0.3 (it has been around since Android API 14, or Android 4.0). It is possible that your tablet does not support WiFi Direct due to a hardware limitation, but I doubt it. You probably aren't seeing it in the settings because there is a custom Android skin running on the tablet that prevents you from seeing it, or maybe the WiFi Direct settings interface wasn't implemented until Android 4.1 or something.
Whatever the case, you can test it easily in the code.
First, put the proper permissions in your manifest.xml
http://developer.android.com/training/connect-devices-wirelessly/wifi-direct.html#permissions
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.nsdchat"
...
<uses-permission
android:required="true"
android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission
android:required="true"
android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission
android:required="true"
android:name="android.permission.INTERNET"/>
...
Next, try initializing the Android WiFiP2pManager class to see if it is supported.
http://developer.android.com/reference/android/net/wifi/p2p/WifiP2pManager.html
public void onCreate(Bundle savedInstanceState) {
WifiP2pManager manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
WifiP2pManager.Channel channel = manager.initialize(this, getMainLooper(), null);
}
Where I put null, you could pass a callback to check for failure. If it works, follow the rest of the Wi-Fi Direct guide to create your app.
He's not asking for a coded program example, so much as a way to programatically switch on the technology (ie one line of code). As far as I am aware there is no way to do this. It all has to be done from within your devices settings. While some devices allow Wi-Fi Direct to be switched on, other devices treat it the same as having regular Wi-Fi enabled - have you tried this? And have you checked if the P300 even supports Wi-Fi Direct?

Alternative to enabling data connection

On android 2.3 the permission <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> is not allowed anymore for non-system applications. Is there an alternative to enable/disable data connection, besides that one where you modify APN name? I found Data Enabler Widget on Android Market that does that, but I can't seem to understand how. Can anyone help me?
Thanks! - Alex Ady
I don't know how to change data connection (3g, 2g, etc), but you can enable/disable wifi connection through this:
WifiManager wifiManager = (WifiManager)this.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(boolean enabled);
I found a solution to my problem, so I'm closing this question. The alternative is to simply display the mobile settings activity if a level 10 API or higher is detected, or continue with direct enable from code otherwise. I keep the android.permission.MODIFY_PHONE_STATE, but only use it the API is under level 10.

Multicast on Android 2.2

Has anyone gotten Multicast to work on Android 2.2, specifically JmDNS for Bonjour service detection. There are many questions & answers from the Android 1.5->2.0 timeframe, including on stackOverflow, that indicate varying levels of success, and a bug in the bug tracker that indicate it was fixed, and closed, for 2.2 (http://code.google.com/p/android/issues/detail?id=2323) . I've tried the "TuneControl" source code, but that worked on ~1.5 and has not been updated, and does not work for me on 2.2.
So, the questions...
1) Has anyone seen multicast work on 2.2, specifically JmDNS, and specifically for Bonjour service detection?
2) What is necessary in code to make this work?
I'm using the appropriate permissions:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
I acquire the multicast lock:
WifiManager wifi = (WifiManager)getSystemService( Context.WIFI_SERVICE );
if(wifi != null)
{
MulticastLock mcLock = wifi.createMulticastLock("mylock");
mcLock.acquire();
...
And then try to start jmDNS to look for servers:
mdns = JmDNS.create(addr, HOSTNAME);
jmdns.addServiceListener(TOUCH_ABLE_TYPE, listener);
jmdns.addServiceListener(DACP_TYPE, listener);
...
The listener never sees any services. I've verified using Wireshark that the request packets are sent, and that the server responds, but the response packet are never seen by the socket listener code in the jmDNS library.
So... am I missing something? Is this still a bug? Has ANYONE gotten anything even remotely like this to work???
To (rudely) answer my own question, more information was provided at http://code.google.com/p/android/issues/detail?id=2917#c48 by another person. For posterity, as they say, here is brian.ro...#gmail.com's answer...
"I've spent quite a bit of time
debugging mDNS issues with JmDNS on my
Evo and HTC Hero (CDMA). What I found
is there appears to be a filter in
place in the broadcom wireless driver
on the Evo (and since I'm getting a
similiar reprt from an HTC Desire user
- with the same chipset, presumably that handset as well). The filter, by
default, blocks any non-unicast or
network broadcast traffic, including
multicast. Apparently the theory was
it's a battery saver.
The problem appears to be the
wpa_supplicant on the Evo does not
support removing those filters when
you get a MulticastLock. (Check the
log output right after you get the
lock and you'll see what I mean).
Unfortunately what has happened is the
hardware vendors have fragmented
multicast support.... :("
So... it appears this is a device problem more than a coding problem. D'oh. :( If I get an opportunity to test on another device...
I've been doing a bit of research into this, and I believe it is a problem with Android in general, and fixed in or around Android 2.3.7.
It's a bit too anecdotal, but here's what I tested:
HTC Desire, 2.2, stock: fail
HTC Desire, 2.3.7, CyanogenMod: success
Motorola Milestone, 2.1-update1: fail
HTC Desire S, 2.3.3: fail
Acer Iconia A501, 3.2.1: success
Samsung something, 2.3.3: fail
HTC Legend, 2.2 I think: fail
When I say 'fail', in fact they were all able to send multicast messages to the 'success' devices, but never receive anything back except their own messages - as jldupont describes.
Note that the multicast IM app Kouchat is only available for 2.3.7 onwards, even though it can be made to compile for as far back as 2.1, which gives further credence to this theory.
I think the other reason is your AP does not support.
Other:Computer send/recieve to/from Android
your computer must only use WIFI,Best off all other network

Categories

Resources