Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I think your problem is about using AlarmManager without proper use of WakeLocks, when device "sleeps" with screen turned-off, your receiver will not work properly.</p> <p>I guess your receiver got onReceive() from AlarmManager, which is most probably was started with <code>_WAKEUP</code> flag like this:</p> <pre><code>mAlarmManager.set(AlarmManager.RTC_WAKEUP, .......); </code></pre> <p>This _WAKEUP flag means that device will "turn-on" even if it will be in a sleep mode. However, as described by documentation here ( <a href="http://developer.android.com/reference/android/app/AlarmManager.html">http://developer.android.com/reference/android/app/AlarmManager.html</a> ) :</p> <blockquote> <p>The Alarm Manager holds a CPU wake lock as long as the alarm receiver's onReceive() method is executing. This guarantees that the phone will not sleep until you have finished handling the broadcast. Once onReceive() returns, the Alarm Manager releases this wake lock. This means that the phone will in some cases sleep as soon as your onReceive() method completes. If your alarm receiver called Context.startService(), it is possible that the phone will sleep before the requested service is launched. To prevent this, your BroadcastReceiver and Service will need to implement a separate wake lock policy to ensure that the phone continues running until the service becomes available.</p> </blockquote> <p>In your code that means that system goes back to sleep as soon as <code>onReceive()</code> ends, and as <code>startActivity(i)</code> doesn't work synchronously - that leads directly to the problem, mentioned above - it will be launched, but much, much later, just when user will turn the screen on.</p> <p>To solve it, I would recommend doing something like this:</p> <pre><code>//BroadcastReceiver @Override public void onReceive(Context context, Intent intent) { Logger.initialize(context); Logger.log("StartAlarm received"); Intent i = new Intent(context, AlarmOnScreen.class); i.putExtras(intent.getExtras()); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); AlarmOnScreen.acquireLock(context); //Before, system could sleep right after this line(not exactly, however) and activity actually would be started much later } //AlarmOnScreen (activity) private static WakeLock sWakeLock; public static void acquireLock(Context context) { PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); sWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "providersLock"); //Limit 10 sec, if something wrong will happen - we'll not drain the battery to much. sWakeLock.acquire(10000); //As we are acquiring and releasing only once - we don't need a counter. sWakeLock.setReferenceCounted(false); } private static void releaseLock(Context context) { try { sWakeLock.release(); } catch (Exception e) { //In case it's already auto-released e.printStackTrace(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.alarm_on_screen); Logger.log("AlarmOnScreen create"); //Time value of alarm is logged below (...) @Override protected void onResume() { releaseLock(this); } </code></pre> <p>This solution will work for the first time and will let you understand the problem deeper. To test - just start to use your alarms when screen is off and, possibly, cable is plugged-off, but I'm not sure if the last is really needed to get device into sleep mode.</p> <p>However, I would highly recommend to implement more elegant solution, suitable for your project, because current static-reference design is pretty poor, as it doesn't work perfectly in racing conditions, for example.</p> <p>Hope it helps and please let me know if any questions. Good luck.</p> <p><strong>UPD:</strong> I think I will also suggest to use not only PARTIAL_WAKE_LOCK, but FULL one. Like:</p> <pre><code>pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "providersLock"); </code></pre> <p>That will force the screen to be ON anyway, not depending on previous state and platform reaction on new activity creation.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload