AlarmManager Android 4.4.2 bug - android

In my app I have a service and I use AlarmManager in this way:
AlarmManager am =(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, getIntent(), PendingIntent.FLAG_UPDATE_CURRENT);
long mills = SystemClock.elapsedRealtime();
mills += time;
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mills, pi);
And here is the receiver for my intent of the am:
if (intent.getAction().equals(Timer3GOn.intentExtra)) {
//some code
}
Here is how my app works:
when screen goes on (i receive Intent.ACTION_USER_PRESENT ) i set an AlarmManager that after a certain amount of time sends my intent Timer3GOn.intentExtra that is received by my class.
All this works fine except in Android 4.4.2 (haven't tested in 4.4.1 yet, but in 4.4 it works well). Only in android 4.4.2 if I delete my app from the "recent app list" of the device, the am is set properly but the intent is never received by my app; plus all the code in the service remains like stuck. So my app stops working but service remains in the RAM.
The problem doesn't start when I delete my app from recent app list, but only after I do that and the AlarmManager is set. How to resolve the problem?
P.S. in my app i have a CountDownTimer in the same class with the same context and it works well!
P.P.S. I've noticed that whatsapp has the same problem, if you delete it from recent apps, all the incoming messages don't being delivered until i open the program. It's just me or this happens to all 4.4.2 android versions?

Starting android 4.4 you have to use setExact() in order to execute alarms in accurate time.
Otherwise it'z the OS decision when to execute your alarm.

Related

Is there a device-agnostic way to handle simple recurring push notifications in Android?

Push notifications are still working great on all my devices running anything under 8.0, but anything 8.0+ is a nightmare.
Let's say I want a simple daily notification to pop up. It goes off once a day at a certain time, even if the application is closed. Exact timing isn't relevant:
AlarmManager am =(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, alarmnotify.class);
PendingIntent pi = PendingIntent.getBroadcast(context, ALARM_ID, i, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), AlarmManager.INTERVAL_DAY, pi);
On many devices supporting Doze this doesn't work and I have to use setAndAllowWhileIdle() or setExactAndAllowWhileIdle() and refresh the alarm when it fires (annoying). But many more devices, this doesn't work either.
If the device is stock Android I can request an "ignore battery optimization privilege", but this isn't working for almost any of my testing devices because of some silly OEM battery manager that runs on top of the stock battery manager. Even Samsung has one of these now. And plus, Google does not recommend this approach, and it can get your app de-listed if they feel you don't need it.
Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
Some devices are working if I use AlarmManager.setAlarmClock(), but this is silly, my app is not an alarm clock, I just want to display a notification.
I considered moving to FCM, but it's ridiculous to build client-server infrastructure over a simple once-daily alarm. Plus, that brings in numerous other considerations. The simplest: what if the user is offline?
I'm noticing this a major issue even in enterprise grade applications with millions of downloads. I have the same applications installed on a 7.0 and 9.0 device. The 7.0 device gets notifications and the 9.0 does not. What gives?
Is there a universal approach to handling alarms post-8.0, much like the first snippet was universal to all devices prior to 8.0?

Repeating alarm canceled after a few days

I'm having a problem with a very simple app that shows a notification once a day. To do that I am simply doing this:
PendingIntent pendingIntent = [pending Intent to a Service]
alarmManager.setInexactRepeating(AlarmManager.RTC, DateTimeUtil.getTomorrowAtEight(), AlarmManager.INTERVAL_DAY, pendingIntent);
This works for a few days and then stops working, on a device running Android 6.0 (LG G4).
adb -d shell dumpsys alarm shows that indeed my alarm is not in the list of "Pending alarm batches".
I don't have this problem on a device running Android 5.1 (Samsung S4).
I'm guessing this has something to do with Doze Mode or App Stand by, but as far as I can tell (correct me if I'm wrong), alarms can be delayed, which is fine for my use case, but are not supposed to be cancelled!
Ideas?

AlarmManager not working on Samsung devices in Lollipop

I develop an app that uses AlarmManager to set a bunch alarms (usually around 50) that need to be fired at a certain time during the year.
This is the code I'm using since 4.4 kitkat changed the AlarmManager.
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
long setDate = fireDate.getTime(); // it's a calendar date defined above
Intent intent = new Intent(LOCAL_DISPLAY_MESSAGE_ACTION);
PendingIntent pending = PendingIntent.getBroadcast(ctx,
id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.RELEASE.startsWith("6")) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, setDate, pending);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
am.setExact(AlarmManager.RTC_WAKEUP, setDate, pending);
} else {
am.set(AlarmManager.RTC_WAKEUP, setDate, pending);
}
Apart from the code above I'm using a broadcast receiver properly defined in the manifest.
public class LocalReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
PushWakeLocker.acquire(context);
// do some stuff
PushWakeLocker.release();
}
}
More info thay might help.
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="19" />
Since a few months ago I've been getting bad reviews only from Samsung devices (5.0 /5.1 android version) that don't get their local notifications at all. I mean, it's not firing the alarm, it seems that the device skips it or does not wake up.
In the tests, mainly with a Samsung S4 with 5.0.1, I always get the alarms on time, so this is driving me crazy.
FYI this code has always worked pretty fine.
I researched a lot about this but unfortunately I got no helpful information. It's not that they get the alarm with delay (as I've read in some threads), it's that they don't get it at all. So this is not about the known issue in lollipop and alarmmanager.
I appreciate your time and any suggestion is welcomed!
Your problem (or nightmare) is the Samsung Smart Manager. This app comes pre-installed with all Samsung phones since 2015 and is supposed to deactivate Apps that are unused.
"How does it know which apps are not used?" You may ask - simple:
Every app that has not been launched by the user for 3 days gets deactivated.
All remaining AlarmManager entries - of course - also get deleted. You can read about it on their "Developer Forums". Feel free to follow here or here until these threads get deleted by the staff. I have yet to see someone from Samsung respond to the topic.
The only way to "fix" this is to inform the Users of your app about the situation and show them how to whitelist your app in Smart Manager. We've had to setup a website with step-by-step instructions showing how to do this for our users.
You may think about setting up a background service, or calling AlarmManager every six hours or so - none of these hacks will work.
When devices are re-starterd it clears alarms so your on boot alarm has to set them up again.

