Having trouble receiving ACTION_PASSWORD_SUCCEEDED

2019-02-10 09:36发布

问题:

I am using Android's Administration API and have a DeviceAdminReceiver, and override the following functions:

@Override
public void onEnabled(Context context, Intent intent)
{
    System.out.println("Admin On======================");       
}

@Override
public void onDisabled(Context context, Intent intent)
{
    System.out.println("Admin Off======================");
}

@Override
public void onPasswordFailed(Context context, Intent intent)
{
    System.out.println("PW Bad============================");
}

@Override
public void onPasswordSucceeded(Context context, Intent intent)
{
    System.out.println("PW Good===========================");       
}

@Override
public void onPasswordChanged(Context context, Intent intent)
{
    System.out.println("Changed PW=======================");        
}

On enabled, Disabled, and PW changed work, however password failed and succeeded do not. Strangely, they randomly work once in a while and then stop working. Is there anything wrong with my code, or could this be an API problem?

The receiver in AndroidMaifest

<receiver android:name="AdminReciever"
            android:label="Administration"
            android:permission="android.permission.BIND_DEVICE_ADMIN" android:enabled="true">
            <meta-data android:name="android.app.device_admin"
                android:resource="@xml/adminpolicies" />
            <intent-filter>
                <action android:name="android.app.action.ACTION_PASSWORD_SUCCEEDED"/>
                <action android:name="android.app.action.ACTION_PASSWORD_FAILED"></action>
                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED"></action>
                <action android:name="android.app.action.ACTION_PASSWORD_CHANGED"></action>

            </intent-filter>
</receiver>

FIXED

Found out the problem, it seems this wasn't documented. I had set a minimum password length with dpm.setPasswordMinimumLength(). The password entry activity does not fire a PASSWORD_FAILED intent if the password entered is less then the minimum length. Also PASSWORD_SUCCEEDED only fires if a bad password (PASSWORD_FAILED fired) was entered before the successful one. So two successful passwords in a row will not fire the second intent.

回答1:

You can make use of the android.intent.action.USER_PRESENT. This intent will be fired whenever the user unlocks the device. You can register a broadcast receiver which will capture the android.intent.action.USER_PRESENT to detect the device unlock events.



回答2:

Very late answer here but I was having the same issue and your 'Fixed' edit helped me work out why.

As you say, this isn't very well documented at all so can be quite misleading. The documentation suggests that any password failure will result in onPasswordFailed being called.

ACTION_PASSWORD_FAILED

Action sent to a device administrator when the user has entered an incorrect device or profile challenge password. You can at this point check the number of failed password attempts there have been with DevicePolicyManager.getCurrentFailedPasswordAttempts(). You will generally handle this in onPasswordFailed(Context, Intent, UserHandle).

However, that's not true. onPasswordFailed only appears to be called when the password/PIN/Pattern satisfies the Default Policy. This is different from your minimum password length.

Although I can't find any documentation stating the default policies, it appears to be 4 numbers (PIN), 4 characters (Password) or 4 points (Pattern). Anything less than these will not trigger the call.

For an example, set minimum length to 6 and set your password to 123ABC. Now try to login using the following :-

  • 123 - onPasswordFailed is not called
  • 123A - onPasswordFailed is called

Nice little tester project here you can try this with.

Even though you've probably well and truly moved on from this issue, someone else may gain some clarity.

Cheers.