Android 9: Background Restriction App Setting - android

I'm working on a music player app and I'm noticing weird behavior on Android 9 devices when a user enables the "Background Restriction" setting (Settings -> Apps -> [App Name] -> Battery -> Background Restriction).
Here's what I'm doing:
I start my music player service by calling Service.startService() then set it to foreground via Service.startForeground() while my app is in the foreground.
Here's what I'm seeing when "Background Restriction" is turned on:
1) Service.startForeground() will not posting a notification
2) My foreground service is killed by the OS within a minute of my app going to the background
Here's what I see in the logs:
1) "Service.startForeground() not allowed due to bg restriction" when calling Service.startForeground()
2) "Stopping service due to app idle" when my app is auto-killed by the OS
Here's my question:
I thought the whole point of a foreground service is to allow background processing with the user's knowledge (an ongoing notification); is the "Background Restriction" setting really intended to disallow all background activity?
Interesting find:
Looking at Google's "Universal Music Player" sample project on GitHub, I noticed that their sample project is not being killed like my app is. After digging I noticed this is because they are binding to their service and never unbinding in Activity.onPause(). According to Google's docs, bound services are not subject to the same background restrictions. Is this really the solution to my problem? Seems a little hacky/fragile.
Thanks in advance for the help!

Here's what I've found:
"Background Restriction" (or "Allow Background Activity" on some devices) is intended to stop ALL background activity regardless of whether your service has called setForeground()
There is no way around this setting. You cannot programmatically disable it. Your only option is to programmatically check if it's enabled using ActivityManager.isBackgroundRestricted() and display a pop-up informing your users on how to disable this setting
Google's Universal Music Player sample project on GitHub happens to work (as of the writing of this answer) only because a service bind is not released when the main Activity is paused. The sample project's service is however killed when the main Activity is garbage collected (typically 30-45 minutes depending on the device).

Related

How to make sure a service that runs when the Application is closed does not get killed?

I am developing a Fitness Application as part of my Bachelor Thesis, and want to keep track of step counts even when the application is completely closed. For this I am currently starting a service that utilises the built in Sensors "Step Counter" and "Step Detector". After some testing I found out that sometimes my Service gets killed and no longer keeps track of the steps taken. I left the phone on my desk overnight and walked around in the morning then I opened the application and the steps I took in the morning were not tracked, whereas when I close the application and immediatly start walking the tracking of steps still works.
Is there a way to make sure that my Service does not get killed?
Would the use of a Foreground Service solve my issue and are there any alternatives to using a foreground service?
Foreground Service is the only way if you want to assure that the service will not be killed.
The reason for this is that the foreground service always shows a notification to the user and can be killed by the user if he wants to, this is especially important if you want to know for sure what runs on your device.
All previous methods of making permanent running services are deprecated starting from android 9, when a new privacy policy was introduced.
Basically you need to keep service running in the background,
Here is the workaround to achieve this
https://stackoverflow.com/a/58162451/7579041
above link is useful for Stock ROM & Custom ROM Devices like OnePlus, OPPO, VIVO, etc
I hope this will help you out

Xamarin MediaPlayer interrupted by Android Doze Mode

We have a music app (mp3) developed in Xamarin (Native Android App) using MediaPlayer. There will be list of songs that should be played one after the other. After around 10 minutes or so, the player stops. Once the phone is unlocked, the Player starts playing the next track. Seems the Nougat Doze is somehow intervening the Player. If I manually disable Battery Optimization for my app, then there is no issue.
Is there any fix for this problem rather than having each user to manually change the 'Batter Optimization' option. I wonder how other apps like Spotify plays songs continuously without any setting changes. Please help!
Any process that contains a running foreground service will not be considered for Doze mode. This is what apps like Spotify and Google Play Music use. Consider creating a relevant foreground service - it will be shown in the notification screen while the foreground service is running, so a dummy service will stick out.
Another option is to request the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission and then launch an ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS intent, which will take the user to the Battery Optimization screen for your app. This is a less-than-stellar user experience but does not require the creation of a foreground service that you may not otherwise need.

Sticky Service and Intent Service gets killed when the app is destroyed

