Written by Chris Leversuch
May 23, 2017

PIN protection for your app using LolliPin

How to setup LolliPin pin protection to keep your apps secure

Secure access with LolliPin

We take privacy and security seriously here at Brightec. It's obviously an important issue, and increasingly so in an ever-changing digital landscape.

Clients and customers will need to be both reassured and protected. We use a range of solutions to help this, depending on the app, it's user base and business model.

One such solution to ensure that user-sensitive data is accessed securely is for an app to require PIN protection when being opened.  

The requirement is quite simple - when opening the app, either from closed or suspended states, the user should be asked to enter their PIN.

We recently used LolliPin to achieve this.

LolliPin in action

Adding LolliPin to your app is straightforward.

Setup

Add the following to your main module's build.gradule file:

compile ('com.github.orangegangsters:lollipin:2.0.0@aar') {
      transitive = true
}

Then add the following to the project's main build.gradule:

allprojects {
    repositories {
        maven {
            url "https://github.com/omadahealth/omada-nexus/raw/master/release"
        }
        jcenter()
    }
}

With this in place you need to create an Activity that extends AppLockActivity (called CustomPinActivity below, remember to add it to your Manifest file) then activate the PIN lock. The easiest place to do this is in the onCreate method of an Application subclass:

LockManager lockManager = LockManager.getInstance();
lockManager.enableAppLock(this, CustomPinActivity.class);

This is also the place to configure some of the PIN lock behaviour and appearance, such as changing the logo on the PIN screen or removing the forgot PIN code option:

lockManager.getAppLock().setLogoId(R.drawable.passcode_logo);
lockManager.getAppLock().setShouldShowForgot(false);

Setting the PIN

If PIN lock is a requirement for using your app rather than just an option, you’ll want to force the user to set a PIN.

In your main activity, you’ll need to check whether a PIN is set and, if not, open the relevant activity:

if (!LockManager.getInstance().getAppLock().isPasscodeSet()) {
    Intent intent = new Intent(this, CustomPinActivity.class);
    intent.putExtra(AppLock.EXTRA_TYPE, AppLock.ENABLE_PINLOCK);
    startActivityForResult(intent, REQUEST_FIRST_RUN_PIN);
}

Changing the PIN

Your users may want to change their PIN so you’ll need to provide an option somewhere in your UI that launches the PIN activity:

Intent intent = new Intent(getActivity(), CustomPinActivity.class);
intent.putExtra(AppLock.EXTRA_TYPE, AppLock.CHANGE_PIN);
startActivityForResult(intent, REQUEST_CODE_ENABLE);

Protecting the app

The PIN lock won’t work yet as we haven’t told LolliPin what to protect.

It doesn’t seem to have an option to just protect the app so instead, you protect the main activity in your app. This is done by making the activity extend PinActivity.

There are also PinCompatActivity which extends AppCompatActivity and PinFragmentActivity which extends FragmentActivity if you need them.

With this in place, every time you visit the activity (after the default 10-second timeout), you’ll be asked to enter your PIN.

Stopping the PIN whilst using the app

This isn’t quite what we want as we only want to protect app launch. You shouldn’t be asked to enter your PIN while using the app.

We achieved this by adding some more code to the Application subclass, specifically an implementation of ActivityLifecycleCallbacks.

In the onCreate method add registerActivityLifecycleCallbacks(this); then implement the methods.

The only one we actually need is onActivityPaused:

@Override
public void onActivityPaused(Activity activity) {
    if (activity instanceof SplashActivity) {
        return;
    }

    LockManager.getInstance().getAppLock().setLastActiveMillis();
}

The general idea is to reset the last active time every time you leave an activity, meaning that there won’t have been 10 seconds between another activity closing and the main activity opening.

In this implementation, we have a splash screen which needs to be ignored otherwise the last active will be reset every time the app opens and the PIN screen won’t be shown.

After implementing this I discovered that the library has an Only Background Timeout feature that, when paired with ignored activities, may achieve the same thing.

We hope this helps!

Top