KeyguardManager fails to unlock kitkat screen

1.1k views Asked by At

I've noticed very interesting behavior of Android that I cannot explain. I'm using the following code to wake up the phone and disable keyguard:

        PowerManager.WakeLock mFullWakelock = mPowerManager.newWakeLock(
                (PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
                        PowerManager.FULL_WAKE_LOCK |
                        PowerManager.ACQUIRE_CAUSES_WAKEUP),
                LOCK_TAG
        );

        mFullWakelock.acquire();

        KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
        KeyguardManager.KeyguardLock keyguardLock = keyguardManager.newKeyguardLock(LOCK_TAG);

        keyguardLock.disableKeyguard();

Imagine there is cycle of wake (programmatically)->disable keyguard (programmatically)->press power button (manually)->wake->disable keyguard. The cycle works great until I manually press Home button while the phone's keyguard is disabled. After that, phone does wake up but keyguard is no longer disabled programmatically. I'd appreciate any ideas!

2

There are 2 answers

0
Robbe On BEST ANSWER

The problem is that a keylock seems to expire whenever the user presses home button or opens a notification. So whenever this happens, you have to create a new keylock.

I used this solution and it worked great: https://stackoverflow.com/a/14519861/4098821

2
tanmeet On

I had the same problem and i solved it using reflection and making my application as system signed app.

Here's the code:

try{
                                   Class lockPatternUtilsCls = Class.forName("com.android.internal.widget.LockPatternUtils");
                                   Constructor lockPatternUtilsConstructor = 
                                       lockPatternUtilsCls.getConstructor(new Class[]{Context.class});
                                   lockPatternUtilsConstructor.setAccessible(true);
                                   Object lockPatternUtils = lockPatternUtilsConstructor.newInstance(ChangeDeviceLockMode.this);
                                   Method clearLockMethod = lockPatternUtils.getClass().getMethod("clearLock", boolean.class);
                                   clearLockMethod.setAccessible(true);
                                   Method setLockScreenDisabledMethod = lockPatternUtils.getClass().getMethod("setLockScreenDisabled", boolean.class);
                                   setLockScreenDisabledMethod.setAccessible(true);
                                   clearLockMethod.invoke(lockPatternUtils, false);
                                   setLockScreenDisabledMethod.invoke(lockPatternUtils, true);     
                                   Toast.makeText(ChangeDeviceLockMode.this,"none", Toast.LENGTH_LONG).show();  
                           }catch(Exception e){
                               System.err.println("An InvocationTargetException was caught!");
                                                   Throwable cause = e.getCause();
                                                   Toast.makeText(ChangeDeviceLockMode.this,"none--"+cause, Toast.LENGTH_LONG).show();  
                               Toast.makeText(ChangeDeviceLockMode.this,"none--"+e, Toast.LENGTH_LONG).show();  
                           }

You also need to add a permission in manifest

android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />

This permission requires app to be system signed.