I have an Android service which connects to a Bluetooth peripheral.
I don’t want Android to kill my service at its own discretion, as that would defeat the purpose of the app.
However, the app sometimes attempts to launch the service and connect when it just suspects the BT device might be in range—which may succeed or not. Unless the connection is successful, I don’t want to bother users with the notification which would be shown when the service becomes a foreground service. (The user can enable or disable this feature, thus it’s not about doing things behind the user’s back.)
I therefore considered delaying the call to startForeground() until the Bluetooth connection is complete. Brief description in prose (as code would be lengthy):
MyService#onStartCommand() creates an AsyncTask and launches it (it will run in a background thread, to keep the lengthy Bluetooth connection setup off the UI thread).
AsyncTask#run() sets up the Bluetooth connection.
AsyncTask#onPostExecute() (which runs on the UI thread after run() finishes) verifies we’re connected, and if so, calls startForeground(), creating the notification.
However, after onStartCommand() returns there is a short timeframe in which the service is still a background service.
Is there any risk of Android killing my service in that brief time to reclaim memory (when it would leave a foreground service alone)?
If so, does Android take the time elapsed since the service was started into account (killing the longest-running services first)?
Related
I am currently using a foreground service to check every 30 seconds if a specific bluetooth device is in range.
When it comes in range I connect to it and read data to display to the user.
I've been reading up on background services, and even though during the actual connection it should be a foreground service, while waiting to connect it should be a background one.
so I made a different service (yes I know I could just move it into foreground when it becomes connected, but I prefer to use a different service for it) which is in the background and will continuously scan for the specific mac address, when it finds it it will start the working service which will run in the background.
I don't mind the system killing my service if it is low on memory (it is not that important, plus if the user wishes to connect they can force the connection through the ui which will start the foreground service), but I would like to make sure that when there is enough memory the service is started again, is START_STICKY enough?
In case the system destroys my service, where do I put the clean up code? will onDestroy always fire?
Finally how can I test low memory conditions for android so as to make sure the restart goes correctly?
this has been answered here please ignore it
I'm fighting with the Android desire of killing everything which isn't active on the screen. My problem in few words:
I have a microcontroller which communicates with a processor on which Android runs;
the processor must keep active a watchdog on the microcontroller, resetting periodically (every one second) one of its registers; an application, say App B, accomplishes this duty;
on the processor I can be sure about the persistent existence of another application, say App A (or, however, if App A dies App B can die too because the system is compromised) which for now does nothing, in the future will accomplish other duties.
Which is the best way to implement App B?
I tried the following solution: App B contains a Bound Service, say Service A, to which App A can bind on; Service A starts a thread, say Thread A, which periodically resets the microcontroller watchdog. Thread A is launched when app A sends a command to Service A (e.g. START_WATCHDOG).
In my idea, Service A lives until App A lives (thanks to the binding), and so the process to which Service A belongs lives, and so also Thread A.
Unfortunately, from tests I see that sometimes (in a sporadic manner), after some time (sporadic time, too), with almost no work running on the system (except for App A, Service A and Thread A) the system kills Service A process, and so Thread A stops and the watchdog elapses.
When Service A dies, it is restarted (because it is a Bound Service and App A is still running) but, for now, I don't save the current state of Service (which simply consists on the START_WATCHDOG command arrival or not) and this is the reason for which the watchdog elapses.
So, I've got several questions about my solution:
is it ok and I simply need to save the current state of Service A in order to restore it when restarted?
should I discover better the reasons for which Service A, or better its process, is killed?
is there a better solution for my problem?
Thank you very much to everyone who will spend some time to help me.
Being not sure about periods in which your service runs you can try these:
Use foreground service. However, you might need to acquire a wakelock within your service start point if you need cpu in long time. Plus, a notification needs to be shown on phone status bar.
Use WorkManager-new api part of jetpack simplifying the use of alarm managers and jobschedulers- to schedule your tasks periodically. However if your frequency is higher than 1 per 5-10minute then you will need to take care of doze mode. If phone gets into doze, your tasks might be delayed till maintenance periods. A trick to apply here might be starting a foreground service when you catch activation of doze mode and return back to Workmanager logic in deactivation(if you don't want user to see the foreground service's notification). Do whatever you want in the foreground service like.
Use Firebase Cloud Messaging to push notification from your server to your users periodically for you to have a small amount of time to do work in background. When notification comes, OS grants you an interval to run a task.
Use Work manager it is easy to implement.
I have been searching the net for hours. I am trying to make an application that has a UI interface and a service running in the background for SIP phone communication, kind of like Skype.
The UI starts and stops the service based on UI events, and the service stays logged in with a internet server in the background. I have found many articles talking about running the service on a separate thread(done), using startService as opposed to binding the service(done) but whenever I use the task manager to kill the application as a user might, I get an error popup saying my application has crashed and the service no longer runs.
How do programs like Skype, Facebook, or email clients do this?
Do I have to run these as separate applications using implicit intents?
Is there some settings I have to set in the manifest file other than declaring the service and it's name?
Better yet, is there a link to some page or source example using this kind of service?
EDIT: Sorry, I guess I wasn't clear. The service is stopping, and I don't want it to. I am trying to keep the service running in the background even after a user kills the application with the application manager.
One of the more confusing things with Service is that it is not run in a separate thread by default. Calling startService() as opposed to bindService() makes no difference in this regard. However, the binder mechanism will cause the Service exposed methods to be called in arbitrary thread context. In both cases, your Service is part of your application's process. If you kill it via the task manager or it crashes then the Service dies as well.
When you kill the app via the task manager and it pops up the message about the app dying, you have something misbehaving. Check logcat and it will point you at exactly where the crash happened.
If you need to have your Service running regardless of the UI, then don't stop the Service when your UI exits. You will still call startService() when your UI starts to re-connect (and possibly re-start it), but don't stop it unless you really want it stopped. Starts do not "stack". If something calls start 5x it doesn't take 5 stops to terminate the Service, only 1.
I'm writing an Android app whose main Activity starts a Service that makes itself sticky. The Service makes repeated HTTP POSTs to a server, exchanging some information. This process works perfectly as long as the phone's screen is on, but once I turn the screen off, the service stops after a while. Is there any way to guarantee that my Service keeps running indefinitely?
Is there any way to guarantee that my Service keeps running indefinitely?
No.
Furthermore, you should not want your service to be "running indefinitely". Certainly your users do not want your service "running indefinitely", as that is why they will attack you with task killers, the force-stop operation in Manage Services in Settings, and so on. Not to mention all the lovely one-star ratings on the Market, choice comments in discussion boards, and the like that such applications will trigger.
Moreover, your problem here is not that your service is not running, per se, but that the device is falling asleep. This is perfectly normal. Users want their device to fall asleep -- otherwise, their battery life will be horrific.
The Service makes repeated HTTP POSTs to a server, exchanging some information.
The proper way to do this is to use AlarmManager, to trigger your code to execute periodically. Your user should be able to control the period (perhaps via a SharedPreference), including an option of "I'll manually request the data transfer, thanks". And, via an IntentService or similar means, you arrange for your code to be started by AlarmManager, do its work, and then shut down to get out of RAM.
Getting AlarmManager to wake up the device out of sleep mode is not that difficult (use a _WAKEUP flavor of alarm), but keeping the device awake long enough for you to do your HTTP request can be. The HTTP request cannot be performed on the main application thread, as it may take too long. One recipe is to use my WakefulIntentService component, which is an IntentService that keeps the device awake long enough for your work to be complete, then shuts down and allows the device to fall back asleep.
First Way: What you can also do to make HTTP POSTS to a server continuously is, you can make a timer and inside the task of the timer ie. in run() of class TimerTask you can make startService() and as soon as you are done with the HTTP POST work you destroy the service. Thus on a periodic basis, the timer will start the service and there won't be any background service.
Second: You can also use the PowerManager.WakeLock
Third: You can use AlarmManager as discussed in the previous answer.
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.