How to ensure RemoteViewsService is run in the background in Oreo? - android

Android 8 has its background execution limits, so when we started targeting Oreo we changed our services to using JobIntentSerivce to be able to get work done.
However, we have a widget that updates every few minutes with live score data. The widget's service extends the good old RemoteViewsService. How can we make sure that the widget is updated even when the app is in the background?
I've taken a look at the suggestions in another SO question, but they all seem to have some caveats:
JobScheduler needs a JobIntentSerivce which I can't see how can be combined with RemoteViewsService (or can it somehow?)
PendingIntent.getForegroundService() is not perfect when on a poor Internet connection (or maybe a slow device) and will sometimes either give an ANR, and we ideally don't really want to show a notification when we see the time limit is closing in on us
I haven't experimented with BroadcastReceiver.goAsync() yet, but maybe that is my best shot?

Related

What's the proper way to schedule tasks and reminders in Oreo?

Background
Ever since Android O came out I had trouble with what classes and methods I should use when I want to schedule background sync tasks and notifications, more specifically, I want to do these two separate things:
Background sync task to download data from the server, and notify the user about important information (that was just fetched from the server). These syncs should occur at an almost precise time of the day (e.g. 21:30 ±10min).
Notify the user about an upcoming event, for example, one week before an exam.
Because Android O has placed some restrictions on AlarmManager, I cannot set a background service that runs at a specific time of the day, unless I use getForegroundService(), which, as the docs say, should only be used for services that are noticeable to the user.
What I tried / considered
I have been using JobService that runs periodically every so and so hours, but I would prefer for it to run at a more specific time of the day.
I have looked into CalendarProvider, and also considered a push notification service, but it seems to me like an overkill for simple tasks like these.
Question
My final question is what methods I could, or I should use to implement the above features?
Use WorkManager this is the best way to Run Task in Background in Android Oreo and Pie versions and it also works in older versions of Android.
See the Documentation
https://developer.android.com/topic/libraries/architecture/workmanager
https://developer.android.com/topic/libraries/architecture/workmanager/basics
https://developer.android.com/topic/libraries/architecture/workmanager/advanced
GitHub Example
https://github.com/krunalpatel3/WorkManager-Example-Andorid
Reference
http://thetechnocafe.com/how-to-use-workmanager-in-android/
https://www.youtube.com/watch?v=fAQKvBHeg_w
https://www.youtube.com/watch?v=1VVir3-4hII
https://www.youtube.com/watch?v=0jgkQYebYvQ
https://www.youtube.com/watch?v=ooP8kkhvRQI

Running service to download content (SyncAdapter vs JobScheduler vs Service)

I am still new to android and working on an application that works on Android (API >= 21). This application displays data that is previously downloaded from a server on the local network so I need to implement a service to download the content, on-demand & Periodically, on the device.
SyncAdapter
I've implemented this "Downloader" using SyncAdapter and it was working fine but at the end the code was really verbose:
The application does not have ContentProvider. The content is downloaded as files.
It runs on a local closed network so there is no need for authentication.
The application had 3/4 extra classes that not doing any real job.
JobScheduler
After some reading and searching, I decided to go with JobScheduler.
"JobScheduler is guaranteed to get your job done." medium article
It looks easy and has clear API, I said, so I re-implemented my "Downloader" with JobScheduler and the result was really good. The application was able to download the content, writing a good log to trace errors and operations. The Job runs when the device is Idle and kicks off/stopped, on demand, as expected.
I used alarm manager to implement the periodical calls of the job and turning wifi on. Oh, I forgot to mention that the application is the responsible of turning on the wifi because it is inside a case and works as Kiosk
The problem is that there is a catch. This is not mentioned in the documentation, or I was blind not to see it, at all. The Job is limited to 1 minute only (1 minute on lolipop and more on Android >= 0) then the onStopJob() will be called. So my is cancelled before completing the download when the data is a little big. Of course I can keep my thread going and continue download in the background but in this case I can't benefit from the API to maintain a good log, reschedule my job and manage Wifi status.
I need another implementation
I need something similar to SyncAdapter or JobScheduler that runs when the Wifi is on and when the device is Idle.
I am not sure whether triggering a service from JobScheduler is the solution I am left with. I need a little certain information before implementing the same thing for the third time.
Any idea?

When to use and when not to use a Service in Android

