I started to test my app on Nexus 5x with Android O.
My targetSdkVersion is 22.
In the developer site I read about Background execution limits:
Where:
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.
Where is these settings (to enforce Android O limitations)?
Whats is the best practice for these limitation while I still want
to keep lower targetSdkVersion?
I found the setting under App info > Battery usage although not all apps have this setting.
When this setting is OFF I see following logs:
W/BroadcastQueue: Background execution not allowed: receiving Intent { act=android.intent.action.$ACTION dat=package:$APP_PACKAGE flg=0x4000010 (has extras) } to $APP_PACKAGE/$APP_RECEIVER
[UPDATE Sep 27, 2017]
As described here:
However, developers cannot use the Settings app to apply this limitation, unless their app happens to be in the battery blame list, which ideally doesn’t happen.
This article offers undocumented way to test background limitations via following command (ignore and allow values are possible)
adb shell appops set your.application.id.here RUN_IN_BACKGROUND ignore
Best practices are
If you plan on sticking with a lower targetSdkVersion for a while, and you are really really sure that your app will not show up on the battery blame list, and you want to ignore the background limitations for now, that’s your decision to make.
If, however, you plan on sticking with a lower targetSdkVersion and your app does tend to consume a fair bit of battery life, you should test your app with the adb shell appops command cited above. If nothing else, you can identify the likely symptoms that users will experience if they limit your background work through the Battery screen in Settings. That way, if you get customer service calls/emails/texts/Play Store comments/candygrams about those symptoms, you can better advise users about what to do.
See also Android Oreo Background Execution Limits
I cannot find it either.
Best practise would be to develop this for API 26, although you are not targeting it. So starting your service(s) as foreground service. After that, your service should start a foreground Notification in the onCreate.
From the docs:
The new Context.startForegroundService() method starts a foreground service. The system allows apps to call Context.startForegroundService() even while the app is in the background. However, the app must call that service's startForeground() method within five seconds after the service is created. (startForeground pushes the notification)
App info > Battery usage
IMO best practice is unfortunately to target API 26... This default behaviour is there only for legacy apps (sitting in play store but not being updated anymore).
Related
I can scan the Beacon in foreground using beaconManager.startScan(); so it is giving the beacons info available in the area.
same code I am using in service to scan the beacon and there also I am getting the beacon info.
But for scanning the beacon in background, I have to start the service.So is it the right practice to scan beacon using service.?
The topic of doing Bluetooth scanning in the background on Android is quite… interesting/complicated these days…
Using a background service isn't really a good option anymore. Starting with API 26 (Android 8.0), background services only continue running for a few more minutes once the user leaves the app.
(Arguably, it's not even a good option on older Androids. At Estimote, we found that some big-name Android smartphone manufacturers include their own power-management "optimizations" in their customized versions of Android, that tend to kill background services.)
You can use a foreground service, which has no limitations, but requires you to show a notification to inform the user that your app is still doing some work.
Finally, the good news is, in Android 8.0 there's a new API for Bluetooth scanning, where the BLE scan results get delivered via a PendingIntent rather than a standard callback. This will work even if the app got suspended/terminated in the meantime.
startScan(List<ScanFilter> f, ScanSettings s, PendingIntent i)
The bad news is of course, since this is API 26 (Android 8.0) and higher, you can't really rely on it much yet, as the Android 8 adoption is still very low. The future for background BLE scanning on Android looks bright, it's just not quite here yet.
--
Naturally, if you're using a ready-made scanning lib, it's best to consult with its authors about its background capabilities and how to use them.
The https://github.com/ufobeacons/Android-SDK lib seems (at a first glance at least) not to have any background support of its own, so you're probably best off just wrapping it in a foreground service.
Based on my testing, it appears that the NotificationListenerService(NLS) in my android app is not getting bound to the system on Android 8 (Oreo). I am targeting my app for SDK version 26 to make it compatible with the new OS.
Prior to Android N, the NLS service was bound to SystemUI forever (Ref: Google I/O 2016). Starting from Android N, two new methods were introduced in NLS service: requestRebind(ComponentName) and requestUnbind().
In Android Oreo, there are new Background Execution Limits that apply to services. However, it does not apply for certain services, such as a "Notification listener that another app binds to". This is my use case, as I am using an NLS service that is supposed to be bound to the SystemUI.
However, as I observed, this service is never getting bound to SystemUI. Additionally, even if I explicitly call requestRebind(ComponentName), the service is never getting bound and hence it is non-functional because this means I am unable to listen to notifications.
How do I fix this problem in Android Oreo?
Oh boy, this is silly! The issue was resolved by a reboot. I suppose Android was misbehaving on my phone and simply refused to work the right way. Rebooting the phone and trying again made the service work the way it is supposed to!
I'll leave this question up as a reminder to all that sometimes the simplest and most cliched fix (i.e. "Did you try turning it off and on again?") is the right answer!
Good grief!
I'm creating an app and its mainly depends on the battery notification which we receive when our battery level is low like 15%. However I know how to get the battery level, but I thought what if there is a way to use the existing notification based on which we can add features.
Please help.
There is a battery low broadcast that you can use, check out the documentation (scroll to "Monitor Significant Changes in Battery Level")
There is no "existing notification", insofar as the thousands of Android device models can do whatever they want when the battery is low. Not all will raise a Notification.
For those that do raise a Notification, there is nothing for you to "use":
A Notification is a Java object; your app cannot access Java objects from other processes
A Notification is configured by a variety of pieces of data; you have no idea what an individual device will use
You are certainly welcome to putter around the AOSP and see exactly what is used for low-battery indications in "stock" Android. Just bear in mind that what you find there is not going to be used on all Android devices and none of it will be part of the Android SDK (other than the generic Notification API).
My app main usage is overlay, the overlay is running from a service.
Android Security add the nice "Screen Overlay Detected"
I want to avoid "Screen Overlay Detected" when user tries to change permissions. so... I've add an AccessiblityService that detects:
if ( event.getPackageName().equals("com.google.android.packageinstaller") ){
stopService(myServiceIntent);
}
However, even now I see this message popping. (when my service is stopped...).
I saw Twilight does it without problem.
What am I missing?
p.s. - I've also tried building a signed apk but saw exact same behavior.
It seems I've been able to resolve this.
a) stopService isn't assured your service will be stopped.
as described here :
It will not be destroyed until all of these bindings are removed. See > the Service documentation for more details on a service's lifecycle.
b) I was able to kill my service by sending intent that called stopSelf().
However process killing/starting can be slow.
c) Best resolution: so it seems Android checks for view visibility. no need to kill services or do anything more complicated.
Current way I'm doing it:
- AccessibilityService (already used by my app) monitor "com.google.android.packageinstaller" though it can be refined to class: "com.android.packageinstaller.permission.ui.ManagePermissionsActivity"
Once detected in this class, we send Intent to "duck", and when we're out, we send another intent that we're back on.
The service handles those calls by:
[ourView].setVisibility(View.INVISIBLE); // when permission settings shown
[ourView].setVisibility(View.VISIBLE); // when normal flow
As long as Android 6.x is buggy on some devices where this "overlay alert" is displayed without any reason (on 2 to 5% of the devices according to my analytics data), the best solution is to avoid the whole permission process by defining the targetSdk to 22. Take care that you can't downgrade the target sdk for a new version or this will induce a INSTALL_FAILED_PERMISSION_DOWNGRADE error when the user updates requiring an unisntall/install of the app.
Some friends and I have been working in an app that requires to have a service running listening for voice commands. We have successfully implemented the listener. However, after we started having problems because the operating system killed the service after a while (I suppose to reclaim some resources). We (apparently) fixed this problem by making the service a foreground process (calling startForeground).
We have been testing the app in a range of devices and we found out that the app was still being killed by the OS in some devices. Having a close look at this issue we found out that the devices where the app is being killed have Google Search version greater or equal to 2.3... (for instance 2.4.10.626027) If we uninstall the updates and downgrade to version 2.2.10.573038 then it works like a charm.
By the way, I have mentioned Google Search here because when we start the voice listener, a package named com.google.android.googlequicksearchbox is started.
Does anyone have an idea of why this might be? or what main differences exist between the versions 2.2.10.573038 (and older) and those after? Of course the solution would be to downgrade the version but we would like it to be compatible with the newer versions too...