2012-10-24 9 views
12

W mojej aplikacji wyłączam blokadę klawiatury (np. Odblokowanie ekranu blokady) za pomocą poniższego kodu i działa poprawnie, dopóki nie kliknę żadnego powiadomienia na pasku powiadomień. Jeśli kliknę powiadomienie, ekran blokady zostanie automatycznie włączony ponownie. Każda pomoc jest doceniana.Wyłączona blokada klawisza blokady ponownie włącza się po kliknięciu w powiadomienie

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()); 
    } 
} 

Odpowiedz

15

Zauważyłem ten sam problem przez pewien czas. Występuje tylko w Honeycomb (Android 3.0) i nowszych. Po wielu eksperymentach i ciągnięciu za włosy wydaje mi się, że znalazłem rozwiązanie, które działa dla mnie. Nie jest jasne, co dokładnie się dzieje i dlaczego, ale oto co odkryłem.

Wygląda na to, że na Androidzie 3.0+, po wyłączeniu blokady klawiatury, po naciśnięciu klawisza wygasa stary KeyguardLock, ale na szczęście emisja ACTION_USER_PRESENT jest w tym momencie uruchamiana, więc mamy szansę rozwiązać problem.

Jednym z punktów, które nie są wcale oczywiste z dokumentacji, jest to, że konieczne wydaje się ponowne włączenie starej blokady KeyguardLock przed uzyskaniem nowej i ponowne jej wyłączenie. Kolejną "głupotą", jaką odkryłem, jest to, że wyłączenie przez nową blokadę KeyguardLock natychmiast po ponownym włączeniu przez starą powoduje tylko sporadyczny sukces. Rozwiązałem to, czekając 300ms przed wyłączeniem.

Oto nieco uproszczona wersja mojego kodu; powinno być łatwo dostosować się do aplikacji:

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); 
     } 
    } 
}; 
+0

+1 ode mnie. uratowałem mój dzień - po prostu wprowadziłem drobną modyfikację powyższego kodu (przeniesiono linię postDelayed tuż po bloku if). –

+0

Czy to działa z telefonami RedMI? –

+0

@JalpeshKhakhi Nie testowałem tego na tych. Powinno, ale możliwe, że nie, jeśli Android został wystarczająco zmieniony. –

Powiązane problemy