Background Service Limitations Android and voip app - android

I am working on the voip app. I do all the logic regarding the signaling on background service. When user exists the app I am stoping the service. In this case, I am not connected to the server. When I am in this state, server is sending the push notification (FCM), I am starting the service and creating notification for incoming call or message. This is all good so far:)
I have read about the limitations for Oreo for backgrounding services and realize that now I need to start service in foreground while showing notification. Then I wanted to check how the Hangouts(google) does it, and of course they are running the service in the background when message is received. Am I missing something?
Thank you

Visible activity = foreground
When user exists the app I am stoping the service
If this means that the service is running only when your app is visible to the user, then the process and the service is actually in the foreground and you shouldn't experience any problems with system killing your service:
An app is considered to be in the foreground if any of the following is true:
It has a visible activity, whether the activity is started or paused.
FCM received = foreground
Also, receiving high-priority FCM messages will put your app on temporary whitelist for background processing, and you will have more than enough time to do your processing at that time, or you can always start a foreground service after FCM is received - like a service that handles the call and should display a notification while running:
Under certain circumstances, a background app is placed on a temporary whitelist for several minutes. While an app is on the whitelist, it can launch services without limitation, and its background services are permitted to run. An app is placed on the whitelist when it handles a task that's visible to the user, such as:
Handling a high-priority Firebase Cloud Messaging (FCM) message.
Your app design - handling incoming calls by receiving priority FCM and then creating a foreground call service - seems reasonable.
Refer to the documentation which is really clear on these subjects.

Related

Endless background processes without a service and any UI shown

I'm running the Slack app on an Android 11 device. If the app is placed in the background by tapping on the device's home button and a Slack chat message arrives, it displays a notification on the Android notification bar. If you tap on the notification icon to open the notification and then tap on the message, the notification is removed.
What puzzles me is whether an app like Slack even uses a foreground service when receiving chat messages. From my experiencee, to have a continously running background service when no UI is shown, you must display a notification icon on Android's notification bar to indicate to the user that the app is running a background service. While this is considered a background service, it is in fact referred to as a foreground service.
But Slack does not display an icon on the Notification bar to indicate any foreground service. So if it's not using a foreground service but can receive messages while the UI is not shown and post a notification, how is this being done? Has something changed in Android that you don't need a foreground service in order to run a long running process in the background?
The only possible explanation I can think of is that instead of a service, a class that inherits from Application is used and the process for receiving messages is done within a coroutine that is launched from this class and remains active as long as the app remains alive. But if that is true, it means that apps CAN run endless background processes without any UI showing and that means that something changed in the policy required by Android to run endless background services.
What puzzles me is whether an app like Slack even uses a foreground service when receiving chat messages
Most likely, they do not.
So if it's not using a foreground service but can receive messages while the UI is not shown and post a notification, how is this being done?
Most likely, on Google Play ecosystem devices, they are using Firebase Cloud Messaging (FCM) as a trigger to find out about messages that require user notification. FCM and its predecessors (C2DM and GCM) have been around for over a decade and are designed for this sort of problem.
if you look at the firebase messaging documentation you will be understood notifications that arrived to a client are not handled by the application, there is an Android transport layer (ATL) that is responsible for getting messages even if application is not running!

Best way to create a service that doesn't die.(like WhatsApp or Facebook)

I have tried till now
- start sticky
- alarm to restart service
- on task removed start the service
- use job service (has latency and executes task slow)
Is there a proper method to make an infallible background service like the popular apps?
Creating a background service that "does not die" is not possible in android.
You can create a service and take certain measures to have it running as much as possible, but the OS will kill it at times and your service will not be running until the OS decides to restart it (in case it is a sticky service).
Things you can do:
Make the service sticky, so that it will be restarted by the OS after the OS kills it. It is impossible to predict when it will be restarted. It can be almost instant, it can take seconds, minutes, hours, or more.
Start the service when you open the app.
Start the service when the app is upgraded, using the MY_PACKAGE_REPLACED broadcast.
Start the service when the device is (re)booted, using the BOOT_COMPLETED and REBOOT broadcasts.
Override onTaskRemoved in the service, to schedule a restart of the service in case the user swipes away your app from the list of recent apps.
Use FCM to periodically send messages to the app with an instruction to start the service in case it is not running anymore.
You can never have a 100% uptime, but this will get you close.
A background service, if not visible by the user will always be killed earlier or later by the Android system. It is the way memory management work.
If you really need to make a service continously run, you need to show a permanent notification to the user (like when you are using a radio app or a music player app).
What whatsapp and facebook probably do is to wake up the app remotely with any sort of messaging such as Firebase Cloud Messaging (ex-Google Cloud Messaging) or using Broadcast Receiver on certains events... But it surely isn't en ever going on service.
Read this part of Android documentation to better understand this:
Service Process Lifecycle.
As you can see, to give priority to your service process you will need to start it in foreground and pass it an Ongoing Notification using startForeground(int id, Notification notification).
Use setOngoing(true) in your NotificationBuilder to set a Notification as an Ongoing one: setOngoing(boolean b) doc.
Finally you usually want to add action in your Ongoing Notification (such as Player controls or the possibility to close the notification and hence your service when memory will be collected)
Here a full sample code:
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.notification_title))
.setContentText(getString(R.string.notification_text))
.setSmallIcon(R.drawable.ic_small_icon)
.setColor(getResources().getColor(R.color.colorAccent))
.setContentIntent(pendingIntent)
.setOngoing(true)
//.addAction(android.R.drawable.close_service,"Close", closeServiceIntent)
.build();
startForeground(Constants.NOTIFICATION_ID, notification);
It's not a good idea, check out this article. Using a service in this case is not a good approach.

