Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disabled Keyguard Lock re-enables itself after clicking on a notification

In my application I disable the keyguard lock (i.e.Remove Lockscreen) using the code below and it works fine until I click on any notification in the notification bar. If I click on a notification the lock screen is automatically re-enabled. Any help is appreciated.

private void remove_lockscreen() {
    final CheckBoxPreference lock = (CheckBoxPreference) findPreference("remove_lockscreen");
    KeyguardManager km = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);
    KeyguardLock kl = km.newKeyguardLock("keyguard_lock");
    if (lock.isChecked()) {
        prefEdit("remove_lockscreen", 1);
        Toast.makeText(getBaseContext(), "Lockscreen will not be shown", Toast.LENGTH_SHORT).show();
        kl.disableKeyguard();
    }
    else if (!lock.isChecked()) {
        prefEdit("remove_lockscreen", 0);
        Toast.makeText(getBaseContext(), "Lockscreen will be shown", Toast.LENGTH_SHORT).show();
        kl.reenableKeyguard();
        android.os.Process.killProcess(android.os.Process.myPid());
    }
}
like image 907
Jasjit Singh Marwah Avatar asked Oct 24 '12 15:10

Jasjit Singh Marwah


1 Answers

I've noticed the same issue for some time. It only occurs on Honeycomb (Android 3.0) and up. After a great deal of experimentation and hair-pulling, I seem to have found a solution that works for me. It's not clear exactly what's going on or why, but here's what I've figured out.

It seems that on Android 3.0+, after the keyguard is disabled, when a notification is pressed, the old KeyguardLock expires, but thankfully the ACTION_USER_PRESENT Broadcast is fired at that point, so we have a chance to correct the issue.

One point that's not at all obvious from the documentation is that it seems to be necessary to reenable the old KeyguardLock before getting a new one and disabling it again. Another "gotcha" I discovered is that disabling through the new KeyguardLock immediately after reenabling through the old one produces only intermittent success. I resolved this by waiting 300ms before disabling.

Here's a slightly simplified version of my code; it should be easy to adapt to your app:

private KeyguardLock kl;
private KeyguardManager km;

private final Handler mHandler = new Handler();

private final Runnable runDisableKeyguard = new Runnable() {
    public void run() {
        kl = km.newKeyguardLock(getPackageName());
        kl.disableKeyguard();
    }
};

private void setEnablednessOfKeyguard(boolean enabled) {
    if (enabled) {
        if (kl != null) {
            unregisterReceiver(mUserPresentReceiver);
            mHandler.removeCallbacks(runDisableKeyguard);
            kl.reenableKeyguard();
            kl = null;
        }
    } else {
        if (km.inKeyguardRestrictedInputMode()) {
            registerReceiver(mUserPresentReceiver, userPresent);
        } else {
            if (kl != null)
                kl.reenableKeyguard();
            else
                registerReceiver(mUserPresentReceiver, userPresent);

            mHandler.postDelayed(runDisableKeyguard,  300);
        }
    }
}

private final BroadcastReceiver mUserPresentReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())){
            if (sp_store.getBoolean(KEY_DISABLE_LOCKING, false))
                setEnablednessOfKeyguard(false);
        }
    }
};
like image 70
Darshan Rivka Whittle Avatar answered Sep 19 '22 16:09

Darshan Rivka Whittle