My Android app is using Locationmanger service and when it is in background for a longtime, Android OS(7+ version) showing battery draining notification. I'm afraid will it provoke my customer to uninstall the application. So I just want to know is there anyway to prevent my app from showing this notification.
No, this is not possible. Those notifications are managed and sent out by the OS. If apps could disable those, everybody would do that and it would defeat the purpose.
The appearance of these notifications is a sign that you should try to decrease your app's battery usage. Perhaps you are holding a wake lock for a long time, or doing other battery inefficient things.
Sure you can
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
Intent intent = new Intent();
if (!pm.isIgnoringBatteryOptimizations(getPackageName())) {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
And use in the manifest:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
Then you have to do a lock PowerManager.PARTIAL_WAKE_LOCK
Before submitting this code live on the Play Store please read the conditions where you can use this code, because you can get your update rejected.
Related
I'm developing a tracking application that runs on Wear OS watches. I have some troubles when the watch goes to sleep. As soon as the watch goes to Deep Idle mode, all sensors acquisition stops. For that I'll need to whitelist the app using:
Intent intent = new Intent();
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
context.startActivity(intent);
This piece of code works well on mobile version but nothing happen on Wear OS version. I realized that Wear OS as no UI to set the battery optimization mode which should be the cause of the fact that nothing happens when trying to change the optimization.
I also used a wake lock to keep the CPU partially awake with:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MY-WAKELOCK");
But even with that the watch goes to deep sleep after about 15min ?
The last solution I see is to force the screen on or at least dimmed but it will drain the battery very fast.
Is there another solution to keep sensors working ? How can I whitelist my app on a Wear OS device as no UI seems available ? As anyone already encountered this issue?
I am having problems while doing work in the background in Android. I need to do a http request every 5s in a app of my own use (won't publish the app). I've seem that since version O Android had put limitations on the operational system and I'm doing what is recomended, that is, I'm creating a foreground service with a persistent notification to run this task. It works fine with the screen on, and even with the app closed, but after a while if the phone is locked it enters the Doze mode and lock my requests until I turn the screen on again. I've tried to mess with the power savings configurations of my phone with no luck.
Anyone have faced that issue?
Preferably without FCM (Firebase Cloud Messaging).
I am doing it on Xamarin.Forms, but if you have some example in Java that's ok, I'll get the idea.
You have to set REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission in your manifest.
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
Also you have to ask the user to put your app on the Battery_Optimization whitelist at runtime, like descriped here:
//check for ignoring battery optimization
PowerManager mPowerManager = (PowerManager) your_context.getSystemService(Context.POWER_SERVICE)
if (!mPowerManager.isIgnoringBatteryOptimization(your_context.getPackageName())) {
//ask for permission
Intent intent = new Intent(android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + your_context.getApplicationContext().getPackageName()));
startActivity(intent);
}
BUT your app is most likely not going to get approved by Google Play, when you try to release it to the PlayStore!
You should use FCM high-priority messages instead.
There aren't too many ways to do it on Android in nowadays.
Try to look at this Google tutorial and choose the right one.
Regarding the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission, your app should fit these conditions.
You'll find more details here android-doze-standby.
Honestly if you need do a task every X seconds use an alarm broadcast:
https://developer.android.com/reference/android/app/AlarmManager
You just implement a receiver and you can perform the task. If you need it in a specific class implement the receiver as in inner class running on a new thread re-registering the alarm every time.
I was having problem whit android media player because when I turn off the screen the system goes to sleep mode and stop it and I didnt want that because nobody wants to listen music and have the screen on (who do that?).
I noticed that the problem was on the battery optimizations because if the mobile was plug to power cable it keeps the music playin even if it goes to sleep mode.
I tried with a lot of posibilities to fix it (reading android documentation and trying every thing I was finding in the net) but what works was this code:
public void doPower() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String packageName = getActivity().getPackageName();
PowerManager pm = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
try {
//some device doesn't has activity to handle this intent
//so add try catch
Intent intent = new Intent();
intent.setAction(android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
} catch (Exception e) {
}
}
}
}
The problem here is: The app at the beginning shows an alert asking the user to disable the battery optimizations and I dont want that, because some users may thinks "this is a bad thing" or "why its asking this?" Because an app like spotify doesnt do it.
How can I avoid the alert message? If I cant, how can I add something else to the message? (something like this: "So you will able to listen the radio with the screen turn off")
Thanks in advance and best regards.
You can't avoid that dialog and asking to avoid battery optimizations is absolutely not needed.
What is needed is a wakelock, as described in the MediaPlayer Using wake locks documentation:
When designing applications that play media in the background, the device may go to sleep while your service is running. Because the Android system tries to conserve battery while the device is sleeping, the system tries to shut off any of the phone's features that are not necessary, including the CPU and the WiFi hardware. However, if your service is playing or streaming music, you want to prevent the system from interfering with your playback.
In order to ensure that your service continues to run under those conditions, you have to use "wake locks." A wake lock is a way to signal to the system that your application is using some feature that should stay available even if the phone is idle.
If you're using MediaPlayer, this only requires you use the setWakeMode() method:
mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
(Note the additional note on the documentation page about holding a wifi lock if you're streaming your media from the network.)
I am running service background to execute some tasks with some interval using AlaramManager (setExactAndAllowWhileIdle). If its connected the power charger its running. But if its unplugged device power after some i am loosing the network to my application.
Alaram is waking up the service even device is idle.But my app don't have network.
As per https://developer.android.com/training/monitoring-device-state/doze-standby.html# its restricting the network when phone is idle.I tested the same with applying phone idle ($ adb shell dumpsys battery unplug)
But is there any possible to get network access to my application even phone is idle mode.
Application is not of play store. Its really appropriated for suggestion.
I've used PowerManager.isDeviceIdleMode() in your running service to detect whether you're in Doze and if so just invoke setAlarmClock() method with 250 millis (for example) and random broadcast just to wake the device up, it'll completely wake up from doze and thus will get network access as usual. THe down side is that you lose the battery saving that comes with doze.. :D Please mark this as useful should it actually be usefull in your case.
Once your service (set up with setExactAndAllowWhileIdle()) you can go :
private boolean isDeviceInDozeMode() {
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
return pm.isDeviceIdleMode();
So now you know that you're in DOZE or not.
Then you can just set up AlarmClock and set it with setAlarmClock(AlarmClockInfo a, PendingIntent p)
And you're out of Doze with normal network access.
NOTE: Please remember that using setExactAndAllowWhileIdle doesn't mean that your alarm will go off at specified time, it will go off sooner than normal set() method, but not exact (as the method name would suggest). Generally my way isn't perfect in terms of scheduling, but it does exit DOZE programmatically once it's detected on device.
Let me know should you need more update.
I tried many options but none of them works, But finally this works to me.It might help for others.
we can always ask the user to let your app ignore battery optimization functionality using
PowerManager powerManager = (PowerManager)
getSystemService(Context.POWER_SERVICE);
Intent intent=new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
if (powerManager.isIgnoringBatteryOptimizations(getPackageName())) {
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
}
else {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
and in the manifest
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"></uses-permission>
But remember this might make your app not approved by Google Play
https://developer.android.com/training/monitoring-device-state/doze-standby.html#whitelisting-cases
Is it possible to use network access when doze is active? If my app is ignoring battery optimization doesn't go in standby but it's affected by doze anyway. Am I missing anything?
Network access is disabled in doze mode, regardless if your application is ignoring battery optimizations. The only way to wake-up your device from doze mode and to get network access is by sending a high priority Google Cloud Message to your application.
Edit: it is possible to let Android ignore battery optimization for your application, which effectively disables doze mode for your application. However, this requires using the method setExactAndAllowWhileIdle (maximum one wakeup each 15 minutes) and user interaction, which can be done like this:
Intent intent = new Intent();
String packageName = context.getPackageName();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
//battery optimizations toggle
if (pm.isIgnoringBatteryOptimizations(packageName))
//give the user the option to enable battery optimizations again
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
else {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
}
context.startActivity(intent);
Edit: it was suggested to add the permission android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS to the manifest. Besides that this is unnecessary for the suggested solution, it will result your app to be removed from the Play store.
According to the documentation, you can now have a foreground notification for your app which would defy the doze mode and your app should be able to access the network.