Saber cuándo mostrar un bloqueo de contraseña

Estoy desarrollando una aplicación que necesita mostrar una pantalla de código de acceso cada vez que un usuario abandona la aplicación y regresa (ya sea a través de un bloqueo de pantalla, o volver a la pantalla de inicio a través del botón de inicio o de inicio). Lo hice funcionando usando el siguiente:

La actividad de inicio requeriría la comprobación de código de acceso al inicio, y cada actividad agregó la siguiente funcionalidad a su método onPause:

@Override public void onPause() { super.onPause(); if (!isFinishing()) { new PasscodeCheckTask(this.getApplicationContext(),this).execute(); } } 

El PassocdeCheckTask se parece a lo siguiente. Comprueba si la pantalla está desactivada o la aplicación ya no está en segundo plano

 public class PasscodeCheckTask extends AsyncTask<Void, Void, Boolean> { public static final int CHECK_PASSCODE = 0; private Context mActivityApplicationContext; private Context mActivityContext; public PasscodeCheckTask(Context applicationContext, Context activityContext){ mActivityApplicationContext = applicationContext; mActivityContext = activityContext; } @Override protected Boolean doInBackground(Void... params) { Boolean result = false; if (!((PowerManager)mActivityApplicationContext.getSystemService(android.content.Context.POWER_SERVICE)).isScreenOn() || !isAppOnForeground(mActivityApplicationContext)) { result = true; } return result; } @Override protected void onPostExecute(Boolean result) { if (result) { // Start passcode activity to check for passcode /* CODE HERE */ ((Activity)mActivityContext).startActivityForResult(intent, CHECK_PASSCODE); } } protected boolean isAppOnForeground(final Context context) { List<RunningAppProcessInfo> appProcesses = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getRunningAppProcesses(); if (appProcesses == null) { return false; } final String packageName = context.getPackageName(); for (RunningAppProcessInfo appProcess : appProcesses) { if ((appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) && appProcess.processName.equals(packageName)) { return true; } } return false; } } 

La actividad de Código de acceso finalizaría cuando terminara y la actividad de llamada moveríaTaskToBackground (true) si la contraseña no pasó. Este sistema funcionó maravillosamente hasta que lo probé en un HTC Evo con mikg ROM. Por alguna razón, la appProcess.importance nunca apareció como IMPORTANCE_FOREGROUND. Siempre fue IMPORTANCE_BACKGROUND. Por lo tanto, el código de acceso siempre se planteó, a pesar de que la aplicación nunca fue en el fondo.

Intenté DropBox en ese teléfono (que tiene un bloqueo de la contraseña también), y trabajó maravillosamente. Parece que no puedo encontrar una forma diferente de saber cuándo una aplicación ha pasado al fondo, o si se está volviendo del fondo. ¿Ideas sobre cómo hacer que esto funcione?

En onStop() de cada actividad, actualice un miembro de datos estáticos con el tiempo que dejó la actividad. En onStart() de cada actividad, compruebe ese tiempo y, si excede algún umbral de tiempo de espera, muestre su actividad de autenticación. Permitir al usuario establecer el valor de tiempo de espera, de modo que si no quieren ser molestados cada pocos segundos, pueden controlar eso.

Me gustó el enfoque basado en el tiempo, he estado luchando por un tiempo para que esto funcione de una manera agradable. El enfoque basado en el tiempo funciona bien. Hice una clase para un uso más fácil.

 public class PinCodeCheck { private static long INIT_TIME = 0; private static PinCodeCheck ref = null; private static SharedPreferences values = null; private PinCodeCheck(Context context){ values = context.getSharedPreferences("com.example.xxx", 0); //use your preferences file name key! }//end constructor public static synchronized PinCodeCheck getInstance(Context context) { if (ref == null){ ref = new PinCodeCheck(context); } return ref; }//end method public void init(){ PinCodeCheck.INIT_TIME = System.currentTimeMillis(); }//end method public void forceLock(){ PinCodeCheck.INIT_TIME = 0; }//end method public boolean isLocked(){ long currentTime = System.currentTimeMillis(); long threshold = values.getLong(Keys.PASSWORD_PROTECT_TIMEOUT, 30000); // check here, might change in between calls if (currentTime - PinCodeCheck.INIT_TIME > threshold){ return true; } return false; }//end method }//end class 

USO

 private static PinCodeCheck check = PinCodeCheck.getInstance(context); @Override public void onResume() { super.onResume(); if (check.isLocked()) { showDialog(); } }//end method @Override public void onPause() { super.onPause(); check.init(); }//end method 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.