Android long-duration socket listener - android

My company has, in essence, undertaken a project to replace some of its pagers with stock smartphones running Android. As long as they are signed in, the device should be listening on a particular socket to receive "pages" from a server. My naive implementation was to create a foreground service that 1) kicked off a listening thread, and 2) holds a PARTIAL_WAKE_LOCK.
This works fine unless the device has a long period of inactivity, 1+ hours. Then, it appears that the OS shuts down my app's process, understandably believing it to be not in use.
I completely understand their reasons for doing so, but I'm wondering if I can somehow get around this restriction. Are there ways to signal Android that my process really is important enough to keep alive/the device awake? I learned both Java and the Android API for this project, so there are plenty of areas where my knowledge is incomplete.
Failing that, given the description of my business needs, how would you suggest implementing this functionality? While the user is signed in to our custom app, the device should always be listening.
Thanks to everyone for reading this question.

The OS won't kill your process if you are using Service.startForground(). This is what things like music playback use, and you wouldn't want those to be killed after some amount of time.
That said, for this kind of thing you generally wouldn't need to make your service foreground -- when the system does kill your process because it has been sitting around or needs the memory, it still knows the service wants to remaining running so will restart the service shortly after that. This is how Google's own services work, they have one .apk that has a background service running that keeps a network connection open to a Google service which reports back when interesting things should be done like sync new e-mail, retrieve and deliver a C2DM Intent, etc.
Also you should not hold a wake lock during all of that time. You will kill the battery, especially on some devices like those with Samsung's Hummingbird processor. The right way to do this is to just leave the socket open and let the device fall asleep. If data is delivered to the socket, the CPU will wake up to deliver that data and at that point you should acquire a partial wake lock just for the time you need to read and process the data.

What you describe sounds like a job for Android Cloud to Device Messaging Framework.
It's currently not completely open but there is a signup link on that page. I signed up and was accepted within 20 minutes of my application. Worth a look IMO.

Related

Android - Is using a foreground service all I can do to prevent my process from being killed?