AlarmManager stops working in Android 4.4.2 (using SetExact())

I'm setting in my code an alarm to go off in specific time.
The alarm mechanism works great on SDK < 19, but on 19 the alarms aren't fired.
Here is the code where I set the alarm :
public void SetAlarm(Context context, Long executionTime)
{
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReciever.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Only one alarm can live, so cancel previous.
am.cancel(pi);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
am.set(AlarmManager.RTC_WAKEUP, executionTime, pi);
} else {
setAlarmFromKitkat(am, executionTime, pi);
}
}
Since I'm setting the alarm using a Service I use GetApplicationContext() as the context.
The onReceive() code :
#Override
public void onReceive(Context context, Intent intent) {
for (SchedulerListener listener : listeners) {
listener.fetchAndRebuildNotification();
}
}
Here is the declaration of the BroadcastReceiver :
<receiver
android:name="com.SagiL.myAppName.BroadCastReceivers.AlarmReciever" />
The callback runs a method in a service (which is still alive when the alarm supposed to fire, notice it doesn't starts one).
This whole thing is a library which is used in my app, and there I declare the receiver the same way.
Sometimes the alarm do fires once, but mostly it doesn't fire at all.
Has anyone experienced such a thing ?
I can't believe it's common to SDK 19 since a lot of apps are using AlarmManager and they will break too if it is common.
I had a similar problem with my application. I found out that using 0 ad the id in getBroadcast(...); didn't work very well and caused numerous problems.
Try changing the id from 0 to the alarm's real id.
From:
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
To:
PendingIntent pi = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
It´s a late answer, but may help. In Android KitKat 4.4.xx a battery manager is integrated (my device: Huawei Ascend Mate 7). There is an option to kill background process and services of an app in the battery manager. Don´t know if the options are named similar to the german options, so just try:
go to settings
select save energy
select detailed power consumption
select Screen off: perform further
enable Your app
It sounds simple, but that exactly was my problem. On Samsung Galaxy S3 with ICS everything worked like a charm. But bought a new device, the huawei, with Android 4.4.2, and suddenly my apps alarms didn´t work. After checking the system, I detected that option, enabled my app and now everything is fine. Not everything is a programming answer :) .
UPDATE
Since this answer was made, a lot happened in Android. For everybody with a similar problem: Since update to Marshmallow, there are two problems: first one is like described above, the second one is the doze mode:
Optimitzing Doze
Some devices, like my Huawei Ascend Mate 7, using both energy saving methods. So it isn´t enough to do what is described above. Also, you have to whitelist the app and use the new alarmManager methods setAllowWhileIdle(), setExactAndAllowWhileIdle() and setAlarmClock() .
Possible Problems
By whitelisting your app, you have to tell this the user. You can do it with a simple information at starting your app, for example a AlertDialog and/or you can use ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS intent to start the whitelisting screen. But be aware of this Action, because like reported from some developers, Google can suspend an app from playstore that is calling this action.
setAlarmClockshould also work, but if you do this, an alarm clock icon is on the top.
Testing
I have made some tests with that new documented doze mode and found out, that it usually works. But without whitelisting, the app falling to standby and ´alarmManager´ does not fire anymore, also not with that new methods. I tested it over night and the app is send to standby within about one hour. At a normal situation at day, where the user is active and often moves his device, it works without whitelisting.

Android alarm manager not working on Samsung Galaxy phone

I have created an app which polls a server to fetch SMS that have to be sent to our users. For the polling functionality i have used the alarm manager to fire every 5 min to poll server
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent pintent = new Intent(this, SMSSender.class);
PendingIntent pIntent = PendingIntent.getBroadcast(this,0,pintent, 0);
if(checkbox.isChecked()) {
long interval = 60*Integer.valueOf(PreferenceManager.getDefaultSharedPreferences(this).getString("pref_poll_interval", "5000"));//5mins;//5mins
long firstPoll = SystemClock.elapsedRealtime() + 60*Integer.valueOf(PreferenceManager.getDefaultSharedPreferences(this).getString("pref_poll_interval", "5000"));
alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstPoll, interval, pIntent);
Log.d("SMS_GATEWAY", "alarm manager turned on "+interval);
}else {
alarm.cancel(pIntent);
Log.d("SMS_GATEWAY", "alarm manager turned off");
}
I have tested the application on the emulator against the 2.2 build and everything works fine, now test the final out of SMS going out i have installed the app on a Samsung Galaxy S phone.
Once the app is installed and the preference to poll server is selected, nothing really happens.
What could be the problem
Consider using the BuzzBox SDK library for your problem.
http://hub.buzzbox.com/android-sdk/
You can schedule a task using a cron string:
SchedulerManager.getInstance()
.saveTask(this, "*/5 8-19 * * 1,2,3,4,5", YourTask.class);
I have a Galaxy S and I'm using the BuzzBox SDK in a few of my apps.
You can check the scheduler log integrated in the SDK to verify that your Task is running properly.
AlarmManager is not working correctly on Samsung phones in deep sleep :( BuzzBox SDK use AlarmManager so it has the same problem (I tested on Galaxy 5500).
For example http://www.netzpurist.de/2010/11/samsung-gt-i5500-with-android-2-1-update1-alarmmanager-not-suitable/

Categories

Resources