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).
Esto también se puede lograr usando las Políticas de administración del dispositivo http://developer.android.com/guide/topics/admin/device-admin.html
Lo anterior es el camino difícil. Utilice KeyguardManager.isKeyguardSecure()
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;
}