Android手机如何判断有没有锁屏密码

Android手机如何判断有没有锁屏密码

今天来到新公司接收到的第一个任务就是这个,调研有没有方式判断Android手机有没有锁屏密码,最初的想法是自己以前写过一下程序锁的实现原理,去监听历史任务栈,看第一个程序是不是就是程序锁,结果失败告终,问了一个以前的朋友,了解到keyguard这个类,Google一下,看Keyguard解锁屏机制这个介绍的比较详细。大概了解了锁屏的原理。不多说了,直接进入正题


Google有几种默认的锁屏方式

public static final int PASSWORD_QUALITY_ALPHABETIC = 262144;//字母密码
    public static final int PASSWORD_QUALITY_ALPHANUMERIC = 327680;//字母数字密码
    public static final int PASSWORD_QUALITY_BIOMETRIC_WEAK = 32768;
    public static final int PASSWORD_QUALITY_COMPLEX = 393216;//复杂密码,我没有测试到
    public static final int PASSWORD_QUALITY_NUMERIC = 131072;//数字密码
    public static final int PASSWORD_QUALITY_NUMERIC_COMPLEX = 196608; //复杂数字密码
    public static final int PASSWORD_QUALITY_SOMETHING = 65536;//图案密码
    public static final int PASSWORD_QUALITY_UNSPECIFIED = 0;//无密码

下面问题来了,如何获取这些状态呢,通过看KeyGuard类,了解到,这个类里面判断模式的都是通过LockPatternUtils类去获取锁屏时的密码模式的,该类是在 frameworks 层的,Android内置的,无法直接访问。

找了一下资料,在stackoverflow上看到一个如下写的代码:

 boolean isLock = android.provider.Settings.System.getInt(
                getContentResolver(), Settings.System.LOCK_PATTERN_ENABLED, 0) == 1;

判断isLock真假来判断如否有屏幕锁,该方法经过测试,在无密码的状态是可以,在图案密码的情况下也是可以的,但是在数字密码的情况下不行,此方式行不通。还是换回第一种思路

在googlesources上查看LockPatternUtils代码
看到有好几个获取锁屏模式的方法:
getActivePasswordQuality():

 /**
     * Used by device policy manager to validate the current password
     * information it has.
     */
    public int getActivePasswordQuality() {
        int activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
        // Note we don't want to use getKeyguardStoredPasswordQuality() because we want this to
        // return biometric_weak if that is being used instead of the backup
        int quality =
                (int) getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
        switch (quality) {
            case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
                if (isLockPatternEnabled()) {
                    activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
                }
                break;
            case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK:
                if (isBiometricWeakInstalled()) {
                    activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
                }
                break;
            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
                if (isLockPasswordEnabled()) {
                    activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
                }
                break;
            case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
                if (isLockPasswordEnabled()) {
                    activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC;
                }
                break;
            case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
                if (isLockPasswordEnabled()) {
                    activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
                }
                break;
            case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
                if (isLockPasswordEnabled()) {
                    activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
                }
                break;
        }
        return activePasswordQuality;
    }

getKeyguardStoredPasswordQuality():


    /**
     * Retrieves the quality mode we're in.
     * {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
     *
     * @return stored password quality
     */
    public int getKeyguardStoredPasswordQuality() {
        int quality =
                (int) getLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
        // If the user has chosen to use weak biometric sensor, then return the backup locking
        // method and treat biometric as a special case.
        if (quality == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
            quality =
                (int) getLong(PASSWORD_TYPE_ALTERNATE_KEY,
                        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
        }
        return quality;
    }

看注释,getKeyguardStoredPasswordQuality不建议使用,于是反射LockPatternUtils调用getActivePasswordQuality方法获取锁屏模式
代码如下:

private boolean isPhoneHasLock() {
        String LOCKSCREEN_UTILS = "com.android.internal.widget.LockPatternUtils";
        try {
            Class lockUtilsClass = Class.forName(LOCKSCREEN_UTILS);
            Object lockUtils = lockUtilsClass.getConstructor(Context.class).newInstance(this);
            try {
                Method method = lockUtilsClass.getMethod("getActivePasswordQuality");
                Integer mode = (Integer) method.invoke(lockUtils);
                if (mode == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
                    return false;
                } else {
                    return true;
                }
            } catch (Exception e) {

        } catch (Exception e) {
            Log.e("reflectInternalUtils", "ex:" + e);
        }

        return false;
    }

通过该方法就可以判断Android手机是否有解屏密码了。

* 注意,该方法需要在屏幕点亮的广播中调用,才能及时判断用户是否有解屏密码。*

顺带把注册屏幕开关的代码也附上,以后查找方便

  IntentFilter mScreenOnFilter = new IntentFilter("android.intent.action.SCREEN_ON");
   this.registerReceiver(mScreenOReceiver, mScreenOnFilter);

   private BroadcastReceiver mScreenOReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals("android.intent.action.SCREEN_ON")) {
        isPhoneHasLock();
            } 
        }

    };

第一次用markdown写blog,写完啦。仅供同行学习,欢迎指导!

你可能感兴趣的:(android)