Why do WiFi Direct peers vanish - android

The question is based on an observation I made while playing around with the WiFi Direct Demo Application rolled out by google.
Why does the shown list of Available peers tend to shorten even when the WifiDirect enabled devices are in close range? However, if I manually 'search' for available peers again, the list of peers grows. Well the latter seems a normal behavior, whereby mManager.discoverPeers() is called first which subsequently invokes a call to the callback function onPeersAvailable() to give a new set of peers if changed.
But why would onPeersAvailable() get called when the phones are just idle but still nearby and thus shorten the list of peers?
Thanks

Related

How to clear cache of discovered peers

In my Android application, I am using the WifiP2pManager API to discover peers with Wifi Direct. It works, and it discovers them as expected after calling
wifiP2pManager.DiscoverPeers(myChannel, myActionListener);
But sometimes, if I turn off a device after it has already been discovered, it still appears in the WifiP2pDeviceList when I discover peers again. I actually have to turn the wifi off and on from the device (that's discovering peers) so that it doesn't show the device (that's off) anymore. Is there a chache that I can clear instead?
I'm developing this app in Xamarin.Android, but an answer in Java/Kotlin would be fine.
EDIT
Just realized that if I wait for a minute, the turned off device doesn't appear in the list of discovered peers anymore. Still would like to know if there's a way to clear the cache sooner.
The device does not go away until "discoverPeers()" is called again by the system, which is currently set (in android framework) to be called after 60 sec.
This is normal behavior, probably nothing much you can do about it.
An answer to explain the behaviour: https://stackoverflow.com/a/25154034/3260008

Android: wifi p2p disabling event (not disabled)

I register a receiver for the action
WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION
In onReceive() I get this action and compare the EXTRA_WIFI_STATE to this two cases
case WifiP2pManager.WIFI_P2P_STATE_ENABLED:
case WifiP2pManager.WIFI_P2P_STATE_DISABLED:
However I need to know when Wifi is going to be disabled but not disabled yet, in order to call some methods of the WifiP2pManager. I have to call
manager.clearLocalServices
before wifi is disabled, otherwise it fails and the service is not removed.
How can I get the "disabling" event?
I think there is a misunderstanding here. Most apps that use Wifi Direct search for peers and maintain a list of available peers.
However, you will often find that implementations do not remove peers when they are no longer available. When WifiP2pManager.WIFI_P2P_STATE_DISABLED, then by definition, the device is no longer available to other peers. So any peers that think that the device is still available probably just haven't updated the list of "available" peers, that is, they haven't checked which devices are still available.
To verify what the behavior truly is, you should try searching for the device AFTER the state has changed to WIFI_P2P_STATE_DISABLED. If peers are still able to find your device after this event, then there is a fundamental bug in the Android implementation, which I doubt.

Android: Auto-reconnect BLE devices

My goal is to get the Android device to reconnect to a BLE device that it has previously connected to without user intervention in the same way it does for a classic BT paired device does (even works through power cycles).
One of the ideas of BTLE devices is that one saves service, bonding, and enabling states such that a reconnect is VERY fast and consumes very little power on the peripheral.
What I have done seems to work but it works poorly.
The first step is to connect or pair and connect to a new device setting the 'autoconnect' parameter to 'true'.
When the device disconnects, do not call gatt.close(). Everywhere I look I see that one should call gatt.close(). But if I do call gatt.close() the Android central app never reconnects. I have tested this many times.
If I have not called gatt.close() and have not power cycled the Android, the auto-connection usually happens. Sometimes it can take a long time, especially after version 5.0. It is, however, unreliable and it may be unreliable due to a very low-duty scan cycle and the device quitting advertising before a scan cycle actually detects the advertisement. I am not sure because there is no way to detect the scanning operation like there is advertisements! It is also possible the scanning stops after a certain amount of time but there is no documentation on that.
So what I think I need to do is to somehow set the background scan rate used by the Android to a higher duty cycle (only possible in 5.0 and up) when auto-connect has been set but I do not know how to do this. I do not want to start my own scan but somehow set the background scanning rate used by Android for the reconnect. Does anyone know how to do this? Does anyone really know how autoconnect and gatt.close() are to work?
Maybe the auto-connect was NOT meant to re-connect as I indicated above?
Well after many trials and tribulations this is how I best get the Android to auto connect with the only user action being to first select the device (if using the settings menu then first pairing).
You have to trap the paired event in a BroadcastReceiver and do a BluetoothDevice.connectGatt() setting the autoconnect to true. Then when the device disconnects, invoke a gatt.connect().
Update: While the above approach works in general, it is sometimes agonizingly slow probably because the pending connection uses extremely conservative scan rates. The other downside is that for each device you want to auto-reconnect to you have to keep a BluetoothGatt object performing a pending connection. In the embedded world this is insane. Instead what one does is continuously scan and connect to a desired device by inspecting its advertisement. One saves only the minimal amount of data about the device (the services, its paired state and keys, etc.). When an advertisement is captured you see if it is one of your known devices and connect to if it is.
I tried the equivalent on Android. Scan all the time (low power rate) and connect to advertisements of interest, and maintain a class representing a known device. There are some annoying details in this approach (like turning off scanning while connecting and restarting after connected) but it basically works without the overhead of maintaining connections. BUT there is one exception I do not understand. One pre-paired device's advertisements are never seen by the scanner. However, if I invoke a pending connection to this device, I re-connect. I do not understand this at all. On my embedded platforms it works as it should.
If anyone else has tried this approach for auto-reconnecting, please share your experiences!
I have discovered the reason the pre-paired device is not seen by Android. Android only reports scan results IF the device responds to a scan request. Once paired, this device only emits advertisements and ignores scan requests, so the Android system does not pass up its advertisements in the ScanCallback. Thus in order to work using the scan approach, I have to use the pending connect approach for those specific devices. It just seems like you can't win!
============= UPDATE 2020
Many years have passed and I have a lot more experience with the background scan approach. If one keeps the supported platforms 5 and up, one can use only the newest scanner APIs and use filters, eliminating the need to decode the raw advertisements yourself. I have also found that connection and re-connection is snappier if you DONT turn off scanning while connecting. I know it goes against all documentation, but it works and on some platforms allowed connections to happen that otherwise did not. Also, to date, I have found only one (health) device that needs pending connects. Disclaimer: All I have ever worked with is health devices.
This is how I was able to do it for my application.
I first stored the address of the device in a SharedPreference then in gattClientCallback funtion of my BluetoothLeService
else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_DISCONNECTED;
DeviceActivity.runOnUI(() -> {
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String name_dev_1 = sharedPreferences.getString("Dev_1", null) ;
connectToDevice(name_dev_1);
disconnectGattServer();
});
}
}
What this does is if your device is disconnected it will keep on trying to connect to it until a connection is established.

