verificar si el locking fue habilitado o no

Debo verificar si el locking del sistema estaba habilitado o no en la configuración.

Utilicé el código de línea a continuación

boolean b = android.provider.Settings.System.getInt( getContentResolver(),Settings.System.LOCK_PATTERN_ENABLED, 0)==1; 

Devuelve true si configuro el locking de pattern y es falso si configuro la pin/password contraseña.

Necesito verificar si el locking está habilitado o no, ya sea locking de pattern/pin/password en la configuración.

Mi código solo funciona para el locking de pattern no para el locking de pin/password .

Así que por favor dígame cómo verificar todo tipo de cerraduras.

Entonces esta pregunta es bastante antigua, pero parece que todavía no hay una buena respuesta. Después de un código fuente ( del enlace de Ramakrishna ) investigación y autoexperimentos, escribo una clase simple que hace el trabajo.

 public class LockType { private final static String PASSWORD_TYPE_KEY = "lockscreen.password_type"; /** * This constant means that android using some unlock method not described here. * Possible new methods would be added in the future releases. */ public final static int SOMETHING_ELSE = 0; /** * Android using "None" or "Slide" unlock method. It seems there is no way to determine which method exactly used. * In both cases you'll get "PASSWORD_QUALITY_SOMETHING" and "LOCK_PATTERN_ENABLED" == 0. */ public final static int NONE_OR_SLIDER = 1; /** * Android using "Face Unlock" with "Pattern" as additional unlock method. Android don't allow you to select * "Face Unlock" without additional unlock method. */ public final static int FACE_WITH_PATTERN = 3; /** * Android using "Face Unlock" with "PIN" as additional unlock method. Android don't allow you to select * "Face Unlock" without additional unlock method. */ public final static int FACE_WITH_PIN = 4; /** * Android using "Face Unlock" with some additional unlock method not described here. * Possible new methods would be added in the future releases. Values from 5 to 8 reserved for this situation. */ public final static int FACE_WITH_SOMETHING_ELSE = 9; /** * Android using "Pattern" unlock method. */ public final static int PATTERN = 10; /** * Android using "PIN" unlock method. */ public final static int PIN = 11; /** * Android using "Password" unlock method with password containing only letters. */ public final static int PASSWORD_ALPHABETIC = 12; /** * Android using "Password" unlock method with password containing both letters and numbers. */ public final static int PASSWORD_ALPHANUMERIC = 13; /** * Returns current unlock method as integer value. You can see all possible values above * @param contentResolver we need to pass ContentResolver to Settings.Secure.getLong(...) and * Settings.Secure.getInt(...) * @return current unlock method as integer value */ public static int getCurrent(ContentResolver contentResolver) { long mode = android.provider.Settings.Secure.getLong(contentResolver, PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); if (mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) { if (android.provider.Settings.Secure.getInt(contentResolver, Settings.Secure.LOCK_PATTERN_ENABLED, 0) == 1) { return LockType.PATTERN; } else return LockType.NONE_OR_SLIDER; } else if (mode == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) { String dataDirPath = Environment.getDataDirectory().getAbsolutePath(); if (nonEmptyFileExists(dataDirPath + "/system/gesture.key")) { return LockType.FACE_WITH_PATTERN; } else if (nonEmptyFileExists(dataDirPath + "/system/password.key")) { return LockType.FACE_WITH_PIN; } else return FACE_WITH_SOMETHING_ELSE; } else if (mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC) { return LockType.PASSWORD_ALPHANUMERIC; } else if (mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC) { return LockType.PASSWORD_ALPHABETIC; } else if (mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) { return LockType.PIN; } else return LockType.SOMETHING_ELSE; } private static boolean nonEmptyFileExists(String filename) { File file = new File(filename); return file.exists() && file.length() > 0; } } 

Ahora solo debes hacer

 int lockType = LockType.getCurrent(getContentResolver()); 

de tu clase de Actividad . Si desea verificar algún conjunto de tipos de locking, simplemente use la instrucción switch

 switch (lockType) { case LockType.FACE_WITH_PATTERN: case LockType.FACE_WITH_PIN: case LockType.PATTERN: /* do something */ break; } 

