Home » Android » android – How to tell if user is on lock screen from service

android – How to tell if user is on lock screen from service

Posted by: admin June 15, 2020 Leave a comment

Questions:

I have simple service that running in the background and I just want to know when the user is on the lock screen or not, that way I know when to start a process.

How to&Answers:

Check out a similar question asked here. Use KeyguardManager to check if the device is locked.

KeyguardManager kgMgr = 
    (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
boolean showing = kgMgr.inKeyguardRestrictedInputMode();

Answer:

1) You need to firstly register a BroadcastReceiver in your Service to listen when power button is pressed (turns screen on/off):

@Override public void onCreate() {
    super.onCreate();
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_SCREEN_OFF);
    filter.addAction(Intent.ACTION_SCREEN_ON);
    filter.addAction(Intent.ACTION_USER_PRESENT);
    registerReceiver(lockScreenReceiver, filter);
}

final BroadcastReceiver lockScreenReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if (Intent.ACTION_SCREEN_OFF.equals(action)) {
            Log.i(TAG, "ACTION_SCREEN_OFF");
            if (LockScreenHelper.isScreenUnlocked(getBaseContext())) {
                // what does this mean?
                Log.i(TAG, "screen is unlocked\n\n");
            } else {
                // this means device screen is off, and is locked
                Log.i(TAG, "screen is locked\n\n");        
            }

        } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
            Log.i(TAG, "ACTION_SCREEN_ON");
            if (LockScreenHelper.isScreenUnlocked(getBaseContext())) {
                // this means device screen is on, and is unlocked
                Log.i(TAG, "screen is unlocked\n\n");
            } else {
                // this means device screen is on, and is locked
                Log.i(TAG, "screen is locked\n\n");                   
            }
        }

        if (Intent.ACTION_USER_PRESENT.equals(action)) {
            Log.i(TAG, "screen user is present - on and unlocked");
        }
};

2) You can use this helper class to determine the screen states at any time:

/**
 * Decides what state the lock screen is in.
 * Logic adapted from chromium open source project:
 * https://github.com/crosswalk-project/chromium-crosswalk/blob/master/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
 */

public class LockScreenHelper {
  private static final String TAG = 
  LockScreenHelper.class.getCanonicalName();

  /**
   * Determine if the screen is on and the device is unlocked;
   * i.e. the user will see what is going on in the main activity.
   *
   * @param context Context
   * @return boolean
   */
  public static boolean isScreenUnlocked(Context context) {
    if (!isInteractive(context)) {
        Log.i(TAG, "device is NOT interactive");
        return false;
    } else {
        Log.i(TAG, "device is interactive");
    }

    if (!isDeviceProvisioned(context)) {
        Log.i(TAG, "device is not provisioned");
        return true;
    }

    Object keyguardService = context.getSystemService(Context.KEYGUARD_SERVICE);
    return !((KeyguardManager) keyguardService).inKeyguardRestrictedInputMode();
}

/**
 * @return Whether the screen of the device is interactive (screen may or may not be locked at the time).
 */
@SuppressWarnings("deprecation")
public static boolean isInteractive(Context context) {
    PowerManager manager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
        return manager.isInteractive();
    } else {
        return manager.isScreenOn();
    }
}

/**
 * @return Whether the device has been provisioned (0 = false, 1 = true).
 * On a multiuser device with a separate system user, the screen may be locked as soon as this
 * is set to true and further activities cannot be launched on the system user unless they are
 * marked to show over keyguard.
 */
private static boolean isDeviceProvisioned(Context context) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
        return true;
    }

    if (context == null) {
        return true;
    }

    if (context.getContentResolver() == null) {
        return true;
    }

    return Settings.Global.getInt(context.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
}

}