Context / Current Approach
Hello, I'm curious about my usage of a Foreground Service. I have an app which performs voice communication and maintains a persistent connection to our backend via a websocket. It is a common use case for our users to background our app and do something else which is memory- and CPU-intensive, in particular playing mobile games.
In order to prevent our app's process from dying and severing the voice connection, we run a Foreground Service in our app's process (a local service, in some vocabularies). This Foreground Service doesn't actually do much, it displays a notification that allows the user to interact and mute/deafen/disconnect from the notification tray. All the voice logic doesn't actually live in the Service.
Our hypothesis is that by running a Foreground Service, we effectively mark our process as "foregrounded", and the OS is less likely to kill our app. This also allows the user to swipe away our app and have the process stay alive (including the voice connection). This appears to work and looks very similar to the process/service signatures of similar products (Skype, Spotify) using adb shell dumpsys activity services and the inspectors in the device's settings.
However, from time to time we still hear about users who experience our app being killed while gaming or streaming videos, even when they are on voice and the Service is running.
And Now For The Question(s)
After much research it FEELS like we are doing the right thing already. However, we'd like to make our voice stability more bulletproof if possible, and address those user complaints.
Am I doing the right thing already, or is my understanding of using a Service to "mark our app as foreground priority" flawed? (Addendum: It took me getting to the end of writing this for this question to pop up in my searches. It reads like we're on the right track already).
Is there any way I can verify that the OS is indeed killing my app process? Conventional wisdom says no. However I can imagine some solutions which abuse the STICKY flag to relaunch the Service, log to our servers that the Service was relaunched by the OS (and therefore, must have been killed by the OS), and then stops itself again. I just thought of this while writing so forgive me for not having tried it yet...
Do we have other options? The UI components of our app are not particularly heavyweight. This leads me to think that even if we were to invest in a Remote Service (running in another process), if the OS is already killing our Foreground Service, then the OS will likely also just kill that Remote Service. I don't want to use STICKY to combat that as it would be a poor user experience -- it makes sense for services passively processing data but for active voice chat, restarting "later" doesn't sound great...
Thank you very much for taking the time to read the question, I'm happy to provide any additional necessary context.

How to keep alive socket connection in android 7.0 and above?

I am developing multiplayer game using Socket.io library. it Works Well.
But, in android 7.0 and above, system automatically suspend all network work when my app is in background. (And I must need to keep alive my socket connection).
I research about it as described here.
but, i can't understand. So, Please provide solution for that.
Unfortunately there's bad news and some good news for you on this.
Bad:
Since android marshmallow and above, there's a concept of a doze mode. If the device stays put for some time (can't confirm the duration for this and not disclosed by google), the device will go into doze mode and will suspend all network activity. There will be short maintenance windows where in you will be able to do syncs and stuff. Small workaround, do not target 23+ apis, i say small because i have observed this to not work on some phones. Another way to potentially bypass this would be to whitelist your app from battery restrictions but according to google guidelines, i don't think your app will qualify for that.
Worse news is that start from API 26, background services will also get suspended completely when app is totally backgrounded and has no visible component (a notification or a foreground service etc...). So oreo will be worse.
Good:
You might not really want to constantly keep the socket open. Instead opt for bursts of syncs. I personally have a job run every 30 - 60 mins or so to try and sync up.
You can leverage the JobScheduler apis and it will automatically handle the doze modes and stuff and you can make them run periodically when there is internet connection. While the job is running, you can connect to your server, do your thing and shut the socket. This is what google wants and is pushing all devs towards.
UPDATE 19-Apr-2021
WorkManager is the new and the best way to deal with doze mode and background limit restrictions.
Another alternative would be to have a foreground service with an active notification displayed which would constantly be connected via your socket. This will be visible to the user and it will not only annoy them that you are constantly using their data, it can also be bad for the battery. Alternative to this again is using the job scheduler to schedule and run a foreground service periodically so as to be transparent while also syncing your data every once in a while. The latter approach is what WhatsApp does, they have a job running which syncs all incoming messages with a foreground service once in a while.
In Short:
You will not be able to keep it alive always. You can try doing it in bursts using one of the methods that i described and know currently (maybe there are other alternatives that i don't know, i have tested these and they work) You will have to compromise, sorry.

How to run a background process in Android repeatedly

I am using AlarmManager for repeated background process. My app repeatedly requests data from server in 5 sec interval. But after some long time, when I open my app it crashes. I can't figure out why.
How should I execute a background process repeatedly? Should I use AlarmManager,Timer` or something else?
My background process should run always even when the app does not have focus or isn't active.
My app repeatedly request server for data 5 sec interval.
Users with mobile devices, like phones and tablets, will not appreciate your behavior. They will not appreciate your consumption of battery life and your consumption of bandwidth. Device manufacturers and Google are continuing to take aggressive steps to prevent applications like yours from behaving this way, both automatically and by giving users the tools to find ill-behaving apps like yours and get rid of them.
But After some long time when i open my app its crash
Most likely, you have a bug in your app. You will need to fix the bug. Since you have provided no details of your crash, such as source code and a stack trace, nobody can really help you with that.
Which is the best for repeated background process, AlarmManager, Timer or something else?
Switch to a user-configurable and less-crazy polling period (e.g., every 15 minutes by default), then use AlarmManager in conjunction with an IntentService, so that your process can cleanly go away
Or, switch to having the server send messages to the device when the data of interest changes, such as via Google Cloud Messaging. This will allow you to drop the polling period to something infrequent (e.g., every hour by default), as a fallback mechanism in case you miss a push message for some reason.
My background process should run always though the app is not on focus or active
Your users will disagree with you. They do not want apps running all of the time, tying up system RAM. They really do not want apps that consume battery and bandwidth the way that you are proposing. The users will get rid of your background process, either by:
swiping your app off the recent-tasks list
using a third-party task manager
force-stopping your app via its entry in the application list in Settings
uninstalling your app

Keep a permanent connection (same LAN) in the background, without using GCM

I need to keep an open connection in the background, even when the app is not running. It's not possible to use GCM because the connection will be in the same LAN as the server, and the device may not have a working Internet connection.
The connection will be some kind of local Push, so the device will just get some short relevant data from time to time (in addition to the keep-alive messages).
My use case is quite specific so I can consider that the battery is not an issue. I may show a huge red warning saying that enabling the feature will drain the battery, or just disable it if the device is not charging.
On the other hand, is quite important that the process with the connection is not "randomly" killed by Android.
I thought about implementing this with a service, but I would like to hear opinions from someone else. Maybe there is a better way to do it, considering the constraints mentioned before.
"even when the app is not running"
That means that your app is not running, and it doesn't have a process. Without using a third part app (such as the GCM service) that awakes your app, nothing can reach you.
You can, however, have a service that remains active and keeps a connection to a server (say, for instance, an XMPP server) to receive notifications and wake up this or that activity.
You can also do that in a separate application.
You can add robustness with a regular watchdog started by the alarm manager, for example.

Android / iOS: schedule task while app is in background / off

When a Server wants to contact a client, though the corresponding app is inactive or off, he can do this via Google Cloud Messaging. My little application runs in combination with a webserver which I do not own and only runs php on, so actively contacting a client is impossible.
Now there are apps with probably similar problems, such as the Email apps. Mailservers never manually contact their clients, when a new message was received, so they check for new messages every, say, 30 minutes.
My question is: Is it possible to run such a background task? And is there a way to do this in iOS, too?
Thanks in advance!
If there is something you want android to do when the user is not interacting with the widget/application, you should use a service.
Android Service
It is meant to be used for tasks that require no user interaction and is especially great for checking something over and over. No guarantee that the os still wont kill it eventually, but it kept alive as long as possible. You can also create a service to be restarted anytime it dies, if you really want to do something long term.

Categories

Resources