13

So I've got a BroadcastReceiver and the AlarmManager.

Let's say I create the Pending Intents like so:

Intent i;
i = new Intent(context, MyReceiver.class);
i.setAction(MyReceiver.ACTION_1);
i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
pendingIntent1 = PendingIntent.getBroadcast(context, 1, i, PendingIntent.FLAG_UPDATE_CURRENT);

i = new Intent(context, MyReceiver.class);
i.setAction(MyReceiver.ACTION_2);
i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
pendingIntent2 = PendingIntent.getBroadcast(context, 2, i, PendingIntent.FLAG_UPDATE_CURRENT);

And schedule the alarms like so:

now = SystemClock.elapsedRealtime();
long time1 = now + 10 * 1000;
long time2 = time1 + 60 * 1000;

am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, time1, pendingIntent1);
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, time2, pendingIntent2);

I am now experiencing that my broadcast receiver gets the broadcast for ACTION_1 quite reliably, while ACTION_2 is often not being delivered. So onReceive is rarely or never executed with an intent holding the action ACTION_2. How comes that? I thought, *_WAKEUP makes sure that broadcasts are being delivered anyway?

[Update 09/15/2015] - For testing purposes I'm trying to print out a Log message in my onReceive method. Still not working. - I've tried using setExact on AlarmManager now. Still not working. - I've even tried using WakefulBroadcastReceiver. Still not working. - I've found out, however, that the device reliably wakes up when in battery charged state. What could cause this problem? I've read everywhere that broadcast receivers are guaranteed to be executed if triggered by the alarm manager via a pending intent (and not doing too much stuff in onReceive). Do I maybe have some aggressive energy saving policy on my phone which I can't really work against (without acquiring a long wake lock, see comments)?

[Update 09/19/2015] I have just tested some alarm clock app (https://play.google.com/store/apps/details?id=com.alarmclock.xtreme.free) on Google Play and it does not reliably wake up the phone, too. I guess, it's really a bug and not my fault. I'll stick to the wake lock solution then, I guess.

flxapps
  • 1,066
  • 1
  • 11
  • 24
  • what's the value of `showAt`? – Sam Dozor Aug 12 '15 at 17:26
  • Oups sorry, fixed. It was meant to be `time1`. The app is basically about showing a dialog (in a transparent activity) after some time the screen went off (here 10 secs) and hiding it again, if the screen was off for too long (here 10+60=70 secs). – flxapps Aug 12 '15 at 17:43
  • I've now solved my problem by acquiring a wake lock like so: `wakeLock.acquire(time2 - now + 5000);` (keeping the phone awake for - in the upper example - 70 secs plus 5 secs as a buffer) - However, I feel like this is a rather hacky solution. What do you think? Is it legitimate or too dirty, probably causing problems? – flxapps Aug 13 '15 at 11:01
  • Which phone are you testing on? Sony models have an aggressive power saving mode enabled by default which can stop services from waking up. – pmont Aug 15 '15 at 13:58
  • Yeup, it's a Sony Xperia Z1 Compact... I guess, the method with manually acquiring a wake lock with timeout is - as dirty as it is - the most reliable solution then? – flxapps Aug 15 '15 at 14:26

4 Answers4

6

I encountered the same problem, the solution i found is to create the intent only by action string, and register that receiver action in manifest. try changing the intent to something like this:

i = new Intent("com.app.ACTION_ONE");

then in your manifest file add to your receiver the following:

<intent-filter>
    <action android:name="com.app.ACTION_ONE" />
</intent-filter>

My guess is if you dont register at least 1 action to the recevier he just dies when the application procces is terminated.

Hope it works, good luck.

Itay Sued
  • 134
  • 3
  • Still not working. :/ Another side note: If I schedule the first broadcast for e.g. 3 seconds after turning the screen off, it often gets executed after turning on the screen again (after I've already waited like 10 seconds, however). – flxapps Aug 18 '15 at 20:01
2

Did you registered the BroadcastReceiver (or from the Manifest)?

 registerReceiver(new MyReceiver(), new IntentFilter(MyReceiver.class.getName()));

I used last time almost the same methods, but with AlarmManager.RTC_WAKEUP - if you don't want to wake the device from deep sleep, use AlarmManager.RTC

long time = System.currentTimeMillis() + 10*1000;
alarmMgr.set(AlarmManager.RTC_WAKEUP, time, alarmIntent);

The alarmIntent like:

alarmIntent = PendingIntent.getBroadcast(this, 0, new Intent(MyReceiver.class.getName()), PendingIntent.FLAG_CANCEL_CURRENT);
jkyree
  • 284
  • 2
  • 5
1

There is few things it might be usefull to note:

  1. You are using AlarmManager.set() method witch doesnt not guarantee time of the delivery, if you want to have alarm to be triggered at exact time use AlarmManager.setExact()

  2. You broadcast intent doesn't make sense for me. It is implicit, but broadcasts are not supposed to be. Such intent could be reson for strange android behavior. If you want to have implicit intent send it directly to service handling it. In receiver case I would recommend to use:

    Intent intent = new Intent(Contants.Action1);
    
  3. If your receiver is defined in manifest intents will be delivered even if all activities of your application are dead, if receiver registered dynamicly it can receive intents only while thread on whitch it was crated is alive.

  4. Different versions of Android trying to optimise alarms in slightly different way, but the goal is to trigger as many alarms as posible at the same time to achive better battery performance.

All this can be quite confusing. But intents are guaranteed to be delivered, if receiver is registered correctly.

Pavel Luzhetskiy
  • 789
  • 1
  • 8
  • 26
  • Hello, thanks for your reply. 1. I already changed my code using `setExact` for `Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT`. 2. I already changed my code using `new Intent(MyReceiver.ACTION_1);`. 3. My receiver is currently defined in manifest (I tried both though). ~~ Well, my experience, however, is at this point, that they're not guaranteed to be delivered correctly. I currently blame some strict energy saving policy from Sony for my problem, but I'm not sure though. Also check out my edit: I could reproduce the misbehaviour with an alarm app. – flxapps Aug 24 '15 at 16:11
0

Take a look at the settings for "Stamina Mode" on your sony devices. Try disabling Stamina mode or add your app to the whitelist of apps allowed when stamina mode is on.

Hope this helps.

FiMi
  • 261
  • 2
  • 7