Will an Android Nearby advertisment trigger any kind of UI on nearby devices?

Following this article i discovered a comment stating that
Advertising with an AppIdentifer lets other devices on the network discover this application and prompt the user to install the application.
How does the second user interact with this solution? Is there any kind of UI, like a notification? Has anybody tried this yet? Is this available only for a specific use case like Android TV devices?
Nearby Connections leaves it to you, the developer, to create UX that makes sense for your use-case. There are two sides to the API. The advertising side and the discovering side. Nothing happens when you advertise unless another device calls the discovery API and even then, it's up to your app whether or not to display anything.
When a second device invokes startDiscovery it will get an onEndpointFound callback. That's an opportunity to display UX or call sendConnectionRequest (to establish the connection)

How to find a Group owner device automatically

I am developing an android application , in which i need to connect multiple devices with each other using WiFi Direct. i am done with multiple connections as i am aware of connecting devices through one group owner device as if all client devices sends a request to one specific device.But i am doing it manually because if all client devices clicks on a name of one specific device then it is OK with multiple connections.But now i need to do it programmatically so that one device automatically becomes group owner and all other devices should automatically send connection request to that specific device.Please help me with this problem.I am stuck at this point from last many days.Thanks in advance for your help.
What is the exact logic/problem there ?
Does it has to be fully automated ? or can the group owner selection be manual ?
In case all devices start the connections same time, then you must really do either manual selection, or have the devices somehow negotiate how they are selecting the group owner. Selection case you be really easy:
Group owner uses createGroup to create the group for connection
Group owner adds local service, and starts Peers Discovery and keeps it running (generally my research has shown that if there is no active connection, or peer discovery, the device local service is invisible for other dervices)
Clients, simply do Peer & Service discovery and do the connections
if there is possibility that the devices appear is same place different times, then of course the logic for fully automatic would be simple.
First all devices advertise & search for devices same time
with The first connection one device is set as Group owner and the other gets to be client
Both devices stop Peer & service discoveries
The Client device stops advertising the service, thus making the Group owner only visible service for any devices appearing into the vicinity, thus they would be connecting to it.
Anyways, I would have small example project which might help you at: Thali/WDConApp, anyways, with WiFi-Direct you would need to manually allow connections, You would try doing the pairing as I explained in my Blog, though I have to admit that since tuesday this week, I'm not so sure if it really works that way. I would need to do some additional tests (when I have time) to verify that I would actually know how it behaves.
Then, if you don't want to have the manual user acceptance of the dialogs, I would have two options for you. You could use unsecured Bluetooth connection as is used in Thali/BtConApp, or you could use WiFi Direct Access points for connectivity.
Note that Using the access point connectivity, will cut off any other WiFi connections. I do have example for it as well, and I actually uploaded it while writing this reply and you can find it from Thali/WAPConApp. Note that its just my first test version, and I'll likely do loads more work on improving it.

Categories

Resources