Backround: Android 2.x on a tablet
That a the second post on this. Now the WiFi don't get turned off by android but I although loose the connectivity after some, means the server can no longer reach the android device (I get a timeout). I tried this at least on four different tablets so I don't think that it depends on the hardware. A continous polling prevent this but this should be just a workaround.
The answer lays in the wifi router AP (access point). There is a value thats called TTL (time to live) which controls how long a connection is held open after last activity before closing from no activity. You need to change this value in the router.
Related
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
You can use the TYPE_MOBILE_HIPRI network type in order to force connections to a particular host to go over the mobile connection rather than wifi, as described in Rainbowbreeze's answer here: How to use 3G Connection in Android Application instead of Wi-fi?. Unfortunately, the system enforces a timeout on these connections which is too short for my application, meaning it is effectively useless to me. Is there some way of cancelling this timeout, or another way of achieving the same results? If it helps, I am happy to restrict my application to running on rooted phones only.
I got around this issue by refreshing hipri connection after every 50 sec.The system time out for a hipri connection is 1 min.So call 'enableHipri' after every 50sec.
My app connects with a persistent connection to a server. If the device is currently using 3G it will connect over 3g.
The problem is that if it connected using 3G and moved into wifi the connection drops. How do I prevent it from disconnecting?
Sounds like the server is unable to accommodate clients seamlessly switching to a different IP address, or it may be using something like keep-alive packets to maintain connection state, and when the 3G connection drops, it disconnects your session.
This may not be something you have control over. From the Android point of view - the device will prefer WiFi depending on user preferences and you will likely not have any direct control over that either.
In a nutshell - if you can't modify or reconfigure the communications protocol to allow client IP changes on the fly, then there's nothing you can do with Android to mitigate the problem.
All mobile devices, and to a lesser extent, desktops/laptops will at some point change their public facing IP address, so it sounds like a bug or oversight in the server/protocol design to me.
EDIT:
In response to your comment, and in the interests of UX, you should be very careful about finding a way to force your app (possibly even the entire device) to remain on 3G when the user has requested that it use WiFi.
Most people have capped data plans with their device and wouldn't be very pleased if they think they are using WiFi (which is most likely free, or at least no additional cost) when in fact you've forced their device to continue using potentially very expensive 3G data instead.
This is especially important when any method would likely be actively circumventing the reasonable limits the Android environment presents you with, and therefore would probably not be flagged as a "Service that costs you money" when installed.
EDIT 2:
So, there may be a way for you to do it, but it relies on unsupported, private Android APIs which may change at any moment - usual disclaimer applies.
Take a look here where they access the ConnectivityManager object to allow you to enable mobile data.
This method does require you to build against the Android source tree, and use a shared user ID with "system" so may or may not be suitable, but these APIs are private (as apps are not supposed to be able to do this without user action), but it may help you.
This is how Android works. You're app should not maintain a persistent connection, it should only open a connection when needed.
I have a service which polls every hour attempts to sync data automatically to the web from the device.
I have it working but I need to find a way to establish an internet connection if there is not one available.
For example - If my phone is in standby mode (screen locked for a period of time) the internet connection is dropped and it is unable to sync when it needs to.
I would like to attempt to connect via wifi if available, then using 3G if required.
Is there a reliable way to do this?
UPDATE -
I found an article online which uses this code to attempt connection via 3G if there is no wifi available :
int resultInt = connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");
unfortunately it doesn't seem to work on all devices, maybe I need to try other options than "enableHIPRI" ??
Any ideas?
OK, although I haven't been able to solve this problem I have discovered that the main cause for the delay in between sync attempts is because the cpu gets stopped during sleep mode, this means my timer task was paused..
My workaround was to rewrite the service using a wakeful intent to get around the timer issue.
This makes my solution much more reliable so I am closing this question! :)
You should be able to do most of that using ConnectivityManager. It allows you to query the available types of networks and using requestRouteToHost you should be able to ensure there's a connection set up that you need for syncing.
I think you cannot rely on such thing on mobile phone, as in any embedded device you cannot be sure if the device will connect and stay connected when you want. You can only leave a message for the user that data was not synchronized or try to minimize it by checking if there is connection and then synchronizing not just in one hour.
By default, Wifi sleep policy is "Sleep on screen idle".
With this policy, is it possible for a Background Service at a later time to wake up Wifi using some API?
Am trying the following, but does not work:
When my Background Service wakes up, it calls "ConnectivityManager.getActiveNetworkInfo()" to get active network.
Since, the wireless is off on idle, I tried waking it up using "WifiManager.startScan" on a previously used Wifi connection.
But still dont get Wifi connectivity.
Any ideas?
I preferably do not want to change my sleep policy to "Never".
Thanks
Hemant
There are no real simple solutions for this. To with a high probability ensure you have WIFI connectivity when the phone/screen goes to sleep the best way is to turn it off. Look here for a lot of details - http://wififixer.wordpress.com/
It is important to realize that in sleep mode the Wifi enters a low power mode. This will become tricky then to programmatically check as it might have connectivity to the Wifi but the Wifi connection is too weak or too slow to complete the HTTP request and hence it times out. This would force you to also check the speed of the Wifi connectivity as well as you will have an active network but a pretty lousy one.
Proper handling of the escaping when timeout occurs for the HTTP call you make makes it ok to use but ultimately the only way to have a background thread constantly running to get data is only doable when you have the Wifi mode to never sleep.
It is tricky and not the best way I know. :-( It is however the only path I have found which is reliable enough.