studio setsupportactionbar programacion móviles from desarrollo curso change aplicaciones android

android - setsupportactionbar - comprobar si el bloqueo estaba habilitado o no



programacion android pdf 2018 (9)

Tengo que comprobar si el bloqueo del sistema estaba habilitado o no en la configuración.

Usé el siguiente código de línea

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

Devuelve true si configuro el bloqueo del pattern y false si configuro la pin/password .

Necesito verificar si el bloqueo estaba habilitado o no, es un bloqueo de pattern/pin/password en la configuración.

Mi código solo funciona para bloquear el pattern no para bloquear pin/password bloquear la pin/password .

Así que por favor, dime cómo comprobar todo tipo de cerraduras.


@Peter Pint

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

... debería ser ...

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

¡Pero por lo demás, justo en! He votado su respuesta.


@Peter Pint y esme_louise

Gracias, tu solución me hizo seguir. Para saber si el bloqueo de pantalla está habilitado o no, podría simplificar aún más su método. Esto devuelve falso para deslizar o bloqueo apropiado (PIN, PW, Desbloqueo facial, etc.) y devuelve falso para la opción ''Ninguno''. Para la distinción entre deslizar y uno de los métodos de bloqueo apropiados, uso KeyguardManager.isKeyguardSecure ()

Debería funcionar con nivel API 14+:

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

ACTUALIZACIÓN: He adaptado el código para 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 excepción SecurityException. Esto requirió un hack adicional en el bloque catch.

Para mi propósito de detectar si el usuario está ausente y USER_PRESTENT se emitirá cuando el dispositivo se active / desbloquee, IsDeviceSecure () es lo suficientemente bueno y me alegro de deshacerme de las reflexiones frágiles para futuras versiones.

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

Y este es el método que lo usa: determina si el usuario está ausente de manera que la próxima vez que se encienda la pantalla (si no se configura el bloqueo de la pantalla) o si el dispositivo está desbloqueado (incluido el deslizamiento) se emite un USER_PRESENT_ACTION.

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


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 ... }


Así que esta pregunta es bastante antigua pero parece que todavía no hay una buena respuesta. Después de algunas investigaciones de código fuente ( del enlace de Ramakrishna ) y auto experimentos, escribí clases simples que hacen 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 necesitas hacer

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

de su clase de Activity . Si desea verificar algunos conjuntos de tipos de bloqueo, 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 desea "Desbloqueo facial" sin importar con qué método adicional

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

EDIT: entonces, estoy probando esta clase en 3 teléfonos y parece que no todos los teléfonos detectan correctamente el método de desbloqueo facial. En algunos teléfonos, PASSWORD_QUALITY_BIOMETRIC_WEAK devuelve y PASSWORD_QUALITY_SOMETHING en otros. Creo que podemos comprobar que un archivo que contiene información para el desbloqueo facial existe y no está vacío, es similar a los métodos de contraseña / pin y patrón. Pero por ahora no sé exactamente dónde está 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 bloqueo 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 el propietario y grupo del "sistema", por lo que Sólo la raíz puede hacer el trabajo).




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

Espero que te ayude. Lo siento si no te entendí :)


¡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 bloqueo con cierta 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; }


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