Kotlin SQLite CRUD Operation Android Example Tutorial

kotlin splash screen, kotlin listview searchview, kotlin app intro slider, kotlin webview with progress bar, kotlin webview back forward navigation, kotlin parse json from url, kotlin login register android, kotlin upload image from gallery, kotlin upload image from camera, kotlin sqlite database, kotlin sqlite crud

This is about Kotlin SQLite CRUD Operation Android Example Tutorial.

In this tutorial, you will learn how to insert and retrieve data from sqlite database in android using Kotlin.

CRUD Operations stands for create (store), read, update and delete data in the SQLite database with kotlin in android studio.

After retrieving the data from SQLite database, we will show or display them into the listview.

If you are beginner and do not know the basics of SQLite then read Kotlin SQLite tutorial With Example Android which is the simple tutorial.

First of all, check the following video to see the result of this example tutorial.

 

Step 1. Making a new Project

As always, our first task is to make a new project in the android studio with empty activity as the default one.

Also, set the Kotlin as the main or primary language for the android project.

Step 2. Database Configurations

We are creating a special class that will take care about sqlite configurations.

So go on and make a new kotlin class and give it a name like DatabaseHelper.kt

You need to write the below code in DatabaseHelper.kt class.

import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.util.Log

import java.util.ArrayList

/**
 * Created by Parsania Hardik on 11/01/2016.
 */
