Skip to main content

Create a lock screen inside Android application

http://www.devexchanges.info/2017/02/create-lock-screen-inside-android.html



Like some application which focuses on the protection of user data, if we would like to access content, we must enter password first. This lock screen always show every time we open the app, ensure that strangers cannot access your data. Maybe in some cases to protect user information, developer can use this way.

    In this post, I will make a lock activity by designing in XML. There is an another solution is using a third-party library, please read my previous post

Designing layout for lock activity

    User must input number-password to pass this lock screen, so design a keypad for this activity like this: 
activity_lock.xml 
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/activity_horizontal_margin"
    tools:context="info.devexchanges.lockscreen.LockActivity">

    <LinearLayout
        android:id="@+id/lock_keypad"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/btn1"
                style="@style/Borderless_Button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="1" />

            <Button
                android:id="@+id/btn2"
                style="@style/Borderless_Button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="2" />

            <Button
                android:id="@+id/btn3"
                style="@style/Borderless_Button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="3" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/btn4"
                style="@style/Borderless_Button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="4" />

            <Button
                android:id="@+id/btn5"
                style="@style/Borderless_Button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="5" />

            <Button
                android:id="@+id/btn6"
                style="@style/Borderless_Button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="6" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/btn7"
                style="@style/Borderless_Button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="7" />

            <Button
                android:id="@+id/btn8"
                style="@style/Borderless_Button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="8" />

            <Button
                android:id="@+id/btn9"
                style="@style/Borderless_Button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="9" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/btn_space"
                style="@style/Borderless_Button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:enabled="false" />

            <Button
                android:id="@+id/btn0"
                style="@style/Borderless_Button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="0" />

            <ImageView
                android:id="@+id/btn_clear"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:contentDescription="@null"
                android:src="@android:drawable/ic_input_delete"
                android:tint="@color/colorPrimary" />
        </LinearLayout>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/dot_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@id/lock_keypad"
        android:layout_marginBottom="@dimen/activity_horizontal_margin"
        android:gravity="center"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/dot_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@null"
            android:src="@drawable/dot_disable" />

        <ImageView
            android:id="@+id/dot_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@null"
            android:src="@drawable/dot_disable" />

        <ImageView
            android:id="@+id/dot_3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@null"
            android:src="@drawable/dot_disable" />

        <ImageView
            android:id="@+id/dot_4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@null"
            android:src="@drawable/dot_disable" />

    </LinearLayout>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/dot_layout"
        android:layout_centerInParent="true"
        android:layout_marginBottom="@dimen/activity_horizontal_margin"
        android:src="@drawable/lock" />

</RelativeLayout>
    Expected output: 
    Now, you must have a main activity, it's will start when launching app. It's layout depend on your work, in this simple project, it only include a TextView
activity_main.xml 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="info.devexchanges.lockscreen.MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="@dimen/activity_horizontal_margin"
        android:text="Hello World!" />
</LinearLayout>

Main activity programmatically code

     Because the lock screen always display when app launching, so in onStart() of MainActivity, we'll check if users haven't typed true before, starting LockActivityimmediately by Intent! In order to detect users passed the lock screen or not, we'll use SharedPreferences. Source code simple like this: 
MainActivity.java 
package info.devexchanges.lockscreen;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.TextView;

