I've encountered a problem with mobile internet connection after phone wake up from sleep mode. There is an application which updates some data periodically. AlarmManager triggers my BroadcastReceiver which starts service. service acquires PARTIAL_WAKE_LOCK and some http requests are sent. Unfortunately when update interval is quite big (5h) service could not send/download anything. Problem doesn't appear when I'm using WIFI connection instead of mobile and WIFI sleep policy is set to never. Everything is OK on mobile connection when update interval is short (less than half an hour). I'm also sure 5h event is received by my BroadcastReceiver because I've checked it.
How such events should be handled. I've tried to check whether connection is established by ConnectivityManager and retry 5 times if not but still same problem appears.
Thanks for any answer in advance
The Android system turns of WiFi a few minutes when the device is suspended (i.e. screen turned off).
When the device turns on again (by acquiring the wake-lock), it will take a few seconds until network connection is re-established (this is also true for 3G data connections, which are also torn-down while device is sleeping).
My suggestion:
- Wait for ConnectivityManager's broadcast that the network is up again. Practice proves that waiting 2-3 seconds after the broadcast is received helps things to settle before starting to send and receive data.
- A bit easier: After grabbing the wake-lock, wait a longer timeout and then try to connect.
Related
My app is pinned and after waking up device all network requests that are made right away fail with a connection timeout. Waiting a couple of 100ms or seconds does the trick and everything works normally after that.
I suppose there's a small window of time when wifi is "re-enabled". Whats the best way to detect that event?
Android version 4.4 and wifi sleep is set to "never"
As Augusto Ferrarini points out you can listen for broadcast and handle it accordingly. There is a chapter about it on developer.android which I'd recommend reading together with the link from Augusto Ferrarini.
I wrote an application with one activity and remote service. The main goal of this service is keep net connection with remote TCP server. I use in activity PARTIAL_WAKE_LOCK to prevent system going in sleep mode. But after about twenty minutes when screen is off, the connection stops. It looks it starts unfortunately sleep mode and cut connection. When I turn on my device connection is starting again (my codÄ™ detects error and try to set connection again).
Is a better way to keep connection whole time? I do not have to worry about battery - the device is plug in charge all time. The priority is keep connection.
Could somebody give advice how to resolve my problem?
Regards Artik
I have extended the Application class in my app. In that class, I have a BroadcastReceiver that waits for Connectivity changes. If I switch to airplane mode, it instantly recognizes a connectivity lost and the broadcast is received, however if I lose my data connectivity (ie being underground, etc), it takes a few seconds to a few minutes to fire even though no internet related tasks are successfully completing (even if you try browsing in the browser). Is there a more precise way to find out when internet connectivity is first lost?
A way to find out when Internet connectivity is lost is to do proper exception checking for network errors.
If a networking exception is thrown (socket timeout, I/O error, etc) you can set the state of the application to disconnected. Of course this only works when you are actively trying to send or receive data over the network.
If connectivity notification is that important you can do periodical checks by using a remote server (ping a google server for example), but this will drain your battery as touching the network too often tends to keep the radio awake and draw power.
i'm writing a client-server application which uses TCP socket connection. In my android project, Service creates a thread for listening the TCP socket.
Everything seems OK. But i have got one problem.. My network service running in background fine; But some time later (10-15 min..), when i try to open my application (main activity) again, I can't get responses from the socket connection. It freezes or something?? i cant send or get TCP messages from the socket.. What can be the reason of this? I'm working on my phone, via 3G connection.
(Besides, the app running in the emulator hasn't got such this problem; I assume Its connection is stable, long-during )
Thank you for your answering.
Due to power optimizations and perhaps changes in connectivity (GPRS/HSDPA/Wifi) it's very likely your connection is being dropped.
In order to maintain a connection, your background service needs to claim a wakelock using the PowerManager class. This prevents the device from going to power-saving mode and thus disconnecting your socket. But beware, this significantly lowers the battery life of the device.
Also, you need to handle changes in connectivity which break your open connection. Android sends out a broadcast message named android.net.conn.CONNECTIVITY_CHANGE to notify of changes in connectivity.
Depending on your use-case I would poll with when the device is in the sleep-mode and only build a connection when the device is actively in use or just use C2DM push notifications
When I have experienced something like this in my apps, it has usually been because of power optimisations on the phone (which cant be overridden). If the socket has been idle for too long, it is automatically closed and needs to be reopened.
Are you sending data from time to time? Like implementing a heartbeat protocol ? if you are not, you should...or maybe it has to do with socket READ/WRITE TIMEOUT
I need to keep a TCP connection established indefinitely (as far as possible). Is not an own server so we cannot change the way it works. This server needs some kind on ping each minute to know that the connection is alive. If the server do not receive the ping after some minutes (less than five), the connection and the session is closed. In this way i need to maintain a TCP connection with the server and be able to send pings at the periods specified.
At the moment i have an Android service with the flag "ongoing" so Android should not kill it (at least by normal procedures). The android service seems to run fine and the pings are sent periodically. However when the service is running on a mobile phone (not emulator) and it gets idle, android seems to freeze the service while the CPU is sleeping, so the TimerTask sending pings stop working and the connection goes down.
I have tried to lock the phone from going to sleep with a partial wake lock and it solves the problem but the phone consumes too battery, what is unfeasible.
I noticed that the AlarmManager may help on this task, so i want to schedule an alarm to update the running service and then send the ping. This will let the CPU going to sleep and also the ping being sent. But schedule an alarm each minute may be also so battery consuming or not?
I have not tested this approach at the moment, but is feasible? is there a better way to keep this kind of TCP connection?. How android services like Gmail solves this kind of issues?
I need to keep a TCP connection established indefinitely with a server.
Why?
For starters, it is technically impossible. Users will switch between networks (e.g., was on WiFi, failed over to 3G), users will leave areas where they have Internet coverage, users will turn on airplane mode, etc.
At the moment i have an Android service with the flag "on_course" so Android should not kill it.
There is no such concept as "on_course" in Android. Android services can and will be killed by users (task killer, force-stop in Manage Services) or by the OS. And, since this will be an everlasting services, your users will kill your service if they do not understand what value it is continuously delivering.
I have tried to lock the phone from going to sleep with a partial wake lock and it solves the problem but the phone consumes too battery, what is unfeasible.
Correct.
I noticed that the AlarmManager may help on this task, so i want to schedule an alarm to update the running service and then send the ping. This will let the CPU going to sleep and also the ping being sent. I have not tested this approach at the moment, but is feasible?
Sure. You will still consume too much battery, IMHO. Please allow your user to control your polling period, with a wide range of options (e.g., 10 minutes, 30 minutes, one hour, never).
How android services like Gmail solves this kind of issues?
They use C2DM, which is part of the OS and took a lot of engineering to get right. There was a presentation on it at the 2010 Google I|O conference -- the video should be on YouTube. Note that they do the heartbeat ping every 30 minutes IIRC, and they optimize for the case where the device is on 3G (to allow the WiFi radio to turn off after inactivity).
If your objective of your permanent connection is to implement a push-style communications channel, please consider using C2DM.
You can wake phone from idle with partial wake lock right before you execute ping and after you do it release wakelock. It will scientifically reduce battery consumption and it will do the job. Also, try to increase ping time as long as you can.
5 Minutes is a little short for the ping time, can you configure the server to hold the connection longer? 30 minute ping or higher would be ideal. Here is an example of an application that holds a background tcp connection and will wake up the device from a deep sleep on incoming tcp traffic. https://github.com/schwiz/android-websocket-example