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

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.

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.

Establish a permanent connection with a wearable, or as and when needed?

I have a permanently running service app on the handset, one of the things it does is detect when there is an incoming phone call and send a message and some data to a companion app on a wearable device.
I'm wondering whether the app should establish the API to communicate with the wearable when it launches, or only when there is an incoming call and then disconnect afterwards.
Has anybody with wear development experience got any pros or cons of these approaches?
The service automatically starts at device start-up, and I've noticed if an attempt is made to create the GoogleApiClient/Wearable.API and get the wearable device node soon after rebooting there's a high chance of failure, therefore a disadvantage of establishing the wearable connection at app launch is its probably fail and will need to re-try or wait etc.
In general, to save on battery life, you want to minimize usage of any network connection on a mobile device. The general rule of thumb is: establish a connection only when needed, if you expect to use it again "soon" (e.g. within a minute or so), then keep it around, and close the connection when you are not going to use it for a longer while.
So in your case, since you are responding to phone calls (which should not happen every couple of minutes!), you should re-establish the connection every time. I am not sure though about the delay incurred in this case.

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).

Android USB Host and Device Sleep

I have a USB device that I am interfacing with an android app using USB host mode. The device sends some data approximately once every 10 seconds but in some cases (high priority data) the data can come anytime. On the android app side I have a service that reads the data using USB host mode API. My android app processes the data and writes data back to the usb device. Now all works fine till the android device goes to sleep. The service goes to pause and all communication stops. I understand that I can use partial wake lock to keep the CPU running and the communication going and that it will have a huge impact on the battery. I though have two questions:
Since the USB device can send data anytime, I really need the android service to alive all the time especially since higher priority data can come anytime. This could potentially mean that I acquire the partial wake lock and never release it. Havent been able to find in documentation if this is allowed and if yes what are the ramifications besides draining the battery?
Does the USB Host mode API or any other API provide a different and potentially better solution?
The app is a custom app with limited users and so battery drain is not a big issue. I just want to understand if there are other issues I need to be careful about or if there is a much better way to do it.

How to keep a TCP connection established indefinitely?

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

Categories

Resources