设备策略管理器的GetPasswordQuality方法第一次没有给出任何值?

时间:2016-01-14 09:57:48

标签: android passwords change-password device-policy-manager

在我的设备中,我已经设置了设备密码,现在我安装了由设备策略管理器管理的应用程序。现在,当我称这种方法

 int currentPolicy = devicePolicyManager.getPasswordQuality(demoDeviceAdmin);
    if(currentPolicy==262144)passwordType="Alphabetic";
    else if(currentPolicy==327680)passwordType="Alphanumeric";
    else if(currentPolicy==131072)passwordType="Numeric";
    //if(currentPolicy==196608)passwordType="PASSWORD_QUALITY_NUMERIC_COMPLEX";
    else if(currentPolicy==393216)passwordType="Complex";
    else if(currentPolicy==196608)passwordType="Pattern";
    else if(currentPolicy==0)passwordType="None"; 

它给我密码类型无。现在,如果我在我的应用程序中通过设备策略管理器设置密码,就像这样

  Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
                                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(intent);

然后现在如果再次获得密码质量,它会给我正确的价值。 在我第一次认为设备策略管理器没有或存储旧密码类型。

所以我的问题是如何在通过设备策略管理器从我的应用程序设置密码之前获得密码质量。

谢谢

2 个答案:

答案 0 :(得分:0)

getPasswordQuality没有报告当前密码的质量,它只报告最低允许密码质量的策略设置。

基本上,如果多个管理员处于活动状态,则getPasswordQuality将使用admin的setPasswordQuality或聚合值返回设置的值。

管理员可以通过调用DevicePolicyManager.isActivePasswordSufficient()来检查当前密码是否足够好。

Keyguard使用隐藏方法setActivePasswordState向DevicePolicyManager报告当前密码状态。

据我所知,此信息不适用于第三方管理应用。

如果输入的密码不正确,keyguard会调用DevicePolicyManager.reportFailedPasswordAttempt,如果尝试了太多失败尝试,则会启动恢复出厂设置。

希望这有帮助。

/ Marek Pola(索尼移动员工)

答案 1 :(得分:0)

对于Android 6之前的设备(独家),您可以通过调用类LockPatternUtils中的隐藏函数getActivePasswordQuality()来获取解锁方法类型(您可以通过Java反射调用该函数)。但对于Android 6及更高版本,我还没有想出如何获得解锁方法类型。

 /**
 * Determine authentication method type (DAS, PIN, Password or Biometric)
 */
private String getAuthenticationMethodType(){
    String LOCK_PATTERN_UTILS="com.android.internal.widget.LockPatternUtils";
    String ACTIVE_PASSWORD_QUALITY="getActivePasswordQuality";

    int lockProtectionLevel=0;
    try{
        Class <?> lockPatternUtilsClass=Class.forName(LOCK_PATTERN_UTILS);
        Object lockPatternUtils=lockPatternUtilsClass.getConstructor(Context.class).newInstance(this);

        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
            // Have not figured out how to get the unlocking method type for Android 6 and above devices. The same method will not work on Android 6. See detailed explanation below.
        }else {
            Method method = lockPatternUtilsClass.getMethod(ACTIVE_PASSWORD_QUALITY);
            lockProtectionLevel=Integer.valueOf(String.valueOf(method.invoke(lockPatternUtils,null)));
        }
    }catch (Exception e){
        e.printStackTrace();
    }
    switch (lockProtectionLevel){
        case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
        case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
            return "PIN";
        case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
        case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
        case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
            return "Password";
        case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
            return "DAS";
        case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK:
            return "Biometric";
        default:return "None";
    }
}

对于Android 6,在我到目前为止的所有测试之后,我发现如果我们仍然想要使用函数getActivePasswordQuality(int userId)获取解锁方法,则应用必须具有权限android.permission.ACCESS_KEYGUARD_SECURE_STORAGE才能阅读{{ 1}},并获得解锁方法。但是,权限lockscreen.password_type是签名权限,这意味着我们需要使用制造商用于签署系统的相同密钥(或说明权限)来签署应用程序,以便授予签名权限该应用成功。

希望这会有所帮助。