I have an Android service that's responsible for firing notifications at certain points in time. I use an android.OS.CountdownTimer for this. An activity creates and starts the service. If the phone is locked, notifications that are within let's say 1min are shown. Notifications that are much later are never shown. The service is unbound from the activity when the activity is onpause.
As long as the phone doesn't lock the notifications are generated, even if the activity is stopped and unbound from the service.
It seems to me that the service is stopped/killed. When I make the application debuggable and debug it on target, it works fine, also when the activity is stopped and the service is unbound.
The app is developed for v1.5 and runs at Galaxy S with 2.2.
Service is started as shown below
serviceIntent = new Intent().setAction("com.mytest.MyService");
startService(serviceIntent);
bindService(new Intent(context,
MyService.class), mConnection, 0 /*Context.BIND_AUTO_CREATE*/);
I have an Android service that's responsible for firing notifications at certain points in time. I use an android.OS.CountdownTimer for this.
Please do not do this. Please use AlarmManager and an IntentService, so you do not have a service running all of the time. Users will kill your service using a task killer or the Manage Services screen in the Settings app. Android will stop your service. You are better served going with an architecture (AlarmManager/IntentService) that works in accordance with user and platform wishes.
Related
I've read that I should call
startForegroundService(intent)
if I want to properly start a service that can run as a foreground service. But how should I think if I want it to start without it being a foreground service but potentially becoming one later on? Some info on how we have it right now:
We have an App which uses a service for many tasks. It performs all of these task when the user interacts with the app in the foreground but depending on if the user has enabled a certain feature we want to keep performing these tasks in the background. So when the app is launched (and obviously is in foreground) we start the service using
startService(intent);
When the app transitions into background we check whether the feature is enabled, and if so, run startForeground(id, notificiation); which effectively adds the non-removable notification out in the OS and the service keeps on running. When the app goes back into foreground we call stopForeground(true). If the feature isn't enabled the service will never be set as a foreground service and we won't try to perform these tasks in the background.
So my question is: Is this sufficient to get the "full foreground service performance"? Or am I losing something by not calling startForegroundService(intent)? My impression is that we actually do have a fully working foreground service but I'm getting confused when I read statements that foreground services must be started using startForegroundService(intent) which we're not doing. If we really need to use startForegroundService(intent), the only solution I can think of would be to initially start a normal instance of the service and when the app enters background we start a new one using startForegroundService(intent). But do we need to do this or is running startForegund(id, notification) on a service started using startService(intent) sufficient to achieve a foreground service?
NOTE: One difference I find is that if the application itself is in background when start the service I then need startForegroundService(intent) for API >= 26. In our case we always start the service when the app is in foreground. I do however recall some instances where I've seen the exception thrown when we try to start the service using startService(intent), somehow the app (very very rarely) still think it's in background (perhaps something from the OS comes up just when app is launched). So if I catch when that happens I could run startForegroundService(intent) to start the service. But is it possible to run stopForeground(true) on that service when the app comes back into foreground? Or is it bound to be a foreground service forever since we started it that way?
Seems like you don't have to call startForegroundService and startService is sufficient:
If your service is started (running through Context#startService(Intent)), then also make this service run in the foreground, supplying the ongoing notification to be shown to the user while in this state. By default started services are background, meaning that their process won't be given foreground CPU scheduling (unless something else in that process is foreground) and, if the system needs to kill them to reclaim more memory (such as to display a large page in a web browser), they can be killed without too much harm. You use startForeground(int, Notification) if killing your service would be disruptive to the user, such as if your service is performing background music playback, so the user would notice if their music stopped playing.
From Documentation
I read your question multiple time and I think (hopefully) the answer to your question is :
According to the official document of Android 8.0 Background Execution Limits:
Android 8.0 introduces the new method startForegroundService() to
start a new service in the foreground. After the system has created
the service, the app has five seconds to call the service's
startForeground() method to show the new service's user-visible
notification. If the app does not call startForeground() within the
time limit, the system stops the service and declares the app to be
ANR.
So, make sure you have started ongoing notification by calling startForeground (int id, Notification notification) in the onCreate() method of your service.
Note: Apps targeting API Build.VERSION_CODES.P or later must request the permission Manifest.permission.FOREGROUND_SERVICE in order to use this API.
And there is great medium article posted by Maciej Witowski that help you understand how really new services API works :
https://proandroiddev.com/pitfalls-of-a-foreground-service-lifecycle-59f014c6a125
I developed two apps(can be more in the future) which are using the same service. When I start one of the apps they should start the service(if not already started) and send the name of an activity to tell the Service that the app is available.
The service is located in a third project, which is implemented as a library in the apps. The service listens in the Background for an event and start one of the apps.
The problem now is, how I start the service.
I tried already startService and bindService:
startService:
Intent intent = new Intent(this.getApplicationContext(), DriverBackgroundListener.class);
intent.putExtra("className", "com.example.testProject.Activity1");
this.startService(intent);
Starts a new Service for both apps, because the service is not located in the same app. So 2 Services are running and listen for the same event.
bindService:
I implemented it with the help of a Messenger. (https://developer.android.com/guide/components/bound-services.html)
The Problem here is, that the Service will only run if minimum one Activity is bind to the service. But I need to finish the Activity so the user can use the device normaly. But that will unbind the service and shut it down.
I also have to run the Service after a reboot. But I guess that will work if I create a BroadcastReceiver which starts the activities after the device is booted.
Have anyone an idea how to handle this?
Thanks best regards
Fabian
If you start service and then bind to it with flag 0, it still work even after you disconnect from it. You can try to connect to service first and make a check in onServiceConnected(), and if not start service. Also take a look at AIDL https://developer.android.com/guide/components/aidl.html.
I have intent service in my app. This service has some job to do - uploading some files. It runs only when there is something to do.
Service won't upload when some conditions are met, for example no Internet connection. For that reason it registers itself to on broadcast receiver to receive message about Internet connection changes.
The problem is that service is killed with app even if it is doing something, for example:
App is sending intent to service
Service started uploading something, everything fine
X% uploaded, app is killed, service is killed
Internet connection changed - service is woken up.
If service is woken up after app is killed, why is it killed with the app? Is there any way to prevent killing service when app is killed?
I'm killing app manually. I know android could kill my service anytime and I don't want to prevent it. I just want to have this service running after user closed or killed app.
"It runs only when there is something to do." only theoretically :) - maybe that is you what you want to achieve.
"The problem is that service is killed with app even if it is doing something, for example:"
Of course, there will be cases when the user action will end your Service or Intent service.
This is a fail answer.
"Is there any way to prevent killing service when app is killed?"
It is just watch for "parental control" task protection" keywords in Google!
Because you used an intentService that mean the intentService will destroy once the activty destroy
so you have to use Service instead of intentService, so you can uplaod your file in the backgroud.
According to manipuation between the Service and the activty via broadcast receiver or to bind the service to activty.
Edit :
The Service may be triggered from any thread.
The IntentService must be triggered from Main Thread.
If you don't mind showing notification (in your case, you can for example show notification with upload progress), then in your IntentService (or Service) you can call:
startForeground(int id, Notification notification)
This should prevent killing your service when your application is killed.
From documentation: "You can set this flag if killing your service would be disruptive to the user, such as if your service is performing background music playback, so the user would notice if their music stopped playing."
I want to run a service to collect the accelerometer sensor information and it shouldn't stop when the phone is sleep or the activity (for starting the service) is not running.
I have to send start and stop commands to the service from the menu activity.
currently I am using a bundled service in the same process of the activity but the problem is that it gets closed as soon as activity is closed (return key pressed).
I am wondering if I use a separate process it will resume even if there is no bundled activity (when activity is closed).
If not, which service model should I choose?
You are probably looking for startService instead of bindService.
http://developer.android.com/reference/android/content/Context.html#startService%28android.content.Intent%29
However, even with startService, there are no guarantees the service will remain running "forever" and "always".
WARNING, the options below will consume a lot of battery.
You can increase the chances the service will not be stopped by changing the priority to startforeground (requires a notification).
While the screen is off, the only way to keep the service "alive all the time" is to use Alarm Manager with an RTC_WAKEUP or ELAPSED_REALTIME_WAKEUP schedules.
Less battery...
Practically speaking, however, without startForeground and just using normal RTC or ELAPSED_REALTIME alarm schedules, your service will run most of the time.
You can create a service in the same process with your application, even if your activities all closed, the app still work because your service still alive until you call stopservice (the system will restart your service automatically when it is killed by system). if your service perform complicated communication with activities , i think you should use remote messenger service. During running of service you can bind to service to send and receive data between service and activities.
For more information of service and communicate to service, you can refer here
I have a service in my app, as some other apps have, too. From what I am used to, I can see (and kill) services nicely in settings -> (running) services. But: not mine...
The service itself is extended from IntentService. It is handling Alarm Intents via BroadcastReceiver and also messages from my app and back to do some work. As it's essential to my app and keeps some remote web session and other (read: "a lot of") persistent data, I do explicitly start it in main activity with
startService(new Intent(this, HeartBeatService.class));
and in the service, I even use
startForeground(NOTIFY_RUNNING, runNotification);
Other of my apps' activities using the service just using bindService(), working like a charm.
It really is running. Perfectly and always, as I wished, even if the activities get killed by android because of whatever android thinks it's good for.
Just: I don't "see" it running.
I also tried overrriding the service onStartCommand() to return START_STICKY, but nothing changed. I know, this one should not be overwritten in IntentService.
Or am I just thinking wrong somehow? Is IntentService "different"?
Thank you!
From the Android documentation reference:
IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
Your service will only run when it receives an intent and stops once it is done doing what that intent had it do.
Also, I've found that services bound to activities will not show up in the running services screen.
Once you remove the binding, they show up.