class DatabaseHelper(context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {

    // looping through all rows and adding to list
    // adding to Students list
    val getAllUsers: ArrayList<UserModel>
        get() {
            val userModelArrayList = ArrayList<UserModel>()

            val selectQuery = "SELECT  * FROM $TABLE_USER"
            val db = this.readableDatabase
            val c = db.rawQuery(selectQuery, null)
            if (c.moveToFirst()) {
                do {
                    val userModel = UserModel()
                    userModel.setIds(c.getInt(c.getColumnIndex(KEY_ID)))
                    userModel.setNames(c.getString(c.getColumnIndex(KEY_FIRSTNAME)))
                    userModel.setHobbys(c.getString(c.getColumnIndex(KEY_HOBBY)))
                    userModelArrayList.add(userModel)
                } while (c.moveToNext())
            }
            return userModelArrayList
        }

    init {

        Log.d("table", CREATE_TABLE_STUDENTS)
    }

    override fun onCreate(db: SQLiteDatabase) {
        db.execSQL(CREATE_TABLE_STUDENTS)
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        db.execSQL("DROP TABLE IF EXISTS '$TABLE_USER'")
        onCreate(db)
    }

    fun addUserDetail(name: String, hobby: String): Long {
        val db = this.writableDatabase
        // Creating content values
        val values = ContentValues()
        values.put(KEY_FIRSTNAME, name)
        values.put(KEY_HOBBY, hobby)
        // insert row in students table

        return db.insert(TABLE_USER, null, values)
    }

    fun updateUser(id: Int, name: String, hobby: String): Int {
        val db = this.writableDatabase

        // Creating content values
        val values = ContentValues()
        values.put(KEY_FIRSTNAME, name)
        values.put(KEY_HOBBY, hobby)
        // update row in students table base on students.is value
        return db.update(
            TABLE_USER, values, "$KEY_ID = ?",
            arrayOf(id.toString())
        )
    }

    fun deleteUSer(id: Int) {

        // delete row in students table based on id
        val db = this.writableDatabase
        db.delete(
            TABLE_USER, "$KEY_ID = ?",
            arrayOf(id.toString())
        )
    }

    companion object {

        var DATABASE_NAME = "user_database"
        private val DATABASE_VERSION = 1
        private val TABLE_USER = "users"
        private val KEY_ID = "id"
        private val KEY_FIRSTNAME = "name"
        private val KEY_HOBBY = "hobby"


        /*CREATE TABLE students ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, phone_number TEXT......);*/

        private val CREATE_TABLE_STUDENTS = ("CREATE TABLE "
                + TABLE_USER + "(" + KEY_ID
                + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_FIRSTNAME + " TEXT, " + KEY_HOBBY + " TEXT );")
    }

}

More details

See the below block first

 companion object {

        var DATABASE_NAME = "user_database"
        private val DATABASE_VERSION = 1
        private val TABLE_USER = "users"
        private val KEY_ID = "id"
        private val KEY_FIRSTNAME = "name"
        private val KEY_HOBBY = "hobby"


        /*CREATE TABLE students ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, phone_number TEXT......);*/

        private val CREATE_TABLE_STUDENTS = ("CREATE TABLE "
                + TABLE_USER + "(" + KEY_ID
                + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_FIRSTNAME + " TEXT, " + KEY_HOBBY + " TEXT );")
    }

String variables like DATABASE_NAME, DATABASE_VERSION, TABLE_USER etc. are holding the name of the database, version of the database, name of the table, column names etc.

A variable CREATE_TABLE_STUDENTS is making a SQL query to create a new table into SQLite database.

Now see the below code

 fun addUserDetail(name: String, hobby: String): Long {
        val db = this.writableDatabase
        // Creating content values
        val values = ContentValues()
        values.put(KEY_FIRSTNAME, name)
        values.put(KEY_HOBBY, hobby)
        // insert row in students table

        return db.insert(TABLE_USER, null, values)
    }

Above method will insert the record into the database. This method is getting two string variables in the parameter.

One is name and another is hobby. Our table have two columns and their names also name and hobby.

So, this method will add the records as name in the name column and hobby in the hobby column.

Now focus on the following

  val getAllUsers: ArrayList<UserModel>
        get() {
            val userModelArrayList = ArrayList<UserModel>()

            val selectQuery = "SELECT  * FROM $TABLE_USER"
            val db = this.readableDatabase
            val c = db.rawQuery(selectQuery, null)
            if (c.moveToFirst()) {
                do {
                    val userModel = UserModel()
                    userModel.setIds(c.getInt(c.getColumnIndex(KEY_ID)))
                    userModel.setNames(c.getString(c.getColumnIndex(KEY_FIRSTNAME)))
                    userModel.setHobbys(c.getString(c.getColumnIndex(KEY_HOBBY)))
                    userModelArrayList.add(userModel)
                } while (c.moveToNext())
            }
            return userModelArrayList
        }

    init {

        Log.d("table", CREATE_TABLE_STUDENTS)
    }

This method will simply fetch all the records from the database. This method will create one arraylist which have the objects of the UserModel class. (We will create this UserModel class later)

It will store each row details in one separate UserModel object and it will combine all these objects into the arraylist.

Below is the code for updateUser() method.

  fun updateUser(id: Int, name: String, hobby: String): Int {
        val db = this.writableDatabase

        // Creating content values
        val values = ContentValues()
        values.put(KEY_FIRSTNAME, name)
        values.put(KEY_HOBBY, hobby)
        // update row in students table base on students.is value
        return db.update(
            TABLE_USER, values, "$KEY_ID = ?",
            arrayOf(id.toString())
        )
    }

This method is for updating the existing row into the database table. This method is getting id , name and hobby into the parameter.

Id will help the compiler to find which row it needs to update. It will simply replace the existing value of name and hobby with the new ones.

Follow the below function

 fun deleteUSer(id: Int) {

        // delete row in students table based on id
        val db = this.writableDatabase
        db.delete(
            TABLE_USER, "$KEY_ID = ?",
            arrayOf(id.toString())
        )
    }

This function is for deleting the particular row from the database.

An id is there into the parameter. Compiler will find the row with the help of the id and will simply delete it.

See the following methods

 override fun onCreate(db: SQLiteDatabase) {
        db.execSQL(CREATE_TABLE_STUDENTS)
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        db.execSQL("DROP TABLE IF EXISTS '$TABLE_USER'")
        onCreate(db)
    }

Both these methods are important. If you wish to have some more information about these methods then read Kotlin Android SQLite Database tutorial With Example

Step 3. Model and XML file for Listview

Make a new Kotlin file and give it a name like UserModel.kt

Following is the source lines for UserModel.kt

import java.io.Serializable

class UserModel : Serializable {

    var name: String? = null
    var hobby: String? = null
    var id: Int = 0

    fun getIds(): Int {
        return id
    }

    fun setIds(id: Int) {
        this.id = id
    }

    fun getNames(): String {
        return name.toString()
    }

    fun setNames(name: String) {
        this.name = name
    }

    fun getHobbys(): String {
        return hobby.toString()
    }

    fun setHobbys(hobby: String) {
        this.hobby = hobby
    }

}

Our database table have three columns like id, name and hobby. So we are making three variables in the above class.

I have also created getter and setter methods for all these three variables. These methods will help us to maintain data in the listview.

Now, in the app->res->layout directory, create a new XML file named lv_item.xml and add the below in it

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#000"
        android:orientation="vertical">

         <TextView
            android:id="@+id/name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
             android:textColor="#fff"
             android:layout_marginTop="10dp"
            android:gravity="center_vertical"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:paddingLeft="10dp"
            android:text="Name" />
        <TextView
            android:id="@+id/hobby"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#fff"
            android:gravity="center_vertical"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:paddingLeft="10dp"
            android:text="Hobby" />


    </LinearLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:background="@color/colorAccent"/>

</LinearLayout>

This xml file is for the look and feel of rows of the listview.

Every listview row will be created using this file’s layout.

Step 4. Writing Adapter

Make another Kotlin class with the name like CustomAdapter.kt

Below is the source snippet for CustomAdapter.kt file.

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView

import java.util.ArrayList

/**
 * Created by Parsania Hardik on 26-Apr-17.
 */
class CustomAdapter(private val context: Context, private val userModelArrayList: ArrayList<UserModel>) :
    BaseAdapter() {


    override fun getCount(): Int {
        return userModelArrayList.size
    }

    override fun getItem(position: Int): Any {
        return userModelArrayList[position]
    }

    override fun getItemId(position: Int): Long {
        return 0
    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        var convertView = convertView
        val holder: ViewHolder

        if (convertView == null) {
            holder = ViewHolder()
            val inflater = context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            convertView = inflater.inflate(R.layout.lv_item, null, true)

            holder.tvname = convertView!!.findViewById(R.id.name) as TextView
            holder.tvcountry = convertView.findViewById(R.id.hobby) as TextView


            convertView.tag = holder
        } else {
            // the getTag returns the viewHolder object set as a tag to the view
            holder = convertView.tag as ViewHolder
        }

        holder.tvname!!.text = "Name: " + userModelArrayList[position].getNames()
        holder.tvcountry!!.text = "Hobby: " + userModelArrayList[position].getHobbys()

        return convertView
    }

    private inner class ViewHolder {

         var tvname: TextView? = null
         var tvcountry: TextView? = null
    }

}

This file is the adapter for the listview. After fetching all the records from the sqlite database, we will show them into the listview.

Adapter will set the data into the every row of the listview.

Look at the getView() method in the above adapter class. This method is setting the lv_item.xml as the view for the row layout.

After this, it is finding the two text views and it will set their values using usersModelArralist.

Step 5. Displaying All the Records

Let us create a new activity and set it’s name as GetAllUsersActivity

One file will be there : activity_get_all_users.xml and set it’s code as the below

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:background="@color/colorAccent"
              android:orientation="vertical">

    <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:layout_marginTop="10dp"
            android:textSize="20sp"
            android:textColor="#000"
            android:text="Data from SQLite"/>

    <ListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/lv">


    </ListView>

</LinearLayout>

It has one text view and one listview.

Now write down the below code lines in GetAllUsersActivity.kt

import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.ListView
import java.util.ArrayList

class GetAllUsersActivity : AppCompatActivity() {

    private var listView: ListView? = null
    private var userModelArrayList: ArrayList<UserModel>? = null
    private var customAdapter: CustomAdapter? = null
    private var databaseHelper: DatabaseHelper? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_get_all_users)

        listView = findViewById(R.id.lv) as ListView

        databaseHelper = DatabaseHelper(this)

        userModelArrayList = databaseHelper!!.getAllUsers

        customAdapter = CustomAdapter(this, this!!.userModelArrayList!!)
        listView!!.adapter = customAdapter

        listView!!.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
            val intent = Intent(this@GetAllUsersActivity, UpdateDeleteActivity::class.java)
            intent.putExtra("user", userModelArrayList!![position])
            startActivity(intent)
        }
    }
}

