Open In App

Material Design Pincode in Android with LolliPin Library

Last Updated : 06 Feb, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Lollipin is a Lollipop material design-styled android Pincode library that provides developers to implement a material Pincode activity without any hustle. Now, the question is Why one will use the Lollipin library.

  • Password protection: The password itself is not saved, only it’s hash using the SHA-1 algorithm. This hash is then saved in the SharedPreferences, allowing to verify that the user entered the right PinCode, without giving the possibility to retrieve it.
  • Introducing Fingerprint: Once the user has enabled the password, he can also use his fingerprint scanner to unlock his device.
  • Developer friendly: This awesome library gives you a stunning prebuild User interface with various methods to ease the work.

A sample video is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Kotlin language. 

Step by Step Implementation

Step 1: Create a New Project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Kotlin as the programming language.

Step 2: Add dependency

Add these following dependencies into your project, which will import the Lollipin library into your existing project.

// Paste this in build.gradle app level
// This will import the Lollipin library into your existing project
implementation ('com.github.omadahealth:lollipin:2.1.0@aar'{
      transitive = true
   }
   
   // Paste this in your build.gradle project level
   // This is for custom ripple animation
   allprojects {
    repositories {
        maven{
            url "https://github.com/omadahealth/omada-nexus/raw/master/release"
        }
        jcenter()
    }
   }

Step 3: 

So, let’s discuss the core components of the Lollipin library. So basically, we need to create a dedicated activity for implementing our locker activity. In our case, we made a PinCodeKotlin activity for this purpose.

PinCodeKotlin Activity

Kotlin




import android.widget.Toast
import com.github.omadahealth.lollipin.lib.managers.AppLockActivity
  
// Here we are extending our activity with 
// AppLockActivity so that we can use
// its core features
class PinCodeKotlin : AppLockActivity() {
  
    // For Implementing forgot pin logic
    override fun showForgotDialog() {
        Toast.makeText(this,"Implement your forgot password logic here.",Toast.LENGTH_LONG).show()
    }
  
    // For handling pin failure  events
    override fun onPinFailure(attempts: Int) {
        Toast.makeText(this,"Pin entered is Incorrect and attempts done are $attempts",Toast.LENGTH_LONG).show()
    }
  
    // For handling pin success events
    override fun onPinSuccess(attempts: Int) {
        Toast.makeText(this,"Correct Pin",Toast.LENGTH_LONG).show()
    }
  
    // For overriding default length option
    // We can override the size of
    // Pin required as we want
    override fun getPinLength(): Int {
        return 4
    }
}


After this step, we need to tell the Lollipin library to use this library. So we can do this in two ways.

  1. By telling the library in each activity
  2. By telling the library in one application-level class

We are going to use the 2nd method as it is mostly suggested by the library itself.

App class

We also need to attach this class to our Android manifest file using the name attribute. Our AndroidManifest.xml is below

XML




<?xml version="1.0" encoding="utf-8"?>
    package="in.kay.gfglollipinapp">
  
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:name=".app"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.GFGLollipinApp">
        <activity
            android:name=".LockedActivity"
            android:exported="false" />
        <activity
            android:name=".PinCodeKotlin"
            android:exported="false" />
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
  
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
  
</manifest>


Kotlin




import android.app.Application
import com.github.omadahealth.lollipin.lib.managers.LockManager
  
class app: Application() {
    override fun onCreate() {
        super.onCreate()
          
        // Here we are enabling our 
        // custom Pin code activity
        LockManager.getInstance().enableAppLock(this,PinCodeKotlin::class.java)
          
        // We are setting custom logo 
        // for our Pin code activity
        LockManager.getInstance().appLock.logoId=R.drawable.ic_gfg
        
        // This is used to give locker a custom timeout setting
        // It is in milliseconds
        // LockManager.getInstance().appLock.timeout=4000
    }
}


MainActivity 

Now, we need to call the different core functions of the library from our main Activity.

Kotlin




import `in`.kay.gfglollipinapp.databinding.ActivityMainBinding
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.github.omadahealth.lollipin.lib.managers.AppLock
import com.github.omadahealth.lollipin.lib.managers.LockManager
  
class MainActivity : AppCompatActivity() {
      
    // This is view binding which is used to 
    // bind view without those long findViewbyIds line
    private lateinit var binding: ActivityMainBinding
    
    // We are creating a global locker instance for our work
    private var locker = LockManager.getInstance()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
          
        // locker.appLock.logoId=R.drawable.ic_gfg
        // Used to enable our locker first time
        binding.btnEnable.setOnClickListener {
            
            // We are fwding app to PinCodeKotlin 
            // class for enabling the PinCode
            val intent = Intent(this@MainActivity, PinCodeKotlin::class.java)
              
            // We add some extras which is provided by library
            intent.putExtra(AppLock.EXTRA_TYPE, AppLock.ENABLE_PINLOCK)
            startActivityForResult(intent, 101)
        }
        binding.btnChangePin.setOnClickListener {
            val intent = Intent(this@MainActivity, PinCodeKotlin::class.java)
  
            // We are checking that is our passcode is already set or not
            // In simple terms if user is new and he didn't set the passcode
            // then we will send it to choose new passcode
            if (locker.isAppLockEnabled && locker.appLock.isPasscodeSet) {
                intent.putExtra(AppLock.EXTRA_TYPE, AppLock.CHANGE_PIN)
                startActivity(intent)
            } else {
                intent.putExtra(AppLock.EXTRA_TYPE, AppLock.ENABLE_PINLOCK)
                startActivityForResult(intent, 101)
            }
        }
        binding.btnGoToLocked.setOnClickListener {
            // This is simple intent for LockedActivity
            val intent = Intent(this@MainActivity, LockedActivity::class.java)
            startActivity(intent)
        }
        // This is to disable the PinCode 
        binding.btnDisable.setOnClickListener {
            locker.disableAppLock()
            Toast.makeText(this,"Disabled pin code successfully",Toast.LENGTH_LONG).show()
        }
    }
  
    // This is used to get some external calls to our activity 
    // as we are passing some result code for some operations
    // which will send the result and the data by this method
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
  
        when (requestCode) {
            101 -> {
                Toast.makeText(this, "PinCode enabled", Toast.LENGTH_SHORT).show()
            }
        }
    }
}


