I've been working with the Android WifiP2pManager to discover specific services on other devices. I'm wondering if there is a known timeout period for the function
public void discoverServices (WifiP2pManager.Channel c, WifiP2pManager.ActionListener listener)
I can't find any resources on it in the Android API. I'm aware that I can set a listener for a successful discovery, but I don't know how to tell if no discovery has been made.
Additionally, is there any way to stop discovery without entirely stopping the wifi manager's functionality?
Thanks in advance for any help!
As far as I know the clearServiceRequests() should work fine for cancelling service discovery.
In general I have also not found any docs for timeout, thus I have been using 1 minute timeout timer to fix the issue.
Notice though that you should cancel the timeout timer once you have gotten the callback called once, after that you should just wait for new services being discovered.
I have also not seen any docs for how long the service discovery timeout should be between different services, but with some testing I have determined that it should be at least 5 seconds, in order to get services available discovered nicely.
https://sphen.proxmobil.com/android-wi-fi-direct-service-discovery/
This blog mentioned the timeout is 120 seconds.
Service discovery will only last for 120 seconds from the time the
discoverServices method of WifiP2pManager is called. If application
developers require service discovery for a longer period, they will
need to re-call the WifiP2pManager.discoverServices method.
For the timeout is 2 minutes as mentionned in Android documentation :
// We repeatedly issue calls to discover peers every so often for a few reasons.
// 1. The initial request may fail and need to retried.
// 2. Discovery will self-abort after any group is initiated, which may not necessarily
// be what we want to have happen.
// 3. Discovery will self-timeout after **2 minutes**, whereas we want discovery to
// be occur for as long as a client is requesting it be.
// 4. We don't seem to get updated results for displays we've already found until
// we ask to discover again, particularly for the isSessionAvailable() property.
Related
I'm currently developing an application which uses Google Nearby Connections API. I'm curious whether there is a method to change the timeout for onEndpointLost (method of the EndpointDiscoveryCallback class) and onFailure (method of the OnFailureListener interface).
In my understanding these methods (callbacks) are called when a predefined time is up, and we get these failure calls. I would like to lower this delay, because after a discovered endpoint dissapears, the onEndpointLost method is called too late to my taste. Same applies when a device tries to establish a connection to an endpoint which no longer advertises, resulting in the onFailure callback.
(I would be exxxtra happy if you, Xlythe could spare some time to help me (: )
Thanks in advance!
There's no way to manually adjust these timeouts, and we don't plan to expose a way either. This is because we're combining different scans (eg. BT + BLE + WiFi) and each scan has its own advertising/scanning interval. There isn't a one-size-fits-all number that would work for everything, and we don't control the timeout ourself for every medium (although we do for some).
As for some good news, we are optimizing the onEndpointLost timeout to be shorter for BLE. That's currently our largest timeout (at 15sec) and we're exploring lowering it (to 3sec). This won't lower the overall timeout to 3sec, but it should make it significantly lower.
For the onFailure event, I'd need to know which one you're referring to. If it's a connection request, you can interrupt the request by calling disconnectFromEndpoint. With that, you can have your own timeout of whichever value you want.
I'm using QBluetoothDeviceDiscoveryAgent to search BLE devices on an Android phone.
I request device search to be started by calling QBluetoothDeviceDiscoveryAgent::start(). After a few seconds, QBluetoothDeviceDiscoveryAgent::finished() is emitted, but I did not call QBluetoothDeviceDiscoveryAgent::stop().
At this point, my BLE device was not found yet (it's slow...I know), and it won't as the system decided on its own to stop the search....so I need to restart the search manually.
Why is the system stopping the search? Qt doc says about QBluetoothDeviceDiscoveryAgent::finished():
This signal is emitted when Bluetooth device discovery completes.
What does that mean? How could anyone decide that discovery completes? Does it come from BLE standard? As a end user, I'm the only one who knows when it's completed, i.e. when the device I'm looking for was found....
As commented by Frank Osterfeld, the android implementation of QBluetoothDeviceDiscoveryAgent (see line 273) silently creates a 10 seconds timeout that stops the search automatically.
It's a pain for users who want to search for longer than 10sec...
Filled a bug report here: https://bugreports.qt.io/browse/QTBUG-53012
I'm using a Sync Adapter to perform synchronization for my app. It has set automatic sync:
// Inform the system that this account supports sync
ContentResolver.setIsSyncable(account, AuthenticatorService.AUTHORITY, 1);
// Inform the system that this account is eligible for auto sync when the network is up
ContentResolver.setSyncAutomatically(account, AuthenticatorService.AUTHORITY, true);
If I request the sync:
Bundle b = new Bundle();
// Disable sync backoff and ignore sync preferences. In other words...perform sync NOW!
b.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
b.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
ContentResolver.requestSync(AuthenticatorService.GetAccount(), AuthenticatorService.AUTHORITY, b);
it works well -- as soon as the network is up, SyncAdapter.onPerformSync() is called. However, there's one problem: if the network is up but not connected to Internet (hotspot without tethering for instance), onPerformSync() is still called.
Of course, since it can't reach the server, sync code fails. What is worse, the system thinks everything went OK and wont do any more sync calls unless my data change.
My question is: can I either mark the synchronization as not successful so the system will try it later (for instance on another CONNECTED event or in a few seconds) or better to tell the system to perform the sync only when real Internet connectivity is present?
I could monitor the network state and do a connectivity check by myself but that would defy the whole purpose of sync adapters, wouldn't it. Only workaround I can think of is to schedule periodic synchronization (using ContentResolver.addPeriodicSync()) and when my synchronization code succeeds, turn it off. But I'm not very happy about this either (draining battery).
EDIT: As for the first part of my question, this answer is what I was looking for. It partially solves my problem but if there's consecutive number of "non-working" connections, when the device is associated with the real connection, it would take tens of minutes to sync (because of the exponential backoff algorithm).
Thanks to csenga's suggestion I found a solution: use GcmNetworkManager to schedule the synchronization. It looks a bit stupid as I have to declare yet another service just to call ContentResolver.requestSync() and if something goes wrong I have to reschedule my task instead of setting the SyncResult.stat flags (I'm virtually duplicating Sync Adapter's job here) but still better than to handle my own NETWORK_STATE_CHANGED_ACTION receiver.
When a network connection is unavailable, the drive sdk takes a very long time to timeout -- it takes 15 mins according to this answer.
I access Drive in an AsynchTask which blocks my application. So, if there is no network connection, the application shows a ProgressDialog for 15 mins, until the time out. Possibly I could implement my own timer which kills the AsynchTask after a reasonable duration. However, it might be difficult to differentiate between a timeout and a lenghty process (like downlaoding a large file on a slow connection) and I would be concenred that there could be issues with the token access not cleaning up properly. Any suggestions for how to work around this?
A check if there is a network connection before performing the AsyncTask would help eliminate a lot of the cases, see Detect whether there is an Internet connection available on Android
I am doing my Master thesis at the moment on WiFi positioning and in order to test my algorithms I needed to collect some data.
To do this I have written a short and very simple program for Android which simply collects the RSSI for all availible access points found by each scan and saves them to file. I have set up a BroadcastReceiver that listens on the event WifiManager.SCAN_RESULTS_AVAILABLE_ACTION and I use a Timer, here called tim, to initiate scans with a WifiManager, called wifi as follows:
tim.schedule(new TimerTask(){
#Override
public void run(){
wifi.startScan();
}
}, 0, 1000);
The problem I am having now is that the initiated scans don't seem to happen every second even if I succeed in initiating them and every now and then there are other scans initiated from some other app that gets recorded as well.
Is there any easy way to scan on a set interval and not receive the scans initiated by some other app?
The whole app can be found on https://github.com/while/RSSIMiner if it helps in any way.
Is there any easy way to scan on a set interval?
If this doesn't work well, I'm afraid not. From my experience, "hardware related" methods may not work exactly like their definition says. For example, I once created a small app which records your position every X minutes. So I call requestLocationUpdates with some minTime parameter. But my phone simply ignores the minTime value, and I get updates from the GPS as soon as they're available, whcih is not what I wanted. I posted a question about it here, and got this answer, from which we learn that prior to jelly bean, devices may simply ignore this value...
So it may be something similar now. I'd try to run this code on the latest Android version. And I don't understand that much in Wifi, but isn't 1 second a too frequent interval for scans? Perhaps the system doesn't ignore the scan request (So it returns true) but the hardware does?
Can we ignore the scans initiated by some other app?
As far as I know, it's negative here too. There are no extras contained in the SCAN_RESULTS_AVAILABLE_ACTION broadcast so you can't know which app initiated the scan.
The best solution will be to defnie your requirements. You can use the ScanResult.timestamp to determine if you should use this result or not. For example, if you're trying to get the RSSI for each access point each second, you can compare the current BSSID to previous BSSIDs. If the current BSSID was included in a scan result from the last second, you can simply ignore it. Then, it doesn't matter how many results you get.
Another, much more simple soltuion will be to create a boolean called scanInitiated and set it to true when starting a scan. When receiving the broacast, use the data only if scanInitiated is true, and then set it to false. This isn't so reliable when the intervals are short, but for long intervals it will work great.