Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement Passcode Lock for Android Application

Tags:

android

My application has sensitive user information and we need to implement a passcode screen to be displayed whenever the user opens the application. Here are the two approaches I tried after reading this post.

  1. Use a static variable and reset it in onStop() of each activity and check it again in the onStart() of each activity and show the passcode screen if the time crossed a minimum threshhold say 1-2 secs. The problem with this approach is that my application also uses intents to call camera and barcode scanners and the users may spend longer periods in these external apps. I can increase the threshold in this case but it makes the calculations complicated and is not a very good solution.

  2. I tried the other approach by using this method.

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

But this will always return true when I check for it in the onStart method of each activity since the process already started by the time it is in onStart

Is there any other approach that I can take to display a passcode when ever the user opens the application? It should be displayed even when user clicks on home screen to go out of the app and then comes back to the app from recent apps.

like image 703
achie Avatar asked Sep 19 '12 23:09

achie


1 Answers

i've implemented this exact feature. i essentially did your #1, but in a little cleaner way.

what i did was write an abstract subclass of Activity, and override onResume(). in there, decide if you need to show the pin lock screen. if you do, finish yourself and start the pin lock activity. have all your activities extend this activity.

to remember where you were at, you can add a "starting intent" extra to the intent used to start the pin lock activity. when the app is unlocked, the pin lock activity can use that extra to put the user right back where they were.

if your app was fragment-based, this would be simple. whenever the activity that hosts all of the fragments is resumed, you show the pin lock fragment. that's all.

the problem with an app consisting of a bunch of activities is that there is no clear defining moment of "starting" the app. the concept doesn't exist. this is essentially the problem you found with your #1 solution. onResume() seems like a good choice but that can be called for lots of reasons. for example, the user start activity A, which starts activity B. now they press back. show the pin lock, or not?

any solution that utilizes a thread that checks foreground processes is a terrible idea because of the battery impact.

finally, you might want to question the requirement of having a pin lock every time the app is brought into the foreground. it seems excessive if i bounce out to read a text message and come back 10s later i'm forced to re-enter a pin. time based seems more appropriate.

like image 163
Jeffrey Blattman Avatar answered Sep 25 '22 09:09

Jeffrey Blattman