So let’s design our layout file for this purpose

activity_main.xml

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    tools:context=".MainActivity">
  
    <!-- This is tool bar use to add some 
         header functionality to our app-->
    <Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:background="@color/gfg"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
  
        <!--This is the header textview-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:fontFamily="@font/font_gilroy_bold"
            android:text="@string/str_gfg"
            android:textColor="@color/white"
            android:textSize="24sp" />
    </Toolbar>
  
    <!-- This is button used to add 
         some interaction work-->
    <Button
        android:id="@+id/btn_enable"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="80dp"
        android:layout_marginEnd="24dp"
        android:background="@drawable/ic_btn"
        android:fontFamily="@font/font_gilroy_medium"
        android:text="@string/str_enable_pincode"
        android:textAllCaps="false"
        android:textColor="@color/gfg"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"
        app:layout_constraintVertical_bias="0.0" />
  
    <Button
        android:id="@+id/btn_change_pin"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="80dp"
        android:layout_marginEnd="24dp"
        android:background="@drawable/ic_btn"
        android:fontFamily="@font/font_gilroy_medium"
        android:text="@string/str_set_pin"
        android:textAllCaps="false"
        android:textColor="@color/gfg"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/btn_enable"
        app:layout_constraintVertical_bias="0.0" />
  
    <Button
        android:id="@+id/btn_disable"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="80dp"
        android:layout_marginEnd="24dp"
        android:background="@drawable/ic_btn"
        android:fontFamily="@font/font_gilroy_medium"
        android:text="@string/str_disable"
        android:textAllCaps="false"
        android:textColor="@color/gfg"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/btn_change_pin"
        app:layout_constraintVertical_bias="0.0" />
  
    <Button
        android:id="@+id/btn_go_to_locked"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_marginStart="24dp"
        android:layout_marginEnd="24dp"
        android:background="@drawable/ic_btn"
        android:fontFamily="@font/font_gilroy_medium"
        android:text="@string/str_locked"
        android:textAllCaps="false"
        android:textColor="@color/gfg"
        android:layout_marginTop="80dp"
        android:textSize="16sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/btn_disable"
        app:layout_constraintVertical_bias="0.0" />
  
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="32dp"
        android:src="@drawable/ic_gfg"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_disable"
        app:layout_constraintVertical_bias="1.0" />
    
</androidx.constraintlayout.widget.ConstraintLayout>


and lastly, we will design our locked activity which will be locked after the X seconds which is the timeout time.

LockedActivity

Kotlin




import `in`.kay.gfglollipinapp.databinding.ActivityLockedBinding
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.github.omadahealth.lollipin.lib.PinActivity
import com.github.omadahealth.lollipin.lib.PinCompatActivity
  
class LockedActivity :  PinCompatActivity() {
    private lateinit var binding: ActivityLockedBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding= ActivityLockedBinding.inflate(layoutInflater)
        setContentView(binding.root)
    }
}


and the layout for this activity 

ActivityLocked.xml

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:background="@color/white"
    android:layout_height="match_parent"
    tools:context=".LockedActivity">
  
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/font_gilroy_bold"
        android:text="Unlocked Activity"
        android:textColor="@color/gfg"
        android:textSize="32sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    
</androidx.constraintlayout.widget.ConstraintLayout>


So, here we are ready to go. Run the app now.

Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads