I have an app which uses the AlarmManager
to regularly wake up the phone at full hour and send a message to an Android Wear watch which than makes a short vibration. I have two users with a Samsung Galaxy S6 with stock Android 5.1.1 and the Sony SW 3 with 5.1.1 who experience a weird bug. At the very first full hour the vibration is at the exact time but all other vibrations are 3 minutes delayed. Sometimes even the first full hour vibration is delayed.
Here is some code:
final Calendar time = Calendar.getInstance();
time.set(Calendar.SECOND, 0);
time.set(Calendar.MILLISECOND, 0);
time.set(Calendar.MINUTE, 0);
time.set(Calendar.HOUR_OF_DAY, time.get(Calendar.HOUR_OF_DAY) + 1);
final Intent hourlyChimeIntent = new Intent(context, HourlyChimeReceiver.class);
hourlyChimeIntent.setAction(key);
final AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
final PendingIntent pi = PendingIntent.getBroadcast(context, 0, hourlyChimeIntent, PendingIntent.FLAG_CANCEL_CURRENT);
am.setExact(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pi);
I acquire a WakeLock
in the receiver and then send a message to the Wear watch in a thread. No vibration is missed, they are just 3 minutes late.
I have no other reports about this issue and all my testing devices are working good. I have no Samsung device though.
Any ideas what could cause the 3 minutes delay? Does Samsung ignore setExact
and makes my alarm an inexact? How to force exact alarms on Samsungs?
EDIT:
Here is the Android Wear specific code. In the receiver's onReceive
method I do this:
final PowerManager mgr = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
final PowerManager.WakeLock lock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID);
lock.acquire(7L * 1000L);
final GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context).addApi(Wearable.API).build();
new Thread(new Runnable() {
@Override
public void run() {
googleApiClient.blockingConnect();
long pattern[];
pattern = new long[] {0L, 500L};
final NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await(2000L, TimeUnit.MILLISECONDS);
if (nodes != null) {
for (final Node node : nodes.getNodes()) {
// just send and forget
Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), "/hourly_chime", Utils.Vibrator.serializeVibratePattern(pattern).getBytes()).await();
}
}
}
}).start();
On Android, you can tweak your phone's snooze duration to have an alarm sound as often as every 30 minutes. To do this, go to the Clock app and set up a regular alarm by tapping the big plus button at the bottom and adding your desired parameters.
Step 1: Launch the Settings and click on Apps and Notifications. Step 2: Now, click on the Clock app and then further tap on Storage. Step 3: Finally, tap on Clear Cache and Clear Storage, one by one. A simple restart will conclude the steps and resolve the Android alarm no sound issue.
To clear the cache and data for the Clock app, tap on Settings > Apps > Clock. Alternatively, long-pressing the Clock app on your phone screen and selecting App Info also does the trick. Whichever way you decide, your next move is to select Storage > Clear Cache, and this should ensure your Android alarm works again.
The issue seems to occur only on Samsung devices (e.g. Galaxy Grand, S4, S5, S6, Note 3, Note 4) with Lollipop (5.0, 5.1, 5.1.1). It seems that alarms are scheduled inexact when device is on battery with screen off. If device is charging or has screen on during scheduling alarm the issue will not occur.
You can verify if next alarm will be inexact with:
adb shell dumpsys alarm
I didn't find perfect solution for this problem - only workarounds where each has some drawbacks:
setAlarmClock
instead setExact
(see this answer). This works very well (not on all devices), but the issue with this solution is that the alarm will affect the system by showing alarm icon in status bar (if someone doesn't have alarm clock set already) and displaying next alarm scheduled time on alarm widgets etc. Unfortunately while this works on Galaxy Grand with 5.1.1 it doesn't on Galaxy S4 with 5.0.1.WakefulBroadcastReceiver
, but it doesn't work in my case.BTW This issue drives me crazy :)
Edit: Looks like this issue does not occur when there is keyword "alarm" or "alert" in the app package name (as pointed out by Mathieu H. in comments below).
I was also able to fix the issue manually by disabling App optimization in Battery settings (or in Smart Manager app). It seems it cannot be done programmatically, so you can try asking your users...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With