9

To build an exact and reliable Alarm in Android OS 6, aka Marshmallow, I am forced to use setAlarmClock method of AlarmManager. The problem is this method displays an alarm icon in top status bar. Since my app needs an alarm to refresh some data at midnight, everyday, it will display alarm icon forever, which is not pleasant.

AVEbrahimi
  • 17,993
  • 23
  • 107
  • 210
  • Did u get a ans for this? – user93796 Dec 15 '18 at 19:30
  • Since you're using Marshmallow, have your tried removing the icon from System UI Tuner? How to enable it here https://www.androidexplained.com/enable-system-ui-tune. Also might be helpful this SO answer https://stackoverflow.com/a/2839911/5466997 – josemigallas Dec 19 '18 at 12:13
  • Could you post a copy of how you are using the alarmmanager? It should not behave this way. –  Dec 21 '18 at 22:42

3 Answers3

4

Unfortunately, this is completely intentional design by the Android developers in order to save battery. This motive becomes clear when you look through the documentation for AlarmManager methods. For example, this quote is taken from the documentation on AlarmManager#setExactAndAllowWhileIdle:

These alarms can significantly impact the power use of the device when idle (and thus cause significant battery blame to the app scheduling them), so they should be used with care. To reduce abuse, there are restrictions on how frequently these alarms will go off for a particular application. Under normal system operation, it will not dispatch these alarms more than about every minute (at which point every such pending alarm is dispatched); when in low-power idle modes this duration may be significantly longer, such as 15 minutes. [emphasis mine]

Therefore, Google wants you to signal the user somehow that your app might be draining power by putting the little alarm clock in the status bar if you really really really need to have exact alarms. Quote from the documentation on AlarmManager#setAlarmClock:

As such, these types of alarms can be extremely expensive on battery use and should only be used for their intended purpose.

Thus, you're left with these two options:

  1. Use AlarmManager#setExactAndAllowWhileIdle and accept delays up to 15 minutes
  2. Use AlarmManager#setAlarmClock and accept the alarm clock
techfly
  • 1,826
  • 3
  • 25
  • 31
2

You need to use setExactAndAllowWhileIdle(). If your app is not ignoring optimizations, you have 10 seconds to achieve your goal. If you need more time, a partial wakelock and/or internet access, you need to add the permission to request to the users to ignore optimizations.

greywolf82
  • 21,813
  • 18
  • 54
  • 108
-1

If I understood you correctly you want to use the AlarmManager to schedule a task at midnight without displaying the UI clock. You can use AlarmManager#set this will not display the clock. e.g.

  alarm.set(
      AlarmManager.RTC_WAKEUP,
      midnightInMillis,
      PendingIntent.getService(getApplicationContext(), 11, intent, PendingIntent.FLAG_UPDATE_CURRENT)
  );
Murat Karagöz
  • 35,401
  • 16
  • 78
  • 107
  • 1
    From the link you posted: `Note: Beginning in API 19, the trigger time passed to this method is treated as inexact: the alarm will not be delivered before this time, but may be deferred and delivered some time later.`, which, according to OP's comment on another answer, is not what OP is looking for. – techfly Dec 22 '18 at 14:48