I am trying to develop an application which will require a service to
run in the background. I am relatively new to android programming,
and after reading many posts, blogs, how-to's and books on creating
and managing services, I am still pretty confused about which model I
should try to use.
First, let me present (in general) the application requirements: I
need an application which will spawn a background process (service?)
which will connect to a bluetooth device. The bluetooth device is
designed to deliver data to the android device. The issue is that the
data could come in at any moment, so the bluetooth connection has to
stay active. Note that the application is a VERY SPECIFIC app and is
NOT intended for public use. I do understand the arguments for not
having background apps running all the time, but please understand
that this is a very specific application for a very specific client.
Now, in general, I think the program flow would be to start the
application (and launch a UI activity). Then I need to configure and
connect to the bluetooth device. At this point, the user should be
able to do other things - make phone calls, check their email, etc.,
while the bluetooth connection is still active and potentially
receiving data. If data comes in, a notification is fired, etc.
So here are my questions and concerns:
If I start an app (which spawns a UI activity and ultimately my
bluetooth connection service) but the app is killed, apparently, the
service handling the bluetooth connection is killed as well. How can
I keep that alive? I read that Service.setForeground() was
depricated, but even if I were to set it to the foreground, if the app
is killed, the service is killed as well. I need to have it run in
the background with as high of a priority as possible (again, I do
understand that this is considered "bad form", but this is a specific
app and this functionality has been requested by the client).
If I started the app (and the service, etc.), but the user, say,
answers a phone call, the app is put into the background. However,
let's say the user goes back to the home screen and starts a DIFFERENT
instance of the app, i.e., he doesn't hold down the home key to select
the already running app from the task manager but starts a completely
new one. If the service handling the bluetooth connection is still
running, how will this new instance behave? i.e., how can I get it to
connect to the bluetooth service which is ALREADY running in the FIRST
instance of the app instead of this new instance? Do I have to use
some form of a Remote service instead of a local service? This is
where I'm a little confused by things as it seems remote services and
defining an AIDL seems to create a lot of extra overhead, and since
I'm already creating a lot of overhead with the service running in the
background all the time, I want to keep that as small as possible.
How can I insure I am connecting to the same service already running?
1)
The service does not depend on an Activity. You can have it running on the background until you call stopSelf().
You can have a BroadcastReceiver that listens to the android.intent.action.BOOT_COMPLETED so your service is started when the phone is turned on.
2)
Your Activity should bind to the service. And get the info from it.
Check this question.
Related
I tried to find if there's a way to run foreground service (one which would hopefully never be killed) without any ui. (Ok I guess notification is necessary but other than that)
This is a very specific use-case since the device being used is a custom one (not a phone), where we need one 'server' app, and might be couple 'client' apps. Clients app will have all necessary ui, but server app should behave in a way like a web server.
I understand this is not a intention of foreground services, but it is justified in the use-case we have.
Bonus question: Is there a 'best' way to achieve an android process/service absolutely constantly running and never being killed by platform for cleaning the memory, since this service will be de facto critical part of the system. Like a phone/dial app on phones for example
Sorry, I can't write comments so I have to post an answer.
It's not exactly what you are looking for, but maybe this google codelab can help you
start with something:
https://codelabs.developers.google.com/codelabs/while-in-use-location/#0
The code in the sample project starts a foreground service whenever the app leaves foreground, allowing the service to "survive" even if the application it's destroyed. Basically the system will not stop the service because tied to his notification.
Plus the service can be stopped from the notification itself.
Maybe with a foreground service started from a device boot broadcast you can have an "always running service"
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.
According to the Android developer website https://developer.android.com/guide/components/fundamentals.html
A service is a general-purpose entry point for keeping an app running in the background for all kinds of reasons.
And on several occasions, i read that a service is (also) used as a means to tell the system that the app requires doing some work in the background.
What is the difference in my Application object creating a sticky service and starting it and it creating a POJO that does the same work?
When the app enters the background (home button) how does the existence of the service change how the system treats my app? Will the service (which runs on the main thread) cause the system to schedule my main thread higher or not reduce it a priority while in the background ? Will it do so if there is no service but a POJO doing some work?
Neither will receive any notification of my app entering the background or coming back to front, neither will be connected to any activity (but could provide functionality for activities to connect to them).
So how exactly does the use of a service change how the system treats my app when it is in the background?
Somewhere it was mentioned that if there is a service running the app will be restarted should it be killed for any reason, however, the service will be killed along with its process (we are talking about a service running in the same process as the rest of the app) but this does not have anything to do with "running in the background" as the android guide mentions.
In addition, the Application object could bind to a service, holding it like a POJO. What would be the difference here, regarding how the system treats my app in the background?
I'm developing a similar app to Telegram or WhatsApp, I need to keep a persistent socket connection to a server (I know this is a resource intensive job and I am sure GCM is not going to help in this case, I can't change the architecture at the moment).
First of all I tried writing a Service but since the service is running in the same process as the app's main thread, whenever the app is closed, then the service is restarted. (I have returned START_STICKY on onStartCommand()).
After that I am begining to think I would have to develope an independent service and use AIDL to interact with my app.
I'd appreciate if you could help me with this problem.
Users can always kill your app if they want to. If you've marked your Service as STICKY, Android will simply restart it for you. In this case you will need to recognize that your app has been restarted and recreate the persistent socket connection. There is nothing you can do to prevent a user (or Android) from killing your app under certain conditions.
I am writing an app that connects to a Bluetooth device, continuously receives data from it, and stores in local db. Certain data received requires system alert to pop up. There is a main activity which just displays the status of connection and data received. It all works just fine so far, including the popups.
Since the app requires to be run in background I have implemented a "bluetooth connection" service that manages the BT connectivity, and displays ongoing notification in order to avoid being killed. For coding clarity reasons I would like separate background service to collect all data, and log it (instead of having BT service do all the work). I also prefer loose coupling between my app components, so am using GreenRobot's event bus for all IPC. As a result my BT connection service is completely unaware of any data collection/logging code - it just dispatches a message to event bus and I'd like to keep it that way.
Now I'd like to have my data collection/logging code to be run as another background service. Is there a way to ensure it runs as long as BT connection service is running? And without displaying yet another ongoing notification or tightly coupling the code between two services?
You could let your class extend service so in this case you dont have to make a notification for it. Basically it keep running in the background without the need of displaying notification on the status bar. Make sure before you exit your app to stopservice() otherwise it will keep running until the device restarted or in somehow the user force stop your app from application manager inside of the settings.