Make a service run indefinitely and communicate with activity - android

I Can't understand the differences on android services
I want to have a service run all the time in the background (activity recognition)
When it detect that I RUN -> open GPS -> save curent longitude latitude -> if I stopped to run (WALKING) -> display the log lat on my MainActivity
i want the service run if the user close the app , if the device is closed and re-open , if my service is killed
so I read about:
[Started Service , Intent Service , Bound Service , Intent Bound Service , Job Scheduler , Job Intent Service].......But still i missing something
I understand that with Service start_sticky for API<26 will run forever (if not killed) and with IBinder I can update the UI of my MainActivity; right?
My Many Q are ...:
1. Bound services can run for ever? and update my UI of MainActivity? do i need bound or i can achieve this with service or intent service
2. For oreo I "must" use Job Scheduler -> when killed -> open again with broadcast receiver || work manager || alarm manager ||?
My questions are more for theory Answers not code.
NEED to -> service for "ever" run -> if (something) -> open gps -> save long lat -> show long lat in UI of MainActivity.

To keep a Service running indefinitely in the background, use a foreground service. This will force you to maintain a visible notification/nav bar icon; that's the price Android extracts from you in exchange for keeping your service running for a long time period. Supported on API 5+.
JobScheduler/WorkManager/AlarmManager won't prevent your Service from being killed. They can be used to bring your Service back to life. Also, JobScheduler and WorkManager can get your system out of doze, so you can do useful work. A WakeLock may also be necessary. If the user explicitly terminates your app, JobScheduler jobs will no longer wake it up. I don't know of any good, "Android-approved" way to resuscitate an app in this circumstance. Although, even on Oreo+, you can register to receive these intents, which you can use to regain execution.
You can make any of the Service subclasses you mentioned into a foreground service (by calling startForeground(). The choice of subclass is a matter of convenience, and depends on how you would like to dispatch & schedule your work. Your app could just as easily be implemented with the base-class Service.
START_STICKY doesn't actually prevent a Service from stopping. It's more like a request to the system: "After you kill my app/service, please restart it, if/when you see fit". In my opinion, it is not an effective way of keeping a Service running for a long period of time. If a Service is not in the foreground, and no other application components are in the foreground (e.g., on screen), then Android can kill your app quite quickly. This is more true of later versions of the OS (Oreo+).
Your Service will need to be bound to other components (e.g., Activities) from time to time. You bind to a Service so you can 1.) Make sure it exists and 2.) Carry out communications with it (call functions on it, etc.). So, yes, with IBinder, you can update the UI of your MainActivity.
Binding a Service doesn't make it run forever. If your Activity is bound to the Service, you can be confident that the Service will stick around for as long as the Activity is onscreen. Once it leaves the screen, all bets are off.
In other words, Android is very likely to kill an app/service when it's not in the foreground, and not bound to any components that are in the foreground (onscreen).
A Service can generally open up an Activity at any time it chooses, simply by calling startActivity(). Your Activity can even dismiss the keyguard (in certain circumstances), using FLAG_DISMISS_KEYGUARD.
If you can tolerate less frequent location updates, you may be able to do this without staying in the foreground, but there are limitations.

Related

Do android services have the `onSaveInstanceState` equivalent?

I want to save some data into a file/db immediately without using a foreground service in the background (as I don't want to draw user's attention), when users leave the relevant Activity.
I was thinking of spawning a background service and if my background service fails to execute it's work due to system pressure, I can enable START_STICKY and check if the intent is null when the service is restarted. Only maybe then turn the service to foreground service or, schedule a job (through WorkManager or AlarmManager, depending on how important the data is for users). However, neither of them is quite what I want. Foreground service will make the notification appear, and managers will schedule the work (not immediate).
Has anyone any idea about how to do that?

How to have a continuous running background task on Android?

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.

Keep Android service running even after Activity is closed

