8

I want to turn on the display, unlock the phone and bring my app to the front, when the alarm I've set activates.

public class CountDownAlarm extends BroadcastReceiver {

    public CountDownAlarm(){ }

    public CountDownAlarm(Context context, int timeoutInSeconds){
        AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(context, CountDownAlarm.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        Calendar time = Calendar.getInstance();
        time.setTimeInMillis(System.currentTimeMillis());
        time.add(Calendar.SECOND, timeoutInSeconds);
        alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 
        WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP, "TRAININGCOUNTDOWN"); 
        wl.acquire(); 
        Intent i = new Intent(context, MyActivity.class); 
        i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); 
        context.startActivity(i); 
        wl.release(); 
    }
}

The vibrator from my CountDownTimer is activated, but the display doesn't turn on...

public class MyActivity extends Activity implements OnClickListener {

    @Override
    public void onClick(View arg0) {
        timer = new CountDownTimer(countDown*1000, 1000) {
            public void onTick(long millisUntilFinished) {
                activeBtn.setText(String.valueOf(millisUntilFinished / 60000) + ":" + 
                        String.format("%02d", (millisUntilFinished % 60000) / 1000));
            }

            public void onFinish() {
                activeBtn.setText("0:00");
                Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                v.vibrate(1000);
                ringtone = RingtoneManager.getRingtone(getApplicationContext(),
                        RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
                if (ringtone != null) {
                    ringtone.play();
                }
                new AlertDialog.Builder(MyActivity.this)
                .setMessage("Time's up!")
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface arg0, int arg1) {
                    }
                }).show();
            }
        }.start();
        new CountDownAlarm(this, countDown);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

On a side note, I want to play the "Positive" alarm sound. How do I do this?

thomas.fogh
  • 369
  • 1
  • 4
  • 17

4 Answers4

11

You should acquire wake lock with PowerManager.ACQUIRE_CAUSES_WAKEUP and PowerManager.FULL_WAKE_LOCK.

WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TRAININGCOUNTDOWN"); 

Bear also in mind that if you release wake lock right after startActivity() is called, the activity might not start because it is asynchronous call. I suggest to use WakefulServiceIntent or PowerManager.WakeLock.acquire(long timeout)

bart
  • 2,378
  • 2
  • 19
  • 21
  • Thanks! Now the display turns on, but how do I unlock the screen? – thomas.fogh Dec 20 '11 at 09:07
  • you can try to dismiss key lock http://stackoverflow.com/questions/4352548/how-to-unlock-the-screen-when-broadcastreceiver-is-called – bart Dec 20 '11 at 09:28
  • @bart, can you please explain how to go down the PowerManager.WakeLock.acquire(long timeout) route. Still a little confused. – MobileMon Mar 06 '13 at 14:29
  • 1
    Hi @bart, I want to show my activity view, over lock screen, I have got till display turns on from backgroundReciever when calling my activity... but its only appear if screen is unlocked.... I dont want to unlock the screen at all,,, but want to have an action from user like incoming call which viber also does.... – Abdul Wahab Jun 19 '14 at 18:55
  • PowerManager.FULL_WAKE_LOCK is deprecated, consider using WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON instead – hiddeneyes02 Jan 20 '18 at 21:02
7

In the DescClock it is done in the following way:

    final Window win = getWindow();
    win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
            | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
    // Turn on the screen unless we are being launched from the AlarmAlert
    // subclass.
    if (!getIntent().getBooleanExtra(SCREEN_OFF, false)) {
        win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
    }
Yury
  • 20,618
  • 7
  • 58
  • 86
  • This worked great! FLAG_KEEP_SCREEN_ON will keep the screen on and bright until the current window is visible to user. Call finish(); programmatically or allow user to finish it manually to get back to normal mode. Hope this will help to someone. more info https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_KEEP_SCREEN_ON – mili Jul 02 '17 at 11:14
4

Go to the Activity which you want to start in onReceive(). Paste this in onCreate() of that Activity

final Window win= getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
        WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | 
        WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
Junaid
  • 3,477
  • 1
  • 24
  • 24
1

As I can see onReceive is called with pendingIntent interval. On my device only the first call of onReceive was acquire the WakeLock. If I press the suspend button in the meantime the second call of wl.acquire() was not able to bring the system up. I need a release() first followed by a acquire()

wl.release();
wl.acquire();