o si solo quieres “Face Unlock” no importa con qué método adicional

 if (lockType >= LockType.FACE_WITH_PATTERN && lockType <= LockType.FACE_WITH_SOMETHING_ELSE) { /* do something */ } 

EDITAR: entonces, estoy probando esta clase en 3 teléfonos y parece que no todos los teléfonos detectan correctamente el método de deslocking facial. En algunos teléfonos PASSWORD_QUALITY_BIOMETRIC_WEAK regresa y PASSWORD_QUALITY_SOMETHING en otros. Creo que podemos verificar que algún archivo que contiene información para el deslocking facial existe y no está vacío, de forma similar a los métodos de contraseña / PIN y patrón. Pero por ahora no sé dónde está exactamente este archivo.

EDIT2: Parece que encontré el problema después de la investigación del código de Android 4.3. Esto se debe a que la configuración de locking se movió a una nueva ubicación (/data/system/locksettings.db) y parece que no hay forma de obtener esa configuración de esta base de datos (rw-rw ---- permisos y propietario y grupo de "sistema" para solo root puede hacer el trabajo).

Tenga cuidado, este método parece estar desactualizado también! ¡Gracias Dantalian por la pista!

LockPatternUtils es una clase privada. Pero puedes leer el modo de locking con un poco de reflexión: (funciona con Nexus5, Android 4.4.4)

 private boolean isDeviceSecured() { String LOCKSCREEN_UTILS = "com.android.internal.widget.LockPatternUtils"; try { Class lockUtilsClass = Class.forName(LOCKSCREEN_UTILS); // "this" is a Context, in my case an Activity Object lockUtils = lockUtilsClass.getConstructor(Context.class).newInstance(this); Method method = lockUtilsClass.getMethod("getActivePasswordQuality"); int lockProtectionLevel = (Integer)method.invoke(lockUtils); // Thank you esme_louise for the cast hint if(lockProtectionLevel >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) { return true; } } catch (Exception e) { Log.e("reflectInternalUtils", "ex:"+e); } return false; } 

A partir de Android 6.0 Marshmallow (SDK 23), existe un nuevo método para realizar esta tarea. Mira esto

http://developer.android.com/reference/android/app/KeyguardManager.html#isDeviceSecure ()

Uso:

 public static boolean isDeviceSecure(Context context) { if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { KeyguardManager manager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE); return manager.isDeviceSecure(); } // reflection code from the other answers here ... } 

@Peter Pint y esme_louise

Gracias, tu solución me puso en marcha. Para saber si el locking de pantalla está habilitado o no, podría simplificar aún más tu método. Esto devuelve falso para deslizar o bloquear correctamente (PIN, PW, deslocking facial, etc.) y devuelve falso para la opción ‘Ninguno’. Para la distinción entre deslizar y uno de los métodos de locking adecuados, uso KeyguardManager.isKeyguardSecure ()

Debería funcionar con nivel de API 14+:

 private boolean isLockScreenDisabled(Context context) { String LOCKSCREEN_UTILS = "com.android.internal.widget.LockPatternUtils"; try { Class lockUtilsClass = Class.forName(LOCKSCREEN_UTILS); // "this" is a Context, in my case an Activity Object lockUtils = lockUtilsClass.getConstructor(Context.class).newInstance(context); Method method = lockUtilsClass.getMethod("isLockScreenDisabled"); boolean isDisabled = Boolean.valueOf(String.valueOf(method.invoke(lockUtils))); return isDisabled; } catch (Exception e) { Log.e("reflectInternalUtils", "ex:"+e); } return false; } 

ACTUALIZACIÓN: he adaptado el código a android M utilizando el nuevo método isDeviceSecure (). Sin embargo, esto no permite diferenciar entre ‘Ninguno’ y ‘Deslizar’ más. Además, el método ya comenzó a fallar en 5.x (creo que 5.1.1) con una SecurityException. Esto requirió un hack extra en el bloque catch.

Para mi propósito de detectar si el usuario está ausente y USER_PRESTENT se transmitirá cuando el dispositivo se activa / desbloquea, isDeviceSecure () es lo suficientemente bueno y me alegro de deshacerme de las reflexiones frágiles para lanzamientos futuros.

 private boolean isLockScreenDisabled(Context context) { // Starting with android 6.0 calling isLockScreenDisabled fails altogether because the // signature has changed. There is a new method isDeviceSecure which, however, does // not allow the differentiation between lock screen 'None' and 'Swipe. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ KeyguardManager keyguardMgr = (KeyguardManager) context .getSystemService(Context.KEYGUARD_SERVICE); // But luckily there is no 'Automatically lock x minutes after sleep' option when // 'Swipe' is set which means that as soon as the screen is off, switching back on // requires a swipe which results in a USER_PRESENT broadcast. return !keyguardMgr.isDeviceSecure(); } String LOCKSCREEN_UTILS = "com.android.internal.widget.LockPatternUtils"; try { Class lockUtilsClass = Class.forName(LOCKSCREEN_UTILS); Object lockUtils = lockUtilsClass.getConstructor(Context.class).newInstance(context); Method method = lockUtilsClass.getMethod("isLockScreenDisabled"); // Starting with android 5.x this fails with InvocationTargetException // (caused by SecurityException - MANAGE_USERS permission is required because // internally some additional logic was added to return false if one can switch between several users) // if (Screen Lock is None) { // ... exception caused by getting all users (if user count) // } else { // return false; // } // -> therefore if no exception is thrown, we know the screen lock setting is // set to Swipe, Pattern, PIN/PW or something else other than 'None' boolean isDisabled; try { isDisabled = Boolean.valueOf(String.valueOf(method.invoke(lockUtils))); } catch (InvocationTargetException ex) { Log.w(TAG, "Expected exception with screen lock type equals 'None': " + ex); isDisabled = true; } return isDisabled; } catch (Exception e) { Log.e(TAG, "Error detecting whether screen lock is disabled: " + e); e.printStackTrace(); } return false; } 

Y este es el método que lo usa: determina si el usuario está ausente de manera que la próxima vez que se enciende la pantalla (si no está configurado el locking de pantalla) o si el dispositivo está desbloqueado (incluyendo deslizar) se transmite un USER_PRESENT_ACTION.

 public boolean isUserAbsent(Context context) { KeyguardManager kgMgr = (KeyguardManager) context .getSystemService(Context.KEYGUARD_SERVICE); boolean isDeviceLocked = kgMgr.inKeyguardRestrictedInputMode(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { // there was no 'None' option for screen lock in the olden days return isDeviceLocked; } PowerManager powerManager = (PowerManager) context .getSystemService(Context.POWER_SERVICE); if (isLockScreenDisabled(context)) { // Lock Type 'None' (USER_PRESENT is broadcast when screen comes on) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { // android 3.0 - 4.1: we have a problem with 'None' because // user_present is never broadcast! UserLog.log(TAG, context, "No screen lock on android 3.0 - 4.1: User-presence will not be detected! Please switch to 'Swipe'"); } return !powerManager.isInteractive(); } else { // Lock Type 'Swipe' or proper lock (USER_PRESENT is broadcast when device is unlocked) return isDeviceLocked; } } 

Lo de arriba es la manera difícil. Use KeyguardManager.isKeyguardSecure ()

 KeyguardManager km = (KeyguardManager)getApplicationContext().getSystemService(Context.KEYGUARD_SERVICE); if(km.isKeyguardSecure()) Toast.makeText(getApplicationContext(), "locked", Toast.LENGTH_LONG).show(); else Toast.makeText(getApplicationContext(), "Unlocked", Toast.LENGTH_LONG).show(); 

Esto también se puede lograr utilizando las políticas de administración de dispositivos http://developer.android.com/guide/topics/admin/device-admin.html

@Peter Pint

 int lockProtectionLevel = (int)method.invoke(lockUtils); 

… debería ser …

 int lockProtectionLevel = Integer.valueOf(String.valueOf(method.invoke(lockUtils))); 

Pero de lo contrario, ¡adelante! He votado a favor su respuesta.

Si habla sobre el locking de pantalla, puede intentar configurar un BroadcastReceiver específico y escuchar Itents específicos del sistema Android.

Espero que te ayude Perdón si no te entendí 🙂