I am building one of those SOS apps. Whenever the device is shaken above a threshold value (detected through accelerometer), I am showing a Toast (as of now)
1) App is launched. User gives name, email, etc.. and clicks finish on last screen.
2) Service is started which keeps listening for shake.
3) It detects the shake correctly if the App is running.
4) If I close the app (the activity), the service gets killed along with it.
How do I keep the service running even if app is closed, so that it can listen to shakes from background? (That's the whole purpose of this app)
[1.I am returning START_STICKY in onStartCommand
I also tried using a BroadcasterReciever which will restart service by receiving broadcast from onTaskRemoved
I am testing on ASUS Xenfone Max, Marshmallow OS
]
You have two options:
Start your service as foreground service (with startForeground(int id, Notification notification): docs. But in this case you will have to show Notification in notification tray for as long as your service is running
Use separate process for your service adding in manifest to your process android:process=":nameofyourprocess"
Try starting a service without binding it to the activity (Simple unbound service). Return null on your onBind() function. Sticky services attach itself to a activity and has a lifetime as long as the attachment survives. You might have a constant notification related to your application when you use foreground services.
You can put a Service in foreground, in which case it will always be considered as active (and it will therefore have its own notification, so the user knows that an active Service is running). It won't be stopped until it goes back to background. That is what you want in your case, as you want your Service to stay alive as long as possible. As described in the Android Service documentation:
A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory.
The idea is the same for Activities and Services, actually: when Android needs memory, it starts killing processes. The foreground processes (e.g. the Activity that is displayed on the screen, or foreground services) have a higher priority than the ones that are in background (say, a paused Activity), so they will be the last ones to be stopped by the system.
Using START_STICKY just tells the system that if it has to kill your Service, then you'd like it to restart it can. That doesn't say this Service is higher priority than the others.

new to android - understanding the use of the service

I have been going through this very short tutorialand I am confused as to what is the function of the service. I am also confused as to what is the function of the broadcast receiver.
I tried to do some research and here is what i understand:
- services run in the background, but... i don't understand why we need something
to run in the background to make the phone wake up at a certain time.
I "think" the broadcast receiver acts as some kind of catcher's mit, in that
when the pending intent is launched at a specific time, it catches it then
launches the service... how close am I to the truth ?
As i think that services are used for long running tasks and especially in those cases that run when your main activity is not running.
For this functionality we can use threads this make us to say that a thread is created inside our activity and it can't be active outside of the our main activity,
that is the drawback that's why we have services .
Document URL
Services can be used to run long running tasks independent of your screen flow. For example, consider your application require to communicate with a server via socket throughout its running duration, you can start a service to handle this. Imagine that against starting the socket and making connection at the start of every activity, and clean up when that activity stops.
Services by default run in the main thread. But you can start separate threads in a service context, just like you do in an Activity. If your background task can overlap across multiple activities, then it is better to start it in a Service context because every Thread/AsyncTask created retains the context that it is running. In that case your Activity will be retained even if user navigates to another activity because a thread started from that Activity is already running. If Activity is retained, it might prevent all its views, images getting garbage collected.
What Services can't do is to directly alter UI components. For that it needs to communicate with the currently running Activity context. In short, if your non UI task does overlap the life time of a particular Activity, it is better to shift that task to a Service.
What is the function of the service ?
A service is a component which runs in the background without direct interaction with the user.
As the service has no user interface, it is not bound to the lifecycle of an activity.
Services are used for repetitive and potentially long running operations, i.e., Internet downloads, checking for new data, data processing, updating content providers and the like.
TO READ: Service
What is the function of the broadcast receiver ?
Broadcast receivers are the second kind of component. Like services, they only exist in the background and don't interact with you directly. But unlike services, they can't stay running or perform long tasks: they exist to respond to events. And unlike activities and services, more than one broadcast receiver can be started in one go.
Each broadcast receiver can react straight away, for example by creating a notification, or it can start a service or an activity to take further action. As soon as the broadcast receiver has handled the event, it is stopped and will not run again until another similar event is broadcast.
TO READ: BroadcastReceiver
I don't understand why we need something to run in the background to
make the phone wake up at a certain time ?
We don't want that the application should necessarily be in the foreground to wake the phone up.
Moreover we want notifications in the background.
We started the service. Now even if we close the application, you can get the phone wake up notification. This is so useful.
Services are great to interact with a user through notifications (a way of alerting a user about an event that he needs to be informed about or even take some action on getting that information). Many a time, applications will need to run processes for a long time without any intervention from the user, or very rare interventions. These background processes need to keep running even when the phone is being used for other activities / tasks.
To accommodate for such a requirement, android has introduced the "Service" component.
It runs in the background until it stops itself. This means that a service could be keeping your phone awake (using a wake lock), running down the battery, or using lots of network data, without anything showing on the screen.
I "think" the broadcast receiver acts as some kind of catcher's mit,
in that when the pending intent is launched at a specific time, it
catches it then launches the service... how close am I to the truth ?
Correct, they are meant to respond to an intent (usually one sent by a service or a system event), do something, and be done. When an intent is broadcast via sendBroadcast, it will be sent to all receivers that have matching intent filters.
Service - is a component of android, which runs in the background with out any UI. By default service will run in Main thread only.
Thread - is not android component, but still one can use thread to do some background task. Using thread in place of service is discouraged

Prioritize scheduling restart of crashed android service

By using START_STICKY , if my service is crashed/killed by task manager, it automatically restarts. I see that there are a list of services which gets restarted but in a different order. I want to prioritize this restarting of the service so that it will start sooner by placing to the front of the queue.
It typically takes 15 seconds to 45 seconds to re-start the service. Is there a way to prioritize or start this service sooner than the other.
Is your service long running? If it is, try to get rid of it and only start it when it is needed. Android services are not meant to run as a daemon, they are meant to run as short living workers in the background when no user interaction and interface is needed.
Most of the "I'm just sitting around" services can listen to broadcast intents and be a nice citizen this way.
Another thing: If your service is already short running and the a task killer is active, it's easy: It's the users problem and not your fault. The system doesn't need task killers and you shouldn't take care of them. The user should know that it's not healthy to use them.
I guess this solution is a little bit dirty, but you could use a new Service that starts with START_STICKY and set all other services to START_NOT_STICKY.
You could then use the new service to start all other services (though this is not necessarily needed). This is actually an easy implementation, as you can pass the whole intent to the service that shall be started.
Then you could add a Broadcast on all service's OnDestroy() to tell the new service, that one of the old was killed by the system. You can also pass the old starting intent via OnDestroy(), so it gets restarted.
In case your new service gets killed, you can check after restarting if any of the other services was killed, too and then prioritize the restarting.

Categories

Resources