DevicePolicyManager.resetPasswordWithToken throws NPE

738 views Asked by At

I use it like this:

            devicePolicyManager
                .resetPasswordWithToken(
                    componentName,
                    nonNullOrEmptyPassword,
                    nonNullOrEmptyByteArray,
                    0
                )

And it throws NPE:

java.lang.NullPointerException: Attempt to get length of null array
        at android.os.Parcel.createException(Parcel.java:2094)
        at android.os.Parcel.readException(Parcel.java:2056)
        at android.os.Parcel.readException(Parcel.java:2004)
        at android.app.admin.IDevicePolicyManager$Stub$Proxy.resetPasswordWithToken(IDevicePolicyManager.java:15625)
        at android.app.admin.DevicePolicyManager.resetPasswordWithToken(DevicePolicyManager.java:3959)

Android 10, Samsung A51, app is a device owner. What's wrong?

3

There are 3 answers

0
GinTasan On BEST ANSWER

I tested this and i think this happens in case, when you call resetPasswordWithToken() right after setResetPasswordToken() when password already has been set by user. I suppose on some devices it's "okay" behavior, for example i used to reproduce it on Huawei 10 and mentioned above case occurs the same issue, but on Realme 11 everything is okay, setResetPasswordToken() just returns false and that's it.

Case again:

  1. Password already set
  2. call setResetPasswordToken()
  3. call resetPasswordWithToken()
  4. method resetPasswordWithToken() throws that error or returns false

Solution: I noticed that error only in one case i explained above. This happens because of device peculiarity. You can wrap that resetPasswordWithToken() method into try{}catch{} and just return false when error on some devices occure. And finally to reset password user need to confirm his password by blocking the screen to user enters his password again by waiting for user to block screen by yourself, via lockNow() or just when user's screen screen timeout will be expired. After this isResetPasswordTokenActive() is going to be true and you can reset user's password via resetPasswordWithToken().

Case to reset password:

Case again:

  1. Password already set
  2. call setResetPasswordToken()
  3. Wait for user to confired his password(via lockNow() or just by waiting)
  4. call resetPasswordWithToken()
  5. method resetPasswordWithToken() should be successfully changed
1
Nikola Despotoski On

Probaby internal implementation sets the token to null if the user is not admin on the device. Check what isResetPasswordTokenActive() returns.

0
UgurBH On

Sharing my solution here, it may help someone in the future.

In my case, I was receiving the same NPE when I wanted to reset the existing device PIN. (assigned by my device owner application)

I figured out that I had to call setResetPasswordToken() method when the PIN is set for the first time, because isResetPasswordTokenActive() was returning false. I solved it as shown below.

if (!devicePolicyManager.isResetPasswordTokenActive(DeviceAdminRcvr.getComponentName(this))) {

            devicePolicyManager.setResetPasswordToken(DeviceAdminRcvr.getComponentName(this), byteValue);
            devicePolicyManager.resetPasswordWithToken(DeviceAdminRcvr.getComponentName(this), firstPassword, byteValue, 0);

} else {
            devicePolicyManager.resetPasswordWithToken(DeviceAdminRcvr.getComponentName(this), newPassword, byteValue, 0);
 }