Compiler will first create the objects of listview, CustomAdapter and Database helper classes. It will also create an arraylist with the objects of the UserModel class.

Then it will execute the getAllUsers() function with the help of the Database helper object. This function will fetch all the records and it will store them into the userModelArraylist.

Using this userModelArraylist ,compiler will create the object of the adapter and it will bind it to the listview.

When the user clicks on the listview, it will open a new activity called UpdateDeleteActivity

Step 6. Updating or Deleting SQLite

Let us make a new activity and give it a name as UpdateDeleteActivity

Below is the block for activity_update_delete.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:background="@color/colorAccent"
              android:orientation="vertical">

    <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Name"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:textColor="#000"
            android:textSize="20sp"/>
    <EditText
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:id="@+id/etname"
            android:background="#fff"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginRight="10dp"
            android:hint="Enter Name"/>
    <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Hobby"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:textColor="#000"
            android:textSize="20sp"/>
    <EditText
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:id="@+id/ethobby"
            android:background="#fff"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginRight="10dp"
            android:hint="Enter Hobby"/>

    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_marginLeft="10dp"
            android:id="@+id/btnupdate"
            android:text="update"/>
    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_marginLeft="10dp"
            android:id="@+id/btndelete"
            android:text="delete"/>


</LinearLayout>

This file has two text views , two edit texts and two buttons.

