3

I making the application where an activity launch is scheduled by AlarmManager. I would like to appear even if the screen is turned off and device is locked.

To achive this a set the Window flags

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
        | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);

And try to obtain lock for the screen

if(_lock == null)
{
    PowerManager pm = (PowerManager)App.getAppContext()
            .getSystemService(Context.POWER_SERVICE);

    _lock = pm.newWakeLock(
            PowerManager.FULL_WAKE_LOCK, "ScreenOn");
    _lock.acquire();
}

The _lock is PowerManager.WakeLock which is released in onPause

protected void onPause()
{
     if(_lock != null)
     {
          _lock.release();
     }
}

This code is executed in onCreate and onRestart. Everything works OK if the activity is not launched yet.

But if it was launched earlier the screen is not turned off.

  • onRestart is called first
  • onResume is then called
  • onPause is called immediately

So the activity is not launched. My question is how to turn on the screen in such situation. (I am using API 15).

Seagull
  • 3,319
  • 2
  • 31
  • 37
  • Post more of your code - all of it. What - where is _lock ? and you probably mean "the screen is not turned ***on***" – Mr_and_Mrs_D May 02 '13 at 23:12
  • So lock is a _private static member_ ? Are you SURE that _Everything works OK if the activity is not launched yet_ ? Even when the phone is alseep ? Try to increase the initial alarm time - I bet the activity won't work. When I say more code I mean also the Alarm and receiver for the alarm - you are using a receiver for the ararm no ? And _again, you probably mean "the screen is not turned **on**"_ – Mr_and_Mrs_D May 03 '13 at 12:06

3 Answers3

2

I came up with the solution. I created a new activity which will be trying to turn on the screen in the onCreate() and then wait until it is turned on. When the screen is ok it will launch the activity which should be displayed. To make the Android always create this activity

public class TurnOnScreen extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        if (pm.isScreenOn()) openActivity();
        else {
            registerReceiver(mScreenOnReceiver, new IntentFilter(
                    Intent.ACTION_SCREEN_ON));
            reciever_registered = true;
            turnScreenOn();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (reciever_registered) {
            unregisterReceiver(mScreenOnReceiver);
            reciever_registered = false;
        }
    }

    private boolean reciever_registered = false;
    private final BroadcastReceiver mScreenOnReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            openActivity();
        }
    };

    private void openActivity() {
        Intent intent = new Intent();
        // ....
        finish();
    }

    private void turnScreenOn() {
        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
                | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
    }
}

I am still looking for explanations why the screen is not turned on in onRestart.

Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
Seagull
  • 3,319
  • 2
  • 31
  • 37
  • You should move your code in `onResume` and unregister on `onPause` – Mr_and_Mrs_D May 02 '13 at 23:04
  • I mean the receiver register code - it should be in `onResume` and unregistration on pause : http://stackoverflow.com/questions/7887169/android-when-to-register-unregister-broadcast-receivers-created-in-an-activity – Mr_and_Mrs_D May 03 '13 at 12:02
1

Have you heard of "The Lighted Green Room"? Check out the code below, it may be what you're looking for.

http://code.google.com/p/ch-bfh-fbi-mobicomp-2011/source/browse/ch_simplix_android_repetitive_service/src/com/androidbook/longrun/LightedGreenRoom.java?spec=svn38&r=37

1

Just use your code :

final Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

in onCreate() only and remove all those other Activity-Cycle methods if they are not doing anything else then this.

I don't think you need any more code to use to perform it.

Harpreet
  • 2,990
  • 3
  • 38
  • 52
  • It works perfect only first time. But when I put this activity to background the next time it won't do anything. – Seagull May 03 '13 at 07:59