How to keep a TCP connection established indefinitely? - android

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

Related

It's possible for a mobile app connect to a BLE device and keep the connection alive for hours in background?

We have a device that need to be started at night, the device is started thanks to a bluetooth command sent by a mobile application. It's possible to send this command while the app is in the background and keep monitoring the device (i.e. receiving data), for example, for 30 minutes?
If it's possible what would be the ways to implement this feature in iOS and Android?
Update: Think about a sleep tracking device; the problem shouldn't be to scan all night because the user must connect the device before go to bed (and eventually try to automatically reconnect to a known device, without the need to scan). I'm asking if it's possible to stay connected and send/receive data while, for example, updating an internal database all night.
Several thing to take into account about Android BLE system development, read this for more information: https://blog.classycode.com/undocumented-android-7-ble-behavior-changes-d1a9bd87d983
BLE Scanning has an abuse prevention since Android 7. What does this means?
Prevention for an app stopping and starting BLE scans more than 5
times in a window of 30 seconds.
Long-running scans are converted into opportunistic scans. (30 minutes).
About the background process depends on what type of service you want. You can start a foreground service with a notification or you can start a Job which runs always in the background with no notification.
If you can be more precise on how the system is going to work I can give a more detailed explanation.

If mobile 3G checks Internet every 30 min, how come push messages come immediatelly?

When a device is using the mobile Internet (3G, 4G), it connects to Internet every 30 minutes. This can be seen with emails coming in a bunch instead 1 by 1 like when a device is on wi-fi (among other things).
How come that push-messages for chat apps (hangouts, whatsapp, viber,...) come immediately?
I actually noticed that only Skype messages do not come immediately when I am on the mobile data connection. Others come instantly.
When a device is using the mobile Internet (3G, 4G), it connects to Internet every 30 minutes. This can be seen with emails coming in a bunch instead 1 by 1 like when a device is on wi-fi (among other things).
That just means that those apps happen to be pulling down data every 30 minutes, whether via AlarmManager or JobScheduler or SyncManager or whatever. They could just as easily set their AlarmManager polling period to be 27 minutes, or 2.7 minutes, or 27 days.
How come that push-messages for chat apps (hangouts, whatsapp, viber,...) come immediately?
On a Play Services ecosystem device, either they are using GCM (which maintains an open socket connection), or they are using their own GCM-workalike (which maintains an open socket connection for however long they can keep their service running), or they are using something like AlarmManager with a small polling period (which is really bad for the battery, but that doesn't stop people).
On a Kindle Fire, they might be using Amazon equivalents of GCM, etc.
What makes mobile data interesting is that incoming packets on an open socket connection will wake up the CPU. From there, the apps for which those packets are destined can grab a WakeLock to be able to have time to process those packets. WiFi sockets are usually torn down around the time when the CPU goes into sleep mode, in part because usually the WiFi radio itself usually goes into a sleep mode around the same time, to conserve battery.
I actually noticed that only Skype messages do not come immediately when I am on the mobile data connection.
Skype might not use GCM for competitive reasons. I'm a bit surprised that they aren't using their own workaround GCM-like service (e.g., MQTT-based).

How to receive call on android + pjsip when phone in deep sleep

I'm trying to build voip app based on PJSIP on Android. I decided to use TCP for connection to make the connection be persistent. And app right now has background service (same process) which is responsible for all interactions with SIP server. TCP keep alive timeout is set to 1 minute (just for testing purposes). Everything works fine until the moment when phone goes into a deep sleep mode. From logs I see that phone still sends TCP KA but with 4 minutes interval (why???). But the main issue is if I try to call from another phone to this one the phone keeps sleeping and skips all INVITE messages. Appreciate any help.
When the Android device goes into deep sleep, the CPU throttles down and almost all OS services are suspended. See for example:
Android Sleep/Standby Mode
what is the difference between Sleep mode and Deep sleep mode?
If this were not the case, the OS and most other components would still be on, which would drain battery extremely fast, and most users would uninstall your app.
In order to receive incoming messages (such as the INVITE), it's recommended to use GCM. In this, you need to implement a server piece that is essentially handling the client's responsibilities while the client device is asleep.

Android opportunistic communication vs power management (what happens to service when phone goes to sleep)

I am writing an application for android that will use opportunistic communication. So when two devices are nearby they exchange data. For now it will happen when they are in the same wifi network (using mdns) or when they have paired bluetooth interfaces.
I was wondering from power manager point of view. Will my ongoing service be paused when phone enters sleep mode? If yes how do I prevent it?
Also any general tips how to make it consume as little power as possible? I was thinking to wake it up from time to time, but then there's a chance that it will miss a mdns query sent by other device which I want to avoid to maximize throughput.
And just to clarify - yes, I do want to use opportunistic communication and no I do not want to use any solution that involves connecting to the internet.
Any help appreciated.
Use Wakelock to indicate that your application needs to have the device stay on.
but it consumes considerable amount of power.
you can also use AlarmManager to start your app at that particular time when wifi is available

android dev: problem with mobile internet connection after phone wake up

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.

Categories

Resources