One button is for updating the record and another one is for deleting the row.

Now add the following source code in UpdateDeleteActivity.kt

import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.Toast

class UpdateDeleteActivity : AppCompatActivity() {

    private var userModel: UserModel? = null
    private var etname: EditText? = null
    private var ethobby: EditText? = null
    private var btnupdate: Button? = null
    private var btndelete: Button? = null
    private var databaseHelper: DatabaseHelper? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_update_delete)

        val intent = intent
        userModel = intent.getSerializableExtra("user") as UserModel

        databaseHelper = DatabaseHelper(this)

        etname = findViewById(R.id.etname) as EditText
        ethobby = findViewById(R.id.ethobby) as EditText
        btndelete = findViewById(R.id.btndelete) as Button
        btnupdate = findViewById(R.id.btnupdate) as Button

        etname!!.setText(userModel!!.getNames())
        ethobby!!.setText(userModel!!.getHobbys())

        btnupdate!!.setOnClickListener {
            databaseHelper!!.updateUser(userModel!!.getIds(), etname!!.text.toString(), ethobby!!.text.toString())
            Toast.makeText(this@UpdateDeleteActivity, "Updated Successfully!", Toast.LENGTH_SHORT).show()
            val intent = Intent(this@UpdateDeleteActivity, MainActivity::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
            startActivity(intent)
        }

        btndelete!!.setOnClickListener {
            databaseHelper!!.deleteUSer(userModel!!.getIds())
            Toast.makeText(this@UpdateDeleteActivity, "Deleted Successfully!", Toast.LENGTH_SHORT).show()
            val intent = Intent(this@UpdateDeleteActivity, MainActivity::class.java)
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
            startActivity(intent)
        }

    }
}

When the user comes to this activity, compiler will set the name and hobby into the edit text.

If user wants to update the record, he can change the value of the edit texts and then click on the Update button.

And if user wants to delete the record then he needs to simply click the Delete button.

For updating the record, compiler will call the updateUser() function with the help of Database Helper object.

Similarly for deleting the user, it will call deleteUser() method.

Step 7. Last and Main Step

Let us write last but main activity. There should be two files when you created a new project : activity_main.xml and MainActivity.kt

Here is the coding for activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
              android:background="@color/colorAccent">

    <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textColor="#fff"
            android:textSize="20sp"
            android:layout_marginTop="10dp"
            android:text="Enter Name, Hobby to store in SQLite" />

    <EditText
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:id="@+id/etname"
            android:background="#fff"
            android:layout_marginTop="20dp"
            android:layout_marginLeft="20dp"
            android:hint="Enter Name"/>

    <EditText
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:id="@+id/ethobby"
            android:background="#fff"
            android:layout_marginTop="20dp"
            android:layout_marginLeft="20dp"
            android:hint="Enter Hobby"/>

    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/btnstore"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="10dp"
            android:text="Store"/>
    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/btnget"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="10dp"
            android:text="Get All Users from SQLite"/>

</LinearLayout>

Some UI widgets line two edit texts, two buttons and one text view is there.

Now add the following source lines for MainActivity.kt

import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.Toast

class MainActivity : AppCompatActivity() {

    private var btnStore: Button? = null
    private var btnGetall: Button? = null
    private var etname: EditText? = null
    private var ethobby: EditText? = null
    private var databaseHelper: DatabaseHelper? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        databaseHelper = DatabaseHelper(this)

        btnStore = findViewById(R.id.btnstore) as Button
        btnGetall = findViewById(R.id.btnget) as Button
        etname = findViewById(R.id.etname) as EditText
        ethobby = findViewById(R.id.ethobby) as EditText

        btnStore!!.setOnClickListener {
            databaseHelper!!.addUserDetail(etname!!.text.toString(), ethobby!!.text.toString())
            etname!!.setText("")
            ethobby!!.setText("")
            Toast.makeText(this@MainActivity, "Stored Successfully!", Toast.LENGTH_SHORT).show()
        }

        btnGetall!!.setOnClickListener {
            val intent = Intent(this@MainActivity, GetAllUsersActivity::class.java)
            startActivity(intent)
        }

    }
}

Compiler will first create the objects of edit text, button and database helper class.

User can enter name and hobby into two different edit texts.

When the user clicks Store button, compiler will call addUserDetail() function from DatabaseHelper class. This function will insert the record into the database.

Then compiler will clear both the edit texts.

When the user clicks the Get All Users button, compiler will simply open the GetAllUsersActivity.

Download Code For Kotlin SQLite CRUD Example

https://github.com/demonuts/Kotlin-SQLite-CRUD-Operation-Android-Example-Tutorial