Company http://renewlondon.com/ have the terminal stations that collect all near by mac addresses
Can I via iOS SDK, and Android SDK,do the same thing?
You can access the wifi data using 'WifiManager' and after the scanning the scanresult contain all the data like
BSSID The address of the access point.
SSID The network name.
capabilities Describes the authentication, key management, and encryption schemes supported by the access point.
frequency The frequency in MHz of the channel over which the client is communicating with the access point.
level The detected signal level in dBm.
timestamp Time Synchronization Function (tsf) timestamp in microseconds when this result was last seen.
about the wifi devices.
if you need more related to coding, I think I can help you...
Sample code
WifiManager wManager;
List<ScanResult> wifiList;
wManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
// Inside BroadcastReceiver()
wifiList = wManager.getScanResults();
for (int i=0; i<wifiList.size(); i++){
ScanResult scanresult = wifiList.get(i);
System.out.println("SSID: "+ssid);
System.out.println("RSSI: "+scanresult.level);
System.out.println("Frequency: "+scanresult.frequency);
System.out.println("BSSID: "+scanresult.BSSID);
System.out.println("Capability: "+scanresult.capabilities);
}
Also checkout the BroadcastReceiver().
One way i can think of doing this is making your device as wifi hotspot and use some hidden api to discover devices.You are basically trying to mimic an access point.
Otherwise each device would need some p2p framework on them-either wifi direct on or some other framework like alljoyn or samsung chord which helps in peer to peer discovery
Related
I want the ability to specify and constrain the interface over which UDP datagrams will be sent.
I want to do this without physically disabling the "non wanted" interface. Assume standard INET connectivity is available over the chosen interface (in fact assume that if both interfaces are active then INET connectivity is available over boti)
Most mobile devices will send data over Wifi (in preference to Data interface) if the Wifi interface is enabled; but I want to know how to grammatically "force" UDP over my chosen interface.
There are similar questions already posted, but no question hits the topic precisely. Also I would like the programmed solution to be available (generically or via support library) as FAR BACK as possible in terms of Android SDK versions.
Please note that question "Android how to select wifi network interface to send udp packet" is old and was NEVER answered.
There is an issue with cyanide's answer - how does one ascertain the valid WiFi interface value associated with getName() for ALL devices, current and future?
The solution I have come up with would entail finding the IP address associated with the WiFi interface, then obtaining a UDP socket which is BOUND to this address. Getting a handle onto the WiFi interface can be done by accessing the WiFiManager:
WifiManager wifiManager =
(WifiManager) context.getApplicationContext ()
.getSystemService (Context.WIFI_SERVICE);
.....
int localInetAddressInt = wifiManager.getDhcpInfo ().ipAddress;
ByteBuffer tmp = ByteBuffer.allocate (4);
tmp.putInt (localInetAddressInt);
InetAddress localInetAddress = InetAddress.getByAddress (tmp.array ());
DatagramSocket socket = new DatagramSocket (portNumber, localInetAddress);
Then, when sending over the DatagramSocket (socket), the device SHOULD route the datagram over the appropriate interface, i.e. the interface associated with bound IP address, i.e. the WiFi interface to which the IP address is bound. The IP address would normally be associated with the WiFi interface by the WiFi Access Point via DHCP.
Use NetworkInterface.getNetworkInterfaces" to get list of all active interfaces.
Then for each interface use NetworkInterface.getName.For a wifi it will be wlanXX (Samsung and other), tiwlanXX (Motorola), ethXX (HTC) and e0 (Blackberry). With mobile net it most certainly be rmnetXX.
Then you can use NetworkInterface.getInetAddrress for creating socket.
When WiFi is unavailable, only rmnet appears. Similarly, when WiFi is available, rmnet will not appear, even if Mobile Data is enabled.
Added 30May17 In fact, I doubt that is possible to do what you intend, as it looks like the mobile network is automatically switched off when WiFi is available.
WifiManager wifiManager =
(WifiManager) context.getApplicationContext ()
.getSystemService (Context.WIFI_SERVICE);
.....
int localInetAddressInt = wifiManager.getDhcpInfo ().ipAddress;
ByteBuffer tmp = ByteBuffer.allocate (4);
tmp.putInt (localInetAddressInt);
byte swap; for(int i = 0; i < 2; i++) { swap = tmp.get(i); tmp.put(i, tmp.get(3 - i)); tmp.put(3 - i, swap); }
InetAddress localInetAddress = InetAddress.getByAddress (tmp.array ());
DatagramSocket socket = new DatagramSocket (portNumber, localInetAddress);
This worked for me!
EDIT:
Nope it doesn't. When Mobile data is ON, it doesn't go via WIFI
I need to connect 20+ android devices in a client-server network. Each client Android device will be communicating with the server Android device and vice versa. The client devices do not need to communicate with each other.
The server device would need access to internet for a brief period while connected to the clients.
My question is, can Wi-Fi P2P support that many connections reliably? And if yes, how do I go about implementing them?
Or will I have to ensure that all devices are on the same WLAN?
From experience, in a real-world deployment of an Android Wi-Fi Direct application, 20 devices should not be an issue.
Theoretically, the maximum number of devices in a Wi-Fi P2P group, where the GO is an Android device, is 254. The group owner is assigned the IP, 192.168.49.1. Clients are assigned an IP from the range, 192.168.49.2 to 192.168.49.254.
The group owner address is defined by the following in WifiP2pServiceImpl.java:
/* Is chosen as a unique address to avoid conflict with
the ranges defined in Tethering.java */
private static final String SERVER_ADDRESS = "192.168.49.1";
Determining the range for the clients is done as follows:
In WifiP2pServiceImpl.java, the startDhcpServer(String intf) method will start the DHCP server for a given interface - not a surprise. This method is called when the group has started and the device is the group owner.
Taking a closer look at this code, we can see that on the InterfaceConfiguration object, the link address is set to 192.168.49.1 and the prefix length is 24 (prefix length is the number of bits set in a subnet mask, here equivalent to 255.255.255.0) - this implies the answer, but we can dig a little further.
ifcg = mNwService.getInterfaceConfig(intf);
ifcg.setLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(
SERVER_ADDRESS), 24));
ifcg.setInterfaceUp();
mNwService.setInterfaceConfig(intf, ifcg);
Next, the following commands will restart tethering with the DHCP range specified by the String[], tetheringDhcpRanges. The calls of mNwService (Network Management Service) methods will execute the appropriate netd commands.
ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(
Context.CONNECTIVITY_SERVICE);
String[] tetheringDhcpRanges = cm.getTetheredDhcpRanges();
if (mNwService.isTetheringStarted()) {
if (DBG) logd("Stop existing tethering and restart it");
mNwService.stopTethering();
}
mNwService.tetherInterface(intf);
mNwService.startTethering(tetheringDhcpRanges);
And cm.getTetheredDhcpRanges() is ultimately a reference to the following (ConnectivityManager.getTetheredDhcpRanges() -> ConnectivityService.getTetheredDhcpRanges() -> Tethering.getTetheredDhcpRanges()):
// USB is 192.168.42.1 and 255.255.255.0
// Wifi is 192.168.43.1 and 255.255.255.0
// BT is limited to max default of 5 connections. 192.168.44.1 to 192.168.48.1
// with 255.255.255.0
// P2P is 192.168.49.1 and 255.255.255.0
private String[] mDhcpRange;
private static final String[] DHCP_DEFAULT_RANGE = {
"192.168.42.2", "192.168.42.254", "192.168.43.2", "192.168.43.254",
"192.168.44.2", "192.168.44.254", "192.168.45.2", "192.168.45.254",
"192.168.46.2", "192.168.46.254", "192.168.47.2", "192.168.47.254",
"192.168.48.2", "192.168.48.254", "192.168.49.2", "192.168.49.254",
}
and:
mDhcpRange = context.getResources().getStringArray(
com.android.internal.R.array.config_tether_dhcp_range);
if ((mDhcpRange.length == 0) || (mDhcpRange.length % 2 ==1)) {
mDhcpRange = DHCP_DEFAULT_RANGE;
}
in com.android.server.connectivity.Tethering.
Of course, it is possible for the device manufacturer to change this code, so this is also worth considering.
For those planning to deploy applications where there will be many users, a mechanism to allow a more than one device to be GO is required. If data needs to be synchronised between devices, it is simple to simulate "churn" and have GOs only be a GO for a time period before becoming a client to another GO and synchronising any data.
The max number as far as I know is not specified, so you would need to test that out to be certain. Also there could be differences between hardware.
Anyway, the basic implementation would be rather simple. The server would call GreateGroup, so it would be the Groupowner in all cases. And then start locals service advertising. Clients then would simply look for the advertisement and once they see it, they would start connection process to the server. One the server connection is made over Wifi direct you would simply start socket communications from the client to the server (server would have listening socket on all times).
Note that connection would require user to click on the dialog showed when client tries to connect to the group owner. And if you want to get rid of this. Then you could actually use the Accesspoint created by GreateGroup, and add the access point name as well as the password to the advertising. Then your clients could actually use the accesspoint to connect (like to any Wlan accesspoint)
Note though that the Wifi Direct way, would not interfere with Wifi connections, not would it require it. But the accesspoint way would mean that any existing Wifi connection from the client would be disconnected, and the device thinks that the connection made to the server would provide normal internet connectivity.
Remember that devices don't need to be connected to a network to connect to each other. Wi-Fi Direct allows them to connect directly.
Here is a list of Wi-Fi Direct resources that you may find useful: https://groups.google.com/forum/#!topic/wi-fi-direct/uWpuOzHY6y0
I'd recommend following Android's Service Discovery Demo and try implementing it yourself. And here is the source code for the demo.
Recently I found a seemingly cool way to communicate between devices using Google Nearby API. Skimming through the documentation didn't answer my question - is it possible to measure the connection signal strength in real time, or should I invent some kludges e.g. measuring time of sending and receiving data or something else?
Thank you.
As a developer of Nearby API stated in thread Google Nearby Messages - Cancel initial link between devices :
Today, Nearby doesn't expose distance directly
He suggests to use BLE RSII instead
You can get a rough approximation of distance by measuring BLE RSSI if one of the devices is capable of BLE advertising. This will be sensitive to how the device is held, antenna gain and environmental factors but better than random.
There's not a straight-forward "tape measure" API, though.
If your question really is about "Nearby Connection API" and not "Nearby Messages API", you could simply check the Wifi-Signal Strength:
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
int numberOfLevels = 5;
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int level = WifiManager.calculateSignalLevel(wifiInfo.getRssi(), numberOfLevels);
I am working on an app that would allow indoor navigation using hardware devices that emit wifi signals in large public places such as hotels and hospitals. Each location would have multiple devices and each device would be unique so that we can identify the exact location of the device/person.
For this I don't want the user to connect to the wifi, if only a scan of the network was possible which could determine the current wifi beacon the mobile is closest to would do the job. I decided to use Android's WifiManager for the task:
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi.setWifiEnabled(true);
wifi.startScan() ;
List<ScanResult> mScanResults = wifi.getScanResults();
String s = "" ;
for(ScanResult result: mScanResults){
Log.d("Wifi", result.SSID) ;
}
None of the attributes for result seem to be appropriate for use as a UID for Wifi Beacon, I have two questions:
a) Can we use something like a BSSID for this purpose?
b) Can I write my own wifi manager class and then somehow negotiate a handshake with the wifi where it just tells me who it is without connecting? If so please share resources for doing the same.
I am trying to create a help wizard to recover from bad network connections in the app. One test case I hope to handle is the case where an end user has WiFi turned off, WiFi is available, and the mobile network is slower than the WiFi network. In this event, I want to be able to (1) discover the available WiFi network s, (2) find the WiFi network speed, (3) Compare its speed to the mobile network speed, (4) digest the user changes to the faster network.
For this to work, I need to know how to programmatically get information on available connections. Is that something we can do? If so, how can we tell what connections are available? Thanks in advance.
Task-1: Discover the available WiFi network
This can be done by getting WifiManager's instance from the System.
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
wifiManager.getScanResults();
// The above is an async call and will results are available System will broadcast `SCAN_RESULTS_AVAILABLE` intent and you need to set a `BroadCastReceiver` for it.
// And get the results like this
List<ScanResult> results = wifiManager.getScanResults();
Task-2&3: find the network speed
This link gives an answer to your question about how to get network speeds of wifi and mobile network
Wifi:
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
int linkSpeed = wifiManager.getConnectionInfo().getRssi();
In case of mobile it should work:
TelephonyManager telephonyManager = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
CellInfoGsm cellinfogsm = (CellInfoGsm)telephonyManager.getAllCellInfo().get(0);
CellSignalStrengthGsm cellSignalStrengthGsm = cellinfogsm.getCellSignalStrength();
cellSignalStrengthGsm.getDbm();
Then You should compare this signal levels and if WIFI signal is better keep it turn on, but if mobile is better disconnect wifi
Task-4: Switching to the option with higher speed
In Android by default, if wifi is on and connected then your mobile network won't be used. Hence to use mobile data you must either disconnect from all available wifi-networks or switch off the wifi.
I will also suggest you to read link this, this and this for getting more information on how to get connection speed.