I have been developing for Android for little less then 2 years, and I am still puzzled by this seemingly simple question.
When should one implement a service?
From my experience there are some rare cases but I am questioning this because on every phone there are quite a lot of them running and I doubt it's just a poor application design.
This is essentially core of my question but following are some of my experiences and thoughts about the subject which can explain my question in more detail.
In all apps that I have developed only one really required a service. It was a background sound recorder and I was using it as Foreground service with notification since I wanted buttons to be able to control it (like music players do for example).
Except this I never really saw a requirement for the constantly running service because:
A) Intent listeners (Manifest registered BroadcastReceivers) are quite a useful feature and using them as you know is usually enough for many use-cases (for example showing notifications).
B) If scheduled execution is a must one can subscribe to alarm events.
C) I know that service in Android is quite different then for example in Windows since in Android services are just a "package" to organize your code in and have a the system manage the lifetime of the object. Services use the Main Thread but it's customary to spawn new threads in them.
D) In the development documentation services are suggested for network communication and background calculations but I don't get why you should not just use AsyncTasks for that. I am a big fan of these and use them extensively for lot of things from downloading data from the internet to doing FFT calculations under time critical conditions.
E) I get the usefulness of Foreground services but why are people using background services so much (excluding the system apps).
Those are my thoughts about the SERVICE and I hope someone with more experience will be able to explain these PROS and CONS (along with others that I probably missed).
When should one implement a service?
When you have work -- delivering value to the user -- that:
Needs some time to complete, perhaps longer than you have time for in the component wishing the work to be done, or
Is delivering that value under user control (e.g., music player, controlled by play/pause buttons in a UI), or
In rare cases, needs to be running continuously, as it delivers value continuously
there are quite a lot of them running and I doubt it's just a poor application design
Some are likely to be poor implementations, either due to technical misunderstandings, or other concerns (e.g., making marketing happy) trumping making users happy.
It was a background sound recorder and I was using it as Foreground service with notification since I wanted buttons to be able to control it (like music players do for example)
That is a reasonable use for a service, IMHO.
Intent listeners are quite a useful feature and using them as you know is usually enough for many use-cases (for example showing notifications)
I assume that by "Intent listeners" you mean manifest-registered BroadcastReceivers. In that case, if the work to be done by the BroadcastReceiver will take more than a millisecond, that work should be delegated to an IntentService for completion. onReceive() is called on the main application thread, and it is not safe for a manifest-registered BroadcastReceiver to fork a bare thread, as the process could go away shortly after onReceive() returns. However, in these cases, the service is usually short-lived (e.g., do some network I/O and disk I/O, then go away).
In the development documentation services are suggested for network communication and background calculations but I don't get why you should not just use AsyncTasks for that
An AsyncTask is a fine solution for background work that is:
Requested by the UI (activity or fragment), and
Will take less than a second or so, and
Is non-critical
For example, if you are downloading avatars to show in a ListView, AsyncTask is probably a fine choice, whether you use them directly or use some image-fetching library that uses them internally.
Conversely, if the user buys an MP3 through your app, and you need to download that MP3 file, an AsyncTask is not a good solution. That could easily take over a second. While the download is going on, the user could switch away from the app (e.g., press HOME). At that point, your process is eligible to be terminated... perhaps before your download is complete. Using an IntentService to manage the download is a signal to the OS that you are really doing work here, adding value to the user, and so the process will be left alone for a little while.
Note that if the background work might take 15+ seconds, WakefulBroadcastReceiver or my WakefulIntentService is probably a good idea, so the device does not fall asleep while you are trying to wrap up this bit of work.
I can name some of the Service uses from my experience:
to implement
location listener,
sound module, generating various voices
in app content updates,
API, provide services to other apps
in app billing
Communication with webservices (if requests frequency is high)
actually (excluding 5.) they all are working for the whole app duration, they are using some of the other android services, also they manage their state. I suppose one of the important thing here is state management during application life cycle changes.
I prefer to look at AsyncTasks in a same way as Executors (ExecutorService), they should be executed sequentially and for small tasks.
In the android website, you can find a table when to use Service, Thread, or WorkManager (the new API for scheduling jobs, currently in alpha as of this comment posted). https://developer.android.com/guide/background/#table-choose
The website also state that you need to use started service only as last resort. The Android platform may not support started services in the future. Refer to this link https://developer.android.com/topic/performance/scheduling#services
You should avoid using started services that run perpetually or perform periodic work, since they continue to use device resources even when they aren't performing useful tasks. Instead, you should use other solutions that this page describes, and that provide native lifecycle management. Use started services only as a last resort. The Android platform may not support started services in the future.
If you consider UI and bound services, u would think that both can exist and not be doing anything for certian periods. In such scenarios, your UI can be recreated a lot of times however service does not. And this is where service is important. Lets say you are processing images and then rotate device you want processing to continue while UI is being recreated. You recording a voice and then rotate device. These are one of the places where I find service very important. (Having lot of heavy data processing, interaction with web, that could be few seconds)

