I'm relatively new to android programming but I'm told most applications have a receiver that will cut down on battery expensive activities when android fires ACTION_BATTERY_LOW.
Android developing page says:
public static final String ACTION_BATTERY_LOW
Added in API level 1
Broadcast Action: Indicates low battery condition on the device. This broadcast corresponds to the "Low battery warning" system dialog.
This is a protected intent that can only be sent by the system.
Constant Value: "android.intent.action.BATTERY_LOW"
I was wondering if there was a way to send this intent manually, at any desired battery level. I have a rooted device if that makes a difference.
No. It's not possible. Check this post. Look into the answer given by Mark(commonsware).
Sure there is a way to change the level - just download the terabytes of complete source code and spend a week or two building your own custom ROM, and trying to flash it without bricking your phone. It will only work on your device.
But no, you cannot change it in an app, nor on anyone else's device, and you cannot fire it yourself - did you read the part you quoted, "This is a protected intent that can only be sent by the system."?
Related
Can anyone suggest an Action (intent) which an Android 8.1.0 system should broadcast to registered receivers when changing Notification Channel setting values? Some years back, we did the work to update our notifications system into the required channels and groups and specified a broadcast receiver for the settings changes in the manifest (later on we had to fix that when they took away implicit intents, so now it registers in code too - but that's fixed already). Our receiver sets internal "display" settings which correspond to the notification-channel setting chosen by the user into our sharedpreferences file. That's what controls the display of the content when a user actually opens the app.
I have notes that say we tested this on Android 8, but the actions/intents we registered for don't exist until API28. I'm unclear on how this ever passed on the 8.1 devices, but maybe we were focused on the notifications only and didn't notice the display. So right now, we're stuck with notification settings changes working, but if a user happens to go to the app for something else, they still see messages they expected to be hidden.
Android 9+ notification settings changes work fine all the way through because the broadcast receiver registers for the new-in-API-28 NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED, ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED and ACTION_APP_BLOCK_STATE_CHANGED and these get delivered fine when a user changes settings, since I can see the receiver runs and sets the preferences as we want.
Just to debug this, I registered our BroadcastListener for a few extra intents (basically everything that looked like it might have something to do with notifications!) - like this:
// Register to receive a broadcast whenever notification settings are changed (before API 26 this was done by specifying in AndroidManifest only,):
notificationSettingsReceiver = new NotificationSettingsBroadcastReceiver();
IntentFilter filter = new IntentFilter(NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED);
filter.addAction(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED);
filter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
filter.addAction(NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED);
filter.addAction(NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED);
filter.addAction(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED);
this.registerReceiver(notificationSettingsReceiver,filter);
This proved that the code in my BroadcastReceiver is working fine in 8.1.0 if it would only get called; I can force it to run by changing a few Notification settings (disabling them, or changing the sounds, etc) and then switching the phone into do-not-disturb mode. The actual notification-settings-changes don't ever cause any intent to arrive at my receiver, but the DND change does, so this triggers the notification settings to get written into sharedpreferences (which is where our display code is expecting to find them).
Pre-android 8 notification settings still seem to work fine too and we write these changes into our sharedpreferences file directly. Something about compatibility must just handle this for us because it all still "just works" on API 23 devices.
If anyone could suggest a way for an API 27 device to listen for notification-channel settings changes, I would be most grateful! There has to be a way to to this in API 27, isn't there?
After a few days of looking around and trying things, I was unable to have the NotificationManager in API 27 send anything at all to our BroadcastReceiver.
I was able to come up with a solution, although at first it seemed a bit heavy-handed.
For Android O+ devices, I simply added the same "syncPreferences" block of code to our app's onCreate, onResume and onDestroy methods which calls the same function as our BroadcastReceiver (which works fine in API 28+) to write the values into our shared_prefs file at that time. I say "heavy-handed" since it does it every time, regardless of whether anything has changed, but it actually works very well. It's actually simpler than all the overhead of building a receiver and listening for notification changes... I could probably eliminate that whole process now!
As an amusing aside, as a trekker, I have to admit that I got quite a chuckle from whoever adds the android VERSION_CODES constants though! Check the comment I found while looking up API numbers-to-buildcode declarations:
/**
* Q.
* <p>
* <em>Why? Why, to give you a taste of your future, a preview of things
* to come. Con permiso, Capitan. The hall is rented, the orchestra
* engaged. It's now time to see if you can dance.</em>
*/
public static final int Q = 29;
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).
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 application performs data synchronization in background service which is critical task for application in order to work properly. now, application works fine & expected in some of devices having pure Android or near to pure Android ROM. e.g. Google Nexus, Android One & Motorola devices. but, some devices like Redmi having MIUI has inbuilt options for blocking application's background processes. which causes my application working not properly. So, I want to know "is there any way to find out my background processes are blocked? so that I can notify user to unblock it."
here's a somewhat related question
here's some screenshot related to this.
Any suggestions or help are welcome.
Thanks in advance
as i know, apps cannot get the info about whether or not in whitelist, but you can notify the user any more by :
Intent intent = new Intent(); intent.setAction("miui.intent.action.OP_AUTO_START"); intent.addCategory(Intent.CATEGORY_DEFAULT);
I am implementing SMSListener in my app and I have set it's possibly highest priority as android:priority="2147483647" so that I should get the call on new incoming sms.
In my second sample app I have set the same priority as above for SMSListener but when I get call for new incoming SMS I am using abortBroadcast();.
When I ran both these app and I found that 1 is getting the call before 2. Now I am seeking this behaviour will remain as it is or it is not constant and 2 can get call before 1.
I want to make sure that my app get's the call whenever sms comes even if there exists some other app which has the highest priority and it is aborting the sms.
I hope I have put my point and looking for some convincing answer.
Thanks for devoting your time to my problem.
The abortBroadcast only works when they get it first, usually based on installation order, but not always.) System level apps will execute, then Android will try to sort out non-system apps. If you look at the source code, the order of execution is based on priority level, but the calls to select the order of apps is not consistent for apps over 999 or for apps with the same priority level. It might be in order of installation, but system changes can result in other orders of execution (which I have seen many times with testing this).
Another thing, from what I understand, the priority for applications must be between -1000 and 1000, inclusive.
http://developer.android.com/reference/android/content/IntentFilter.html#setPriority%28int%29
http://developer.android.com/reference/android/content/IntentFilter.html#SYSTEM_HIGH_PRIORITY