1

I need to do something whenever an Android device (running Android 4.0 onwards) is locked or unlocked. The requisites are as follow:

  • If screen lock is set to "None", I do not consider the device to be locked when the power button is pressed and the screen goes off.
  • If screen lock is set to anything other than "None", I consider the device to be unlocked when the keyguard screen is not present.

I have implemented this piece of code which seems to be working for Android 5.0, and which takes into account the not-so-great behaviour of older Android versions when "None" is used. I have also checked other questions such as this one before posting this question.

private class KeyguardWatcher extends BroadcastReceiver {
        public KeyguardWatcher() {
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
            intentFilter.addAction(Intent.ACTION_SCREEN_ON);
            intentFilter.addAction(Intent.ACTION_USER_PRESENT);
            MyService.this.registerReceiver(this, intentFilter);
        }

        public void destroy() {
            MyService.this.unregisterReceiver(this);
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            // Old Android versions will not send the ACTION_USER_PRESENT intent if
            // 'None' is set as the screen lock setting under Security. Android 5.0
            // will not do this either if the screen is turned on using the power
            // button as soon as it is turned off. Therefore, some checking is needed
            // with the KeyguardManager.
            final String action = intent.getAction();
            if (action == null) {
                return;
            }

            if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                // If 'None' is set as the screen lock (ie. if keyguard is not
                // visible once the screen goes off), we do not consider the
                // device locked
                if (mKeyguardManager.inKeyguardRestrictedInputMode()) {
                    doStuffForDeviceLocked();
                }
            } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
                if (!mKeyguardManager.inKeyguardRestrictedInputMode()) {
                    // The screen has just been turned on and there is no
                    // keyguard.
                    doStuffForDeviceUnlocked();
                }
                // If keyguard is on, we are to expect ACTION_USER_PRESENT when
                // the device is unlocked.
            } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                doStuffForDeviceUnlocked();
            }
    }
}

This seems to be working for me in Android 5.0. I was wondering however if it is possible for this to be prone to race conditions when processing ACTION_SCREEN_OFF. Is it possible that something other than "None" is being used (for example "Swipe") and that by the time I am processing ACTION_SCREEN_OFF keyguard is not in restricted input mode but it will be soon afterwards? If that were the case, I would never consider the device locked but it might be.

Community
  • 1
  • 1
user2891462
  • 3,033
  • 2
  • 32
  • 60

0 Answers0