How android chat applications (Watsapp, Hangouts, Facebook Messenger etc) are recieving messages even when back ground process stopped manually?

I am trying to implement an Android chat application using web-socket.
I am using an Android service to connect to the web socket server. It is working fine, but when I force stop the service (Not the application) manually in task manager
(Settings -> Apps -> Running)
Then my application is not receiving any messages from server. What I observe from other chat applications is even if I stop the background services of those applications, they are receiving messages and after some time the services also automatically started. How is it possible? Is there any other hidden service that wakes up the main application thread?
You can force start the service every time it is force stopped
Take a look at this (How to automatically restart a service even if user force close it?)
Most of those apps are using a push service such as Google Cloud Messaging.
Continually polling servers or maintaining a persistent web socket is not a resource-friendly method of receiving messages from a server over an extended period of time.
To my knowledge, they do not have a special way of doing this. They may have "work arounds" that are convenient (for example, Facebook Messenger can wake the FB app, if you have both installed and stop only 1 of them).
As of Android 3.1, an app cannot wake itself and GCM also will not wake it. See here: GCM push notifications on android 3.1 : disable broadcast receiver
CommonsWare usually knows what he's talking about. Also, I have tested it and it doesn't work for me on the 3.1+ APIs.

Why gmail/yahoo / what's app service is not getting killed?

I have an intent service which is continously polling to check if data has been modified in the server. The problem is if the app remains idle for some time , it stops receiving notification. We are suspecting the service has been killed by android.
I think even GCMINTENTSERVICE is also killed by android in some time.
My question is how come gmail / what's app/yahoo mail always sync without foreground notification. Which sync mechanism they are using.
Are you aware of any other app which is always receiving notification even when in background, so that I can check in Google why it is not killed in some time.
Does Google kill gcmintentservice if it has been running for some time in the backgroud.
EDIT: GCMBASEINTENTSERVICE is the service we are planning to implement for push notifications, because with the older polling service the app did not receive notification after some time. This is may be because it was getting killed by android in some time. So with push notifications, the app will always receive notification? Isn't Gcmbaseintentservice an intent service and that will also be killed by android in some time.
Android will kill services after some time, to resolve memory issues. It's not a good thing to always run your application in background, since it will consume memory and processing power.
You have got the wrong idea. GMail and Yahoo are not polling for new mail, they are using Push Notification mechanism, more precisely Google Cloud Messaging or GCM. Push Notifications can be received in the background, and once they receive a push notification, they sync the app.
BBM (BlackBerry messenger) didn't use GCM, as they relied on BlackBerry servers. So they ran the application in the background without getting killed. This is done by always showing non swipeable notification. Someway with notification, you could run a service in background without getting it killed.
According to AndroidHeadlines
You may want to leave it persistent if you want to use BBM. In Android
4.3, Google has begun fighting apps that suck down battery and stay alive without you knowing. It now requires any app that wants to run
in the background to place a persistent icon in your notification.
Hence the BBM icon. Doing this allows that particular app to never be
closed.
Surely google will kill any service if the device runs out of memory or new services are running in background.

Why messenger application receive messages when app force stopped?

I hope that we cannot receive any messages ,when we force stop the default messenger app in our android device.I force stop default messenger app and sent message to that android device. I get message to that device.why this device receive message?
On Android 3.1+, a BroadcastReceiver will only work after its app was force-stopped if an explicit Intent is used to send it a broadcast. Here, by "explicit Intent", I mean one that contains the ComponentName of the receiver, in addition to possibly other data like an action string.
It is unclear what you mean by "the default messenger app" and "messages". If you mean SMS, I would expect that on Android 4.4+, if the user's default SMS client is force-stopped, it would still get SMS messages, as Android probably uses an explicit Intent to talk to it. However, on Android 4.3 and below, I would not expect a force-stopped SMS client to receive messages, as SMS_RECEIVED was just an ordinary ordered broadcast then.
This happens often because there is a service that is listening. The app uses the service to connect with Google Cloud Messaging and receive the messages. You'll need to disable the service. You can view Settings -> Apps, then swipe left to view All or Running and view the services.
Extending a bit further Steve's answer, this is probably an exemplary case that describes why programmers must control any Services in their applications. Many people just declare and run them, and then they forget about them. Services run in a different component than the foreground app, so if you 'close' your app but you don't stop the Service, it will be still running and that's probably what you're experiencing. However, many people tend to misunderstand this concept. This is a different component, but not a different thread nor a different process.
As per the official Android Developer Guide:
A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. [...]
You don't specify what kind of message system uses your app, but if it is GCM (Google Cloud Messaging) or some alike system, it indeed uses a background Service to receive notifications from the central server and you're getting them because your foreground app is closed but your Service is still running.
To stop a Service, you'll need to call Context's stopService() method, as defined in the documentation prior to stopping your foreground application.

Categories

Resources