I have an app which runs a background service overnight. It's triggered to run by an alarm clock app.
The app spends the night uploading data off the phone's external SD card onto Dropbox. It worked seamlessly on previous versions of Android but is not working on Pie. The background service is killed after running for about two hours every night. Interestingly, however, I've noticed that if I make a tiny change to my code, e.g. editing a string, and then run a debug, the app runs perfectly the next night but then on subsequent nights, goes back to being killed after two hours.
I've tried the following:
Using a foreground service with a persistent notification
Opening and closing an Activity after the app is opened so it's in the recent apps list
Making the app a device administrator
Disabling battery optimisations for the app
CPU and Wifi wakelocks
Running a thread with an infinite loop that uses root privileges to adjust the app's minfree values every five seconds
Disabling Pie's adaptive battery manager feature during the night
Despite all of these mechanisms, the app still gets killed. My theory is that there's some kind of artificial intelligent battery manager/performance optimiser on the phone that picks up that the app runs all night and decides to kill it in the future but then gets reset when I re-install the app.
I've tried everything and I still can't seem to find a solution. Can someone please point me in the right direction? I'm sure there's some root/reflection thing that I can do to fix this but I just don't know what it is!
I found the problem! Turns out my phone had a service called G3 which was killing the app to "save power". Apparently, this service is useless so I uninstalled it and the problem was solved instantly!
I used the following command:
adb shell pm uninstall --user 0 com.evenwell.powersaving.g3
adb shell pm uninstall --user 0 com.evenwell.powersaving.g3.overlay.base.s600ww
Pretty annoyed that this service took to killing an app that had root, administrator privileges and permission to avoid battery optimisations - how obvious do I have to make it that I want the app to stay alive?!
try job schedular
https://developer.android.com/reference/android/app/job/JobScheduler.html
https://developer.android.com/topic/performance/scheduling.html
use Alarm manager
https://developer.android.com/reference/android/app/AlarmManager.html
As one of the changes that Android 8.0 (API level 26) introduces to improve battery life, when your app enters the cached state, with no active components, the system releases any wakelocks that the app holds.
In addition, to improve device performance, the system limits certain behaviors by apps that are not running in the foreground. Specifically:
Apps that are running in the background now have limits on how freely they can access background services.
Apps cannot use their manifests to register for most implicit broadcasts (that is, broadcasts that are not targeted specifically at the app).
By default, these restrictions only apply to apps that target O. However, users can enable these restrictions for any app from the Settings screen, even if the app has not targetted O.
Nothing will work like job schedular or Alarm manager
Your problem will be only resolved by using WorkManager
Related
I am building an Android app that needs to be in constant Bluetooth (Classic) communication with a peripheral device. As long as the app is running in the foreground, everything is fine. But when the app is put in the background, the system kills the app after a indeterminate amount of time. The app can hang in there anywhere from 2 - 15 minutes. This happens even when the app doesn't have any battery optimisation. I hoped by turning the Battery Optimization OFF, it would prevent Android from putting the app into Standby Mode/Killing it.
If the app cannot run forever when the device is running on Battery, how long can one expect the App to exist in the background?
I wish the duration of the app's existance in the background was determinable! I appreciate any help on the matter.
Tested on Motorola G5S Plus running Android 8.1.0
The manifest file has background_running turned ON:
<meta-data android:name="android.app.background_running" android:value="true"/>
App's Target SDK is API 29: Android 10
You need to implement background service with WakeLock/Foreground Service, In service you need to write all bluetooth code that you want to run in background, Code that you wrote in activity/fragment place in service, for bluetooth callbacks need to implement Broadcast Receiver.
We develop an Android SDK and, while testing the Android 11 Beta, we found a problem that does not seem to be reported yet.
In Android 11, new one-time permissions have been introduced for Location, Microphone and Camera permissions. With this option, as soon as the user leaves the application, the permission is revoked (more details can be found here).
The problem is that after a short amount of time when the app is no longer in the foreground (it is not necessary to kill the app, just minimizing is enough), all future scheduled alarms or jobs are removed, as if the app was force killed.
This only happens with this level of permission.
Denying or providing other levels keep the previously scheduled alarms or jobs, as expected.
We have reproduced this in the Beta 3 build, in a Pixel 2 emulator with the RPB3.200720.005 build number. In this repo you can find a sample app for reproducing the bug.
This single activity app schedules an alarm to ring in the next five minutes, as well as a job to trigger in between 5-6 minutes.
The screen has three buttons, each triggering the corresponding permission request.
The JobService and BroadcastReceiver classes only log that they have been triggered.
The situation can be reproduced after the following steps:
Whenever the app is started, it is possible to run both adb shell dumpsys alarm | grep com.example.permissions.app and adb shell dumpsys jobscheduler | grep com.example.permissions.app to see that both the alarm and the job are scheduled;
Click in any of the buttons and grant the one-time permission level;
Minimize the app (you can go to the home screen or open other app);
After around a minute, run both adb shell dumpsys alarm | grep com.example.permissions.app and adb shell dumpsys jobscheduler | grep com.example.permissions.app. The alarm and job will no longer appear;
Waiting the original scheduled times for both job and alarm (with lenience for system delays) will show that they won't be triggered.
Have any of you encountered a similar situation? Our hunch is that to revoke the one-time permissions, the app process is being killed in some way that is causing these side effects.
We also submitted an issue on Android Issue Tracker, and we will keep this post updated if Google answers it.
The issue was 'solved'. The problem was actually with Android Studio calling a force close when the permission was revoked after closing the app.
The actual Google's response:
Thank you very much for raising this issue, and providing sample code
to reproduce it. After investigating further, we discovered that this
is due to an interaction between Android Studio and apps launched via
the "Run" command.
Specifically, when Android revokes an app's permission, it kills that
app's process. We found that Android Studio sends a force-stop command
via adb when it observes the app it launched is no longer running.
If the app is started via the launcher (including in an emulator
that's connected to Android Studio), the app is not force-stopped, and
the alarm and job both run as expected.
So it won't cause additional issues except during development phase. For further information, please check out the Android issue tracker linked in the question.
I know that my problem is not exact with this one but I also encountered this issue in android 11 in google map when I click this one time permission. I noticed that if you left your app for 1 minute in background and go back, the app process was killed.
I have 2 SupportMapFragment inside the viewpager and connected in TabLayout and every time this happen, view will be recreated, however the fragment that was in the current position of the viewpager is not recreated properly.
For those people who encountered this as well, you have to change your flow and use only 1 SupportMapFragment instead of two. In that way, your map fragment will recreated properly. I just handle the map state and marker depending on the tab current position
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
I have an open source gps tracking application that has been around for many years. Recently, I have been getting complaints that in android nougat, instead of getting updates once a minute, people are getting updates from the phone once every five minutes when the phone is unplugged.
There is something going on with the power saver mode even though we tried turning it off.
Is there a way to force a phone to get gps updates at a specified time when unplugged?
Here is the code if anyone wants to see it but I don't think it's a problem with the code. It has been very stable for years.
https://github.com/nickfox/GpsTracker/blob/master/phoneClients/android/app/src/main/java/com/websmithing/gpstracker/LocationService.java
thanks.
One change in Android 7/Nougat was that the Doze is now "more aggressive". In Android 6/Marshmallow the doze mode kicked in when the screen was off, the device was running on battery and it was stationary.
(This is documented in Optimizing for Doze and App Standby)
Now in Android 7 the conditions are just screen off and running on battery.
(This is documented in Android 7.0 Behavior Changes)
Apps can be white-listed to be exempt of the restrictions if they break the core functionalility of it. In your case they do as the GPS tracker needs to record coordinates in real time.
There's a list of Acceptable Use Cases for Whitelisting
This includes:
Task automation app | App's core function is scheduling automated
actions, such as for instant messaging, voice calling, new photo
management, or location actions.
Users can white list an app manually on their own in the device settings or whitelisting can be requested by the app and approved or rejected by the user.
This is covered in Support for Other Use Cases
Quoting:
An app can fire the ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS intent
to take the user directly to the Battery Optimization, where they can
add the app.
An app holding the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission can
trigger a system dialog to let the user add the app to the whitelist
directly, without going to settings. The app fires a
ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS Intent to trigger the
dialog.
The user can manually remove apps from the whitelist as needed.
The last point is important of course, but luckily the whitelisting status can be checked programmatically:
An app can check whether it is currently on the exemption whitelist by
calling isIgnoringBatteryOptimizations().
So, dealing with the Doze mode is one thing to study at least.
Another issue is keeping the Service running in general. But the Service getting killed by the system might result in more random time intervals. There are of course the classic things like using START_STICKY or running as a foreground service.
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.