In My app I am trying to download images even though user has force stopped it and exit it using recent app manager by swiping . Why I want this behavior, it has only one reason and that is :
Because I want User to stop the download from my button given in activity
So For this I have made async task at first place , it was working nicely even the activity is destroyed, But When I destroy/kill my app using recent app manger the app gets killed and so the service
Then I moved my async task to the Service which is Sticky , I thought it should not get destroy when the user closes the app from recent app lists, but The service stops. though some times it start again , but due to some reason I just want it to not to stop and download like a google play store does. What ever you do , you can not stop downloading of app , until and unless you use stop button in the google play store app.
Then I read about IntentService, about intent service I read that ,
You can run intent service and forget about it , as it stops itself
after completion of task.
So I though this is something , which could not be killed even user stops it or close app from recent app list by swiping , as intent service would perform its task and would stop itself
But All in vein. I have read many things about the service and how to cure service from being not killed. I came to know about starting service as forground.
But what other ways do other Top class apps adopt to keep the background working all the time , like security apps , gps based apps, and antivirus apps whose services run all the time on background. You can examine same behaviour inn google play store app , you can start downloading of any app and exit the play store app , even from recent app tray , but it would continue to download until and unless you go to notification bar click notification , get navigated to place where you finally see stop downloading button to stop downloading the app.
So How can I achieve this ? what is wrong with service or what else can I use to get the same behavior as google play store has.
Please guide me . Your comments and discussion would be appreciated.
It sounds like you want to run your service in a separate process from your main application so it does not get killed if the app is removed from the "Recent Tasks" list.
This is made possible by using the "Process" attribute explained in the documentation here:
http://developer.android.com/guide/topics/manifest/service-element.html#proc
What you need is a ForegroundService. The android developer guide about services states that:
A foreground service is a service that's considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory. A foreground service must provide a notification for the status bar, which is placed under the "Ongoing" heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.
You can use return return START_STICKY in onStartCommand in service

Prevent that the app get stopped or paused by the OS

I'm developing and Android application on CodenameOne that needs to send a web request every 5 minutes even when minimized. How can I achieve this behavior in order to prevent that the request get stopped or paused by the OS?
You cant do that from the activity, you'll need to create background service.
http://developer.android.com/training/run-background-service/create-service.html
Use AlarmManager to set up your every-five-minute operation. Have it trigger a BroadcastReceiver, which in turn passes control to my WakefulIntentService (or your own IntentService that handles the WakeLock, that you will need so that the device stays awake while you do your work). Have the service do the "web request".
This is still not 100% guaranteed:
The user can Force Stop you from Settings, in which case your alarms are gone and nothing will happen until the user manually runs your app again
The user might block alarms from firing on certain devices, like various SONY Xperia models, that offer "stamina mode" or the equivalent
However, it is the best that you are going to get, short of rolling your own Android OS version.
The other guys answers are correct that you need to create a service but they somehow ignored the mention of Codename One.
Under Codename One you need to create a native directory for android and just place the service source code there (just use a blank service class that doesn't really do anything). Then you need to add to the build arguments the option android.xapplication where you would state the service XML attributes.
Having said that what you are trying to do is VERY wrong and you shouldn't do it in Android! You will drain the battery life from the device in no time and the service will be killed by the OS eventually (since it will be a battery drain). The solution is to send a push notification to the device to wake up the application.
In Android 9 and newer you can prevent your App falling asleep with a battery setting.
Long click on your App -> App info -> battery -> optimize battery consumption
Here add your App from the list.Hint: maybe the menu entries have a different name, depending on your phone.

Does android keep a log of when it starts?

I'm making a parental control/accountability app for android. It consists of a monitoring service that runs in the background and starts when the phone is booted.
Unfortunately, I have found that when android is started in "Safe Mode", services are not started automatically, and because of this my app has a serious flaw.
While in safe mode, the web and other apps can be started without my monitoring service running.
I thought that if it isn't possible to monitor app activity while in safe mode, maybe I could at least have my app detect if the phone was previously in safe mode. Then it could maybe alert the parent or accountability partner?
Does Android keep any log of this? Or any boot log in general?

Categories

Resources