phonegap/webview apps and background services

I hope this question meets the criteria for the site. I'll happily update otherwise.
I am, like many others, developing an application for multiple platforms using the PhoneGap (in this case Cordova 3) framework and want to keep my application alive while the use performs others tasks. I have read around this subject and seem many opinions and possible/partial solutions.
Notionally, what I want to do is allow the user to return to the application had they pressed back, home, they got a phone call, they played tetris or whatever and specifically if the app wants them back under certain conditions.
I am presently tackling this by concentrating on the Android platform and will expand out after this solved. I understand the mechanism by which Android OS will kill processes that are not visible and understand and have implemented an example background service.
I employ JQuery Mobile with collapsible content for my application.
Before I continue development, I would like to ensure I am on the right path.
I have successfully implemented pause/resume to handle phone locking and sleep. My application does not die and I can make it beep and vibrate through appropriate plugins.
My continued intention is this ...
Write a background service to perform periodic "checks" in this case position of phone relative to a known position. The intention is to inform the user when they have reached certain proximity. This would be started on the "pause" event and stopped on the "resume" or of the app is restarted.
Using Local Storage, maintain a record of state of the UI so it can be restarted in the correct state. Upon restart, the stored state will be restored and the app will look like it never went away. There is nothing in the app which continuously updates, like graphics or logs, so there is no reason to retrieve "past states" from the background service and perform a rendering of those as if they had been performed by the app, but that would not seem unreasonable should that be required on the future.
As it's possible that the app will not be running, it seems necessary for the service to create a ("something important has happened") notification that the user can click on in order to restart the application. I have found a couple of status bar notification plugins and intend to use one. I trust I will be able to beep/vibrate accordingly from the background service alo.
In addition, a "stuff is generally happening" continuous notification could be used to restart the app. I see no conflict with the above. It would be nice to find a "bring app to foreground is it's running" method, but I'm holding out no hope.
My essential question is this ...
Am I approaching this problem correctly and maintaining as much cross platform work as possible whilst not setting myself up for a fall when it comes to implementing the iOS facet of the solution?
I just don't want to miss a trick I've not located in the sea of answers to what seems like a common problem.

A background sensor data collector in Android

I am now programming a program that collects sensor data, e.g. acclerometer values for a whole day.
Current I just use an Activity and run the activity for a whole day (I turn off screen auto-black), and don't make any shortmessages or phone calls during the day.
I've heard I can make this kind of long running data collector in background using Service. But after I've checked the pedometer at http://code.google.com/p/pedometer/. I found that, when the screen blacks out, the pedometer does not work. (But An application like predometer should work in any case as long as the power is on.)
Although I don't care about the power problem of always sensing acclerometers, I do want to black out the screen to save the power in screen to record more acclerometer data points.
I am thinking about two ways:
1.Using an Service, however, as the pedometer application showed. When the screen blacks out, the service seems stoped working too! Maybe the code has bugs.
2.My application is still an Activity. But I change the scrren light into 0 or totally black to save power.
My question is that: for 1) does a Service have the abality to be always running even when the screen blacks out for a long time; For 2, how to change the screen light?
Thanks!
concerning 1 - what you need is a remote service. this is a service nearly similar to a 'local' service (that is used in the pedometer example) but can run even if no activity is bound to it, in the background. you can turn off the screen and even the activity can crash (in a bad case ;) ) but the service keeps running if you started it with startService(...) instead of bindService(...).
try getting through this and see if that helps.
concerning 2 - you should really use (1) ;)
You do not need a remote service - this can be done with a local Service.
Use the command pattern instead of the binding pattern for the service i.e. use startService() / stopService() rather than bind() / unbind().
In your service onStartCommand() method, return Service.START_REDELIVER_INTENT or something similar, so that the service lives longer than the Activity.
Now the trick: to keep the service processing properly when the phone goes to sleep, you need to work with a PowerManager.WakeLock. These are quite difficult to get right, and I don't think a full explanation is needed in this answer.
Here is some more info:
How to get an Android WakeLock to work?
Also try Lars Vogel's blog: Using Android Wakelock – Staying up all night long
Apologies for the summary answer, but your question is quite broad in terms that it touches on some advanced topics.
Background service can be implemented with IntentService for the most of the scenarios.
Make sure that the background service works in latest and earlier Android version like 2.3 or 2.2.
Designing background operations is different starting from Android 4.0.
Best Practices for Background Jobs
Performing Network Operations

Categories

Resources