import butterknife.BindView;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.toolbar)
    Toolbar toolbar;

    @BindView(R.id.text)
    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        setSupportActionBar(toolbar);
    }

    @SuppressLint("SetTextI18n")
    @Override
    protected void onStart() {
        super.onStart();
        if (!isPass()) {
            Intent intent = new Intent(this, LockActivity.class);
            startActivity(intent);
        } else {
            textView.setText("The code you typed is right!");
        }
    }

    private boolean isPass() {
        SharedPreferences prefs = getSharedPreferences("PASS_CODE", MODE_PRIVATE);
        return prefs.getBoolean("is_pass", false);
    }

    @Override
    protected void onStop() {
        super.onStop();

        SharedPreferences.Editor editor = getSharedPreferences("PASS_CODE", MODE_PRIVATE).edit();
        editor.putBoolean("is_pass", false);
        editor.apply();
    }
}
As you can see, we must remove password when the main activity closed (by override onStop()to guaranteed that the lock activity always shown when app resumed! 

Lock activity programmatically code

    In this activity, we must:
  • Handle click event of all buttons in the keypad (to get input code - password)
  • Update dots layout when input code changed
  • Check input code right or wrong. If right, return to the main activity and if wrong, show a Toast to warning.
    And this is it's source code: 
LockActivity.java 
package info.devexchanges.lockscreen;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.util.List;

import butterknife.BindViews;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class LockActivity extends AppCompatActivity {

    @BindViews({R.id.btn0, R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4, R.id.btn5, R.id.btn6,
            R.id.btn7, R.id.btn8, R.id.btn9, R.id.btn_clear})
    List<View> btnNumPads;

    @BindViews({R.id.dot_1, R.id.dot_2, R.id.dot_3, R.id.dot_4})
    List<ImageView> dots;

    private static final String TRUE_CODE = "2869";
    private static final int MAX_LENGHT = 4;
    private String codeString = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_lock);
        ButterKnife.bind(this);
    }

    @OnClick(R.id.btn_clear)
    public void onClear() {
        if (codeString.length() > 0) {
            //remove last character of code
            codeString = removeLastChar(codeString);

            //update dots layout
            setDotImagesState();
        }
    }

    @OnClick({R.id.btn0, R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4, R.id.btn5, R.id.btn6,
            R.id.btn7, R.id.btn8, R.id.btn9})
    public void onClick(Button button) {
        getStringCode(button.getId());
        if (codeString.length() == MAX_LENGHT) {
            if (codeString.equals(TRUE_CODE)) {
                Toast.makeText(this, "Code is right", Toast.LENGTH_SHORT).show();
                setIsPass();
                finish();
            } else {
                Toast.makeText(this, "Wrong Pass code", Toast.LENGTH_SHORT).show();
                //vibrate the dots layout
                shakeAnimation();
            }
        } else if (codeString.length() > MAX_LENGHT){
            //reset the input code
            codeString = "";
            getStringCode(button.getId());
        }
        setDotImagesState();
    }

    private void shakeAnimation() {
        Animation shake = AnimationUtils.loadAnimation(this, R.anim.vibrate_anim);
        findViewById(R.id.dot_layout).startAnimation(shake);
        Toast.makeText(this, "Wrong Password", Toast.LENGTH_SHORT).show();
    }

    private void getStringCode(int buttonId) {
        switch (buttonId) {
            case R.id.btn0:
                codeString += "0";
                break;
            case R.id.btn1:
                codeString += "1";
                break;
            case R.id.btn2:
                codeString += "2";
                break;
            case R.id.btn3:
                codeString += "3";
                break;
            case R.id.btn4:
                codeString += "4";
                break;
            case R.id.btn5:
                codeString += "5";
                break;
            case R.id.btn6:
                codeString += "6";
                break;
            case R.id.btn7:
                codeString += "7";
                break;
            case R.id.btn8:
                codeString += "8";
                break;
            case R.id.btn9:
                codeString += "9";
                break;
            default:
                break;
        }
    }

    private void setDotImagesState() {
        for (int i = 0; i < codeString.length(); i++) {
            dots.get(i).setImageResource(R.drawable.dot_enable);
        }
        if (codeString.length()<4) {
            for (int j = codeString.length(); j<4; j++) {
                dots.get(j).setImageResource(R.drawable.dot_disable);
            }
        }
    }

    private String removeLastChar(String s) {
        if (s == null || s.length() == 0) {
            return s;
        }
        return s.substring(0, s.length() - 1);
    }

    private void setIsPass() {
        SharedPreferences.Editor editor = getSharedPreferences("PASS_CODE", MODE_PRIVATE).edit();
        editor.putBoolean("is_pass", true);
        editor.apply();
    }
}
    This is output when app running: 

Shaking animation

    As you see at the output video, when user type a wrong code, the dots layout will be shake. This is xml file to make this animation: 
res\anim\shake_anim.xml 
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:duration="70"
        android:fromDegrees="-5"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="5"
        android:repeatMode="reverse"
        android:interpolator="@android:anim/linear_interpolator"
        android:toDegrees="5" />
    <translate
        android:fromXDelta="-10"
        android:toXDelta="10"
        android:repeatCount="5"
        android:repeatMode="reverse"
        android:interpolator="@android:anim/linear_interpolator"
        android:duration="70" />
</set>
    And this is output:

    You can make other better animation than this by research more about animation in Android
     In this project, I use ButterKnife to make finViewbyId work become easier! In order to use this library, please add this dependency to your app-level build.gradle
compile 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'

Conclusions

    Make a lock screen inside your own application is a not hard work, you can design it better and should pay attention to developing animation and further, vibrating device when user type a wrong code! The fact that there are many third-party libraries which can help you make this layout without write XML codes yourself. Please read my previous post to learn about using one of them. Finally, you can get full project code on Github

Comments

Popular posts from this blog

web2apk

http://web2apk.com/create.aspx Create App   Intro   About   Changes   MalWare ?   Contact   Privacy Useful Links Bluetooth Mini Keyboards Android Mini PC Reset Android URL App Title Icon or

Android Bar Chart Using MpAndroidChart Library Tutorial

https://www.numetriclabz.com/android-bar-chart-using-mpandroidchart-library-tutorial/ Android Bar Chart Using MpAndroidChart Library Tutorial Objective In this tutorial we learn how to implement Bar Chart using MpAndroidChart Library in your Android App. Download Source Code       Step 1 Contents ·        1  Introduction ·        2  Creating Bar chart o    2.1  Create a new Project o    2.2  Adding library in Project o    2.3  Create Layout o    2.4  To Plot Bar Chart §   2.4.1  Initialize the graph id §   2.4.2  Creating a Dataset §   2.4.3  Defining X-axis labels §   2.4.4  Set the data §   2.4.5  Add the description to the chart §   2.4.6  Run your App § ...

how to retrieve image from sqlite database in android and display in listview

 Android platform provides several ways to store data in our application. 1. SQLite database 2. SharedPreferences etc For our post, we will only work with SQLite database. First and foremost, we need to understand what an SQLite database is? SQLite database  is an open source SQL database that stores data to a text file on a device. It executes SQL Commands to perform a set of functions, that is, create, read, update and delete operations. On my previous post, I showed how to  store data in SQLite database from edit text, retrieve and populate it in a listview . For this post, I will show the SQLite CRUD operations with images from gallery and text from EditText. We need to understand this; images are stored in SQLite database as BLOB data type. A BLOB is a large binary object that can hold a variable amount of data.  Note, we can only store images in the database as BLOB data type. We need to convert our image path to a bitmap th...