如何从服务中判断用户是否处于锁屏状态

9

我有一个简单的后台服务,我只想知道用户是否在锁屏状态下,这样我才知道何时启动进程。

3个回答

29

请查看这里提出的类似问题。使用KeyguardManager检查设备是否已锁定。

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

1
顺便提一下,这只有在用户实际设置了锁屏时才有效。如果没有设置锁屏并且用户通过按电源按钮“锁定”屏幕,则无法检测到该状态。 - Daren
权限或其他,我需要声明吗,@mopsled? - gumuruh
1
@Daren 如果没有设置锁屏怎么办...我怎么知道屏幕是否已经锁定???!!! - Ahmed Mostafa
如果没有设置锁屏,屏幕就无法被锁定(只能关闭)。 - IgorGanapolsky
@ahmedghanayem 使用kgMgr.isKeyguardLocked()来检查用户是否在锁屏界面上(无论是否设置了PIN码或密码)。较新的设备可以在某些条件下自动“解锁”,例如家庭WiFi、蓝牙接近、面部解锁等。我已经使用面部解锁进行了测试。(提示:为了测试,请使用Handler每1000毫秒检查一次布尔值)。 - Usman

2

1)首先需要在您的服务中注册一个广播接收器以监听电源按钮的按下(开关屏幕):

@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) 您可以使用此辅助类在任何时候确定屏幕状态:

/**
 * 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;
}

}

0
 PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
 KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
                if (pm.isInteractive() && pm.isScreenOn() && keyguardManager.isKeyguardLocked() && keyguardManager.isDeviceLocked()) { //do your stuff }

我投票关闭此问题。这个问题已经在10年前得到了回答。而你只是在重复它。 - Abhishek Dutt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接