Showing posts with label android sqlite. Show all posts

Android SQLite Tutorial - Kotlin

In this tutorial, we will learn how to implement SQLite Operations in Android with Kotlin. It is similar to the way of implementing SQLite using Java. To learn the basics of Kotlin click here.

Project Setup:

Create new Project with Kotlin Support in Android Studio 3.0 or If you are using Android Studio version below 3.0 then setup Kotlin Plugin.

Coding Part

Create a kotlin class named as Tasks.kt and paste the following code
class Tasks {

    var id: Int = 0
    var name: String = ""
    var desc: String = ""
    var completed: String = "N"

}
DatabaseHandler
Create a Kotlin class named as DatabaseHandler.kt. It is used to Handle the database operations of SQLite with Kotlin. The Parent of this class is SQLiteOpenHelper. Paste the following code in DatabaseHandler.kt
class DatabaseHandler(context: Context) : SQLiteOpenHelper(context, DatabaseHandler.DB_NAME, null, DatabaseHandler.DB_VERSION) {

    override fun onCreate(db: SQLiteDatabase) {
        val CREATE_TABLE = "CREATE TABLE $TABLE_NAME ($ID INTEGER PRIMARY KEY, $NAME TEXT,$DESC TEXT,$COMPLETED TEXT);"
        db.execSQL(CREATE_TABLE)
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        val DROP_TABLE = "DROP TABLE IF EXISTS $TABLE_NAME"
        db.execSQL(DROP_TABLE)
        onCreate(db)
    }
}

CRUD Operations of SQLite

Now we need to write methods for handling all database read and write operations. Here we are implementing following methods for our tasks table.

Insert data to Table
The following code is used to add tasks to SQLite.
fun addTask(tasks: Tasks): Boolean {
 val db = this.writableDatabase
 val values = ContentValues()
 values.put(NAME, tasks.name)
 values.put(DESC, tasks.desc)
 values.put(COMPLETED, tasks.completed)
 val _success = db.insert(TABLE_NAME, null, values)
 db.close()
 Log.v("InsertedId", "$_success")
 return (Integer.parseInt("$_success") != -1)
}
Get all data from Table
The following code is used to get all tasks from SQLite.
fun task(): List {
 val taskList = ArrayList()
 val db = writableDatabase
 val selectQuery = "SELECT  * FROM $TABLE_NAME"
 val cursor = db.rawQuery(selectQuery, null)
 if (cursor != null) {
  if (cursor.moveToFirst()) {
   do {
    val tasks = Tasks()
    tasks.id = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ID)))
    tasks.name = cursor.getString(cursor.getColumnIndex(NAME))
    tasks.desc = cursor.getString(cursor.getColumnIndex(DESC))
    tasks.completed = cursor.getString(cursor.getColumnIndex(COMPLETED))
    taskList.add(tasks)
   } while (cursor.moveToNext())
  }
 }
 cursor.close()
 return taskList
}
Get particular data from Table
The following code is used to get particular task from SQLite.
fun getTask(_id: Int): Tasks {
 val tasks = Tasks()
 val db = writableDatabase
 val selectQuery = "SELECT  * FROM $TABLE_NAME WHERE $ID = $_id"
 val cursor = db.rawQuery(selectQuery, null)

 cursor?.moveToFirst()
 tasks.id = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ID)))
 tasks.name = cursor.getString(cursor.getColumnIndex(NAME))
 tasks.desc = cursor.getString(cursor.getColumnIndex(DESC))
 tasks.completed = cursor.getString(cursor.getColumnIndex(COMPLETED))
 cursor.close()
 return tasks
}
Update data to Table
The following code is used to update particular task to SQLite.
fun updateTask(tasks: Tasks): Boolean {
 val db = this.writableDatabase
 val values = ContentValues()
 values.put(NAME, tasks.name)
 values.put(DESC, tasks.desc)
 values.put(COMPLETED, tasks.completed)
 val _success = db.update(TABLE_NAME, values, ID + "=?", arrayOf(tasks.id.toString())).toLong()
 db.close()
 return Integer.parseInt("$_success") != -1
}
Delete data from Table
The following code is used to delete particular or all task(s) from SQLite.
// delete particular data
fun deleteTask(_id: Int): Boolean {
 val db = this.writableDatabase
 val _success = db.delete(TABLE_NAME, ID + "=?", arrayOf(_id.toString())).toLong()
 db.close()
 return Integer.parseInt("$_success") != -1
}

// delete all data
fun deleteAllTasks(): Boolean {
 val db = this.writableDatabase
 val _success = db.delete(TABLE_NAME, null, null).toLong()
 db.close()
 return Integer.parseInt("$_success") != -1
}
Full Code of DatabaseHandler
class DatabaseHandler(context: Context) : SQLiteOpenHelper(context, DatabaseHandler.DB_NAME, null, DatabaseHandler.DB_VERSION) {

    override fun onCreate(db: SQLiteDatabase) {
        val CREATE_TABLE = "CREATE TABLE $TABLE_NAME ($ID INTEGER PRIMARY KEY, $NAME TEXT,$DESC TEXT,$COMPLETED TEXT);"
        db.execSQL(CREATE_TABLE)
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        val DROP_TABLE = "DROP TABLE IF EXISTS $TABLE_NAME"
        db.execSQL(DROP_TABLE)
        onCreate(db)
    }

    fun addTask(tasks: Tasks): Boolean {
        val db = this.writableDatabase
        val values = ContentValues()
        values.put(NAME, tasks.name)
        values.put(DESC, tasks.desc)
        values.put(COMPLETED, tasks.completed)
        val _success = db.insert(TABLE_NAME, null, values)
        db.close()
        Log.v("InsertedId", "$_success")
        return (Integer.parseInt("$_success") != -1)
    }

    fun getTask(_id: Int): Tasks {
        val tasks = Tasks()
        val db = writableDatabase
        val selectQuery = "SELECT  * FROM $TABLE_NAME WHERE $ID = $_id"
        val cursor = db.rawQuery(selectQuery, null)

        cursor?.moveToFirst()
        tasks.id = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ID)))
        tasks.name = cursor.getString(cursor.getColumnIndex(NAME))
        tasks.desc = cursor.getString(cursor.getColumnIndex(DESC))
        tasks.completed = cursor.getString(cursor.getColumnIndex(COMPLETED))
        cursor.close()
        return tasks
    }

    fun task(): List {
        val taskList = ArrayList()
        val db = writableDatabase
        val selectQuery = "SELECT  * FROM $TABLE_NAME"
        val cursor = db.rawQuery(selectQuery, null)
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                do {
                    val tasks = Tasks()
                    tasks.id = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ID)))
                    tasks.name = cursor.getString(cursor.getColumnIndex(NAME))
                    tasks.desc = cursor.getString(cursor.getColumnIndex(DESC))
                    tasks.completed = cursor.getString(cursor.getColumnIndex(COMPLETED))
                    taskList.add(tasks)
                } while (cursor.moveToNext())
            }
        }
        cursor.close()
        return taskList
    }

    fun updateTask(tasks: Tasks): Boolean {
        val db = this.writableDatabase
        val values = ContentValues()
        values.put(NAME, tasks.name)
        values.put(DESC, tasks.desc)
        values.put(COMPLETED, tasks.completed)
        val _success = db.update(TABLE_NAME, values, ID + "=?", arrayOf(tasks.id.toString())).toLong()
        db.close()
        return Integer.parseInt("$_success") != -1
    }

    fun deleteTask(_id: Int): Boolean {
        val db = this.writableDatabase
        val _success = db.delete(TABLE_NAME, ID + "=?", arrayOf(_id.toString())).toLong()
        db.close()
        return Integer.parseInt("$_success") != -1
    }

    fun deleteAllTasks(): Boolean {
        val db = this.writableDatabase
        val _success = db.delete(TABLE_NAME, null, null).toLong()
        db.close()
        return Integer.parseInt("$_success") != -1
    }

    companion object {
        private val DB_VERSION = 1
        private val DB_NAME = "MyTasks"
        private val TABLE_NAME = "Tasks"
        private val ID = "Id"
        private val NAME = "Name"
        private val DESC = "Desc"
        private val COMPLETED = "Completed"
    }
}

Add Tasks

The following code is used to call Insert Function in DatabaseHandler
val tasks: Tasks = Tasks()
tasks.name = input_name.text.toString()
tasks.desc = input_desc.text.toString()
if (swt_completed.isChecked)
 tasks.completed = "Y"
else
 tasks.completed = "N"
success = dbHandler?.addTask(tasks) as Boolean

Update Tasks

The following code is used to call update Function in DatabaseHandler
val tasks: Tasks = Tasks()
tasks.id = intent.getIntExtra("Id", 0)
tasks.name = input_name.text.toString()
tasks.desc = input_desc.text.toString()
if (swt_completed.isChecked)
 tasks.completed = "Y"
else
 tasks.completed = "N"
success = dbHandler?.updateTask(tasks) as Boolean

Delete Tasks

The following code is used to call delete Functions in DatabaseHandler
// Delete Task
val success = dbHandler?.deleteTask(intent.getIntExtra("Id", 0)) as Boolean
// Delete All Tasks
dbHandler!!.deleteAllTasks()

Read Tasks

The following code is used to call read Functions in DatabaseHandler
// Read All Tasks
val tasks: Tasks = dbHandler!!.getTask(intent.getIntExtra("Id",0))
// Read Particular Task
dbHandler = DatabaseHandler(this)
listTasks = (dbHandler as DatabaseHandler).task()
In this tutorial, I have used Recyclerview. To implement Recyclerview click here.

Full Code of this tutorial

Create MainActivity.kt and Paste the following code
class MainActivity : AppCompatActivity() {

    var taskRecyclerAdapter: TaskRecyclerAdapter? = null;
    var fab: FloatingActionButton? = null
    var recyclerView: RecyclerView? = null
    var dbHandler: DatabaseHandler? = null
    var listTasks: List = ArrayList()
    var linearLayoutManager: LinearLayoutManager? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initViews()
        initOperations()
        //initDB()
    }

    fun initDB() {
        dbHandler = DatabaseHandler(this)
        listTasks = (dbHandler as DatabaseHandler).task()
        taskRecyclerAdapter = TaskRecyclerAdapter(tasksList = listTasks, context = applicationContext)
        (recyclerView as RecyclerView).adapter = taskRecyclerAdapter
    }

    fun initViews() {
        val toolbar = findViewById(R.id.toolbar) as Toolbar
        setSupportActionBar(toolbar)
        fab = findViewById(R.id.fab) as FloatingActionButton
        recyclerView = findViewById(R.id.recycler_view) as RecyclerView
        taskRecyclerAdapter = TaskRecyclerAdapter(tasksList = listTasks, context = applicationContext)
        linearLayoutManager = LinearLayoutManager(applicationContext)
        (recyclerView as RecyclerView).layoutManager = linearLayoutManager
    }

    fun initOperations() {
        fab?.setOnClickListener { view ->
            val i = Intent(applicationContext, AddOrEditActivity::class.java)
            i.putExtra("Mode", "A")
            startActivity(i)
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.menu_main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        val id = item.itemId
        if (id == R.id.action_delete) {
            val dialog = AlertDialog.Builder(this).setTitle("Info").setMessage("Click 'YES' Delete All Tasks")
                    .setPositiveButton("YES", { dialog, i ->
                        dbHandler!!.deleteAllTasks()
                        initDB()
                        dialog.dismiss()
                    })
                    .setNegativeButton("NO", { dialog, i ->
                        dialog.dismiss()
                    })
            dialog.show()
            return true
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onResume() {
        super.onResume()
        initDB()
    }
}
Create AddOrEditActivity.kt and Paste the following code
class AddOrEditActivity : AppCompatActivity() {

    var dbHandler: DatabaseHandler? = null
    var isEditMode = false

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_add_edit)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        initDB()
        initOperations()
    }

    private fun initDB() {
        dbHandler = DatabaseHandler(this)
        btn_delete.visibility = View.INVISIBLE
        if (intent != null && intent.getStringExtra("Mode") == "E") {
            isEditMode = true
            val tasks: Tasks = dbHandler!!.getTask(intent.getIntExtra("Id",0))
            input_name.setText(tasks.name)
            input_desc.setText(tasks.desc)
            swt_completed.isChecked = tasks.completed == "Y"
            btn_delete.visibility = View.VISIBLE
        }
    }

    private fun initOperations() {
        btn_save.setOnClickListener({
            var success: Boolean = false
            if (!isEditMode) {
                val tasks: Tasks = Tasks()
                tasks.name = input_name.text.toString()
                tasks.desc = input_desc.text.toString()
                if (swt_completed.isChecked)
                    tasks.completed = "Y"
                else
                    tasks.completed = "N"
                success = dbHandler?.addTask(tasks) as Boolean
            } else {
                val tasks: Tasks = Tasks()
                tasks.id = intent.getIntExtra("Id", 0)
                tasks.name = input_name.text.toString()
                tasks.desc = input_desc.text.toString()
                if (swt_completed.isChecked)
                    tasks.completed = "Y"
                else
                    tasks.completed = "N"
                success = dbHandler?.updateTask(tasks) as Boolean
            }

            if (success)
                finish()
        })

        btn_delete.setOnClickListener({
            val dialog = AlertDialog.Builder(this).setTitle("Info").setMessage("Click 'YES' Delete the Task.")
                    .setPositiveButton("YES", { dialog, i ->
                        val success = dbHandler?.deleteTask(intent.getIntExtra("Id", 0)) as Boolean
                        if (success)
                            finish()
                        dialog.dismiss()
                    })
                    .setNegativeButton("NO", { dialog, i ->
                        dialog.dismiss()
                    })
            dialog.show()
        })
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        val id = item.itemId
        if (id == android.R.id.home) {
            finish()
            return true
        }
        return super.onOptionsItemSelected(item)
    }
}

Download Code:

You can the download code for this post from Github. If you like this, tutorial star it on Github.

SQLite Importer Exporter - Library


A light weight library for exporting and importing sqlite database in android

Created By

API

How to Download

Gradle:
compile 'com.ajts.androidmads.sqliteimpex:library:1.0.0'
Maven:
<dependency>
  <groupId>com.ajts.androidmads.sqliteimpex</groupId>
  <artifactId>library</artifactId>
  <version>1.0.0</version>
  <type>pom</type>
</dependency>

How to use this Library:

This Library is used to import SQLite Database from Assets or External path and Export/Backup SQLite Database to external path.
SQLiteImporterExporter sqLiteImporterExporter = new SQLiteImporterExporter(getApplicationContext(), db);

// Listeners for Import and Export DB
sqLiteImporterExporter.setOnImportListener(new SQLiteImporterExporter.ImportListener() {
    @Override
    public void onSuccess(String message) {
        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onFailure(Exception exception) {
        Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_SHORT).show();
    }
});

sqLiteImporterExporter.setOnExportListener(new SQLiteImporterExporter.ExportListener() {
    @Override
    public void onSuccess(String message) {
        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onFailure(Exception exception) {
        Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_SHORT).show();
    }
});

To Import SQLite from Assets

try {
    sqLiteImporterExporter.importDataBaseFromAssets();
} catch (Exception e) {
    e.printStackTrace();
}

To import from external storage

try {
    sqLiteImporterExporter.importDataBase(path);
} catch (Exception e) {
    e.printStackTrace();
}

To export to external storage

try {
    sqLiteImporterExporter.exportDataBase(path);
} catch (Exception e) {
    e.printStackTrace();
}

Download From Github

Room Android Architecture

Android Mads

In Google I/O 2017, Google announced about Room Architecture for Android. This Architecture is used to maintain the State of Android Application when the orientation changes. As well as google announced about Room Architecture.

Room

We have more boiler plates while creating SQLite Database in Android even it is small. Room as a library used to remove the boiler plates like Cursors & Handlers and database can be handled with annotations and model classes. If we remember about Sugar ORM or Active Android, the same approach is dealt with Room. 
We don't want to go for any third party libraries, when the official Android libraries give you an equal, or better solution.

Life Cycle Activity

We have faced the problem mostly as that to maintain the State of Android Application when the orientation changes. The Life Cycle Activity used to handle the state easily.

Coding Part

Create a new project in Android Studio.

First, Add Google’s maven repository to your project-level build.gradle file.
allprojects {
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }
    }
}
Then, Add following dependencies to your app-level build.gradle file.
compile 'android.arch.persistence.room:runtime:1.0.0-alpha1'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0-alpha1'
compile 'android.arch.lifecycle:extensions:1.0.0-alpha1'

Creating the Model

Create a Model class and named as ProductModel.
@Entity
public class ProductModel {

    @PrimaryKey(autoGenerate = true)
    public int itemId;
    private String itemName;
    private String itemQty;
    @TypeConverters(DateConverter.class)
    private Date itemAddedDate;

    public ProductModel(int itemId, String itemName, String itemQty, Date itemAddedDate) {
        this.itemId = itemId;
        this.itemName = itemName;
        this.itemQty = itemQty;
        this.itemAddedDate = itemAddedDate;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public void setItemQty(String itemQty) {
        this.itemQty = itemQty;
    }

    public void setItemAddedDate(Date itemAddedDate) {
        this.itemAddedDate = itemAddedDate;
    }

    public String getItemName() {
        return itemName;
    }

    public String getItemQty() {
        return itemQty;
    }

    public Date getItemAddedDate() {
        return itemAddedDate;
    }

    public int getItemId() {
        return itemId;
    }
}
Here,
  1. @Entity annotation is used to tell the Model Class as Database Table. 
  2. @PrimaryKey annotation is used to set Primary Key for Table and autoGenerate = true is used to set Auto Increment to Primary Key. 
  3. @TypeConverters annotation is used to convert the Date into String and Vice-Versa. The DateConverter is class created by your own as like below.

Creating Type Converter

Create a class and named as DateConverter and Paste the following code.
class DateConverter {

    @TypeConverter
    public static Date toDate(Long timestamp) {
        return timestamp == null ? null : new Date(timestamp);
    }

    @TypeConverter
    public static Long toTimestamp(Date date) {
        return date == null ? null : date.getTime();
    }
}
This Converter is used to convert date to string and vice versa. Because, We cannot save Date format in SQLite Directly.

Creating Data Access Object(DAO)

Create a class and named as ProductModelDao.class and paste the following code.
Here, the Query for storing and retrieving data from Local DB performed.
@Dao
@TypeConverters(DateConverter.class)
public interface ProductModelDao {
    
    @Query("select * from ProductModel")
    LiveData<List<ProductModel>> getAllProducts();

    @Query("select * from ProductModel where itemId = :itemId")
    ProductModel getProductById(int itemId);

    @Insert(onConflict = REPLACE)
    void addProduct(ProductModel ProductModel);

    @Update(onConflict = REPLACE)
    void updateProduct(ProductModel ProductModel);

    @Delete
    void deleteProduct(ProductModel ProductModel);
    
}
  1. @Dao annotation indicate this interface as DAO. 
  2. @Query annotation indicate the data surrounded is Queries to retrieve data from DB. 
  3. @Insert, @Update, @Delete,annotations used to insert, update and delete the data stored in DB respectively. 
  4. onConflict indicates that to replace the data when conflicts occurs while performing the tasks..

Creating Database

Create a abstract class and named as AppDataBase.class and pass the following code.
@Database(entities = {ProductModel.class}, version = 1)
public abstract class AppDataBase extends RoomDatabase {
    private static AppDataBase INSTANCE;

    public static AppDataBase getDatabase(Context context) {
        if (INSTANCE == null) {
            INSTANCE = Room.databaseBuilder(context.getApplicationContext(), AppDataBase.class, "product_db")
                    .build();
        }
        return INSTANCE;
    }

    public static void destroyInstance() {
        INSTANCE = null;
    }

    public abstract ProductModelDao itemAndPersonModel();
}
  1. @Database annotation indicate this class as Database of our Application. 
  2. entities is an array of tables or entities and separated by comma. 
  3. version is used to denote the version of the database.
This class is used to create the database and get an instance of it. We can create the database using
Room.databaseBuilder(context.getApplicationContext(), AppDataBase.class, "product_db")
.build();
Create Android View Model for Retrieving all the data from DB.
public class ProductListViewModel extends AndroidViewModel {

    private final LiveData<List<ProductModel>> itemAndPersonList;
    private AppDataBase appDatabase;

    public ProductListViewModel(Application application) {
        super(application);
        appDatabase = AppDataBase.getDatabase(this.getApplication());
        itemAndPersonList = appDatabase.itemAndPersonModel().getAllProducts();
    }

    public LiveData<List<ProductModel>> getItemAndPersonList() {
        return itemAndPersonList;
    }

    public void deleteItem(ProductModel borrowModel) {
        new deleteAsyncTask(appDatabase).execute(borrowModel);
    }

    private static class deleteAsyncTask extends AsyncTask<ProductModel, Void, Void> {

        private AppDataBase db;
        deleteAsyncTask(AppDataBase appDatabase) {
            db = appDatabase;
        }
        @Override
        protected Void doInBackground(final ProductModel... params) {
            db.itemAndPersonModel().deleteProduct(params[0]);
            return null;
        }

    }

}
Create Android View Model for Retrieve a single data from DB as well as the code update the Data.
public class AddProductViewModel extends AndroidViewModel {

    private AppDataBase appDatabase;

    public AddProductViewModel(Application application) {
        super(application);
        appDatabase = AppDataBase.getDatabase(this.getApplication());
    }

    public void addProduct(final ProductModel borrowModel) {
        new addAsyncTask(appDatabase).execute(borrowModel);
    }

    private static class addAsyncTask extends AsyncTask {

        private AppDataBase db;

        addAsyncTask(AppDataBase appDatabase) {
            db = appDatabase;
        }

        @Override
        protected Void doInBackground(final ProductModel... params) {
            db.itemAndPersonModel().addProduct(params[0]);
            return null;
        }

    }
}
Create Android View Model for Retrieve a insert the Data.
public class UpdateProductViewModel extends AndroidViewModel {

    private AppDataBase appDatabase;

    public UpdateProductViewModel(Application application) {
        super(application);
        appDatabase = AppDataBase.getDatabase(this.getApplication());
    }

    public ProductModel readProduct(final int itemId) {
        try {
            return new readAsyncTask(appDatabase).execute(itemId).get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        return null;
    }

    public void updateProduct(final ProductModel borrowModel) {
        new UpdateProductViewModel.updateAsyncTask(appDatabase).execute(borrowModel);
    }

    private static class updateAsyncTask extends AsyncTask<ProductModel, Void, Void> {

        private AppDataBase db;

        updateAsyncTask(AppDataBase appDatabase) {
            db = appDatabase;
        }

        @Override
        protected Void doInBackground(final ProductModel... params) {
            db.itemAndPersonModel().updateProduct(params[0]);
            return null;
        }

    }

    private static class readAsyncTask extends AsyncTask<Integer, Void, ProductModel> {

        private AppDataBase db;

        readAsyncTask(AppDataBase appDatabase) {
            db = appDatabase;
        }

        @Override
        protected ProductModel doInBackground(final Integer... params) {
            return db.itemAndPersonModel().getProductById(params[0]);
        }
    }
}

Creating Custom Adapter

Create Adapter for Recyclerview and Paste the Following code.
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {

    private List<ProductModel> ProductModelList;
    private View.OnLongClickListener longClickListener;
    private View.OnClickListener clickListener;

    public RecyclerViewAdapter(List<ProductModel> ProductModelList,
                               View.OnLongClickListener longClickListener,
                               View.OnClickListener clickListener) {
        this.ProductModelList = ProductModelList;
        this.longClickListener = longClickListener;
        this.clickListener = clickListener;
    }

    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new RecyclerViewHolder(LayoutInflater.from(parent.getContext())
                .inflate(R.layout.recycler_item, parent, false));
    }

    @Override
    public void onBindViewHolder(final RecyclerViewHolder holder, int position) {
        ProductModel productModel = ProductModelList.get(position);
        holder.itemTextView.setText(productModel.getItemName());
        holder.nameTextView.setText(productModel.getItemQty());
        holder.dateTextView.setText(productModel.getItemAddedDate().toLocaleString().substring(0, 11));
        holder.itemView.setTag(productModel);
        holder.itemView.setOnLongClickListener(longClickListener);
        holder.itemView.setOnClickListener(clickListener);
    }

    @Override
    public int getItemCount() {
        return ProductModelList.size();
    }

    public void addItems(List<ProductModel> ProductModelList) {
        this.ProductModelList = ProductModelList;
        notifyDataSetChanged();
    }

    static class RecyclerViewHolder extends RecyclerView.ViewHolder {
        private TextView itemTextView;
        private TextView nameTextView;
        private TextView dateTextView;

        RecyclerViewHolder(View view) {
            super(view);
            itemTextView = view.findViewById(R.id.itemTextView);
            nameTextView = view.findViewById(R.id.nameTextView);
            dateTextView = view.findViewById(R.id.dateTextView);
        }
    }
}
To use the View models inside our Application, use LifeCycleActivity instead of extending the Activity. and Access the view models by
public class MainActivity extends AppCompatLifeCycleActivity implements View.OnLongClickListener, View.OnClickListener {

    private ProductListViewModel viewModel;
    private RecyclerViewAdapter recyclerViewAdapter;
    private RecyclerView recyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(MainActivity.this, AddActivity.class));
            }
        });
        recyclerView = findViewById(R.id.recyclerView);
        recyclerViewAdapter = new RecyclerViewAdapter(new ArrayList<ProductModel>(), this, this);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        recyclerView.setAdapter(recyclerViewAdapter);

        viewModel = ViewModelProviders.of(this).get(ProductListViewModel.class);

        viewModel.getItemAndPersonList().observe(MainActivity.this, new Observer<List<ProductModel>>() {
            @Override
            public void onChanged(@Nullable List<ProductModel> itemAndPeople) {
                recyclerViewAdapter.addItems(itemAndPeople);
            }
        });

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        AppDataBase.destroyInstance();
    }

    @Override
    public boolean onLongClick(View v) {
        ProductModel productModel = (ProductModel) v.getTag();
        viewModel.deleteItem(productModel);
        return true;
    }

    @Override
    public void onClick(View v) {
        ProductModel productModel = (ProductModel) v.getTag();
        Intent i = new Intent(MainActivity.this, UpdateActivity.class);
        i.putExtra("itemId",productModel.itemId);
        startActivity(i);
    }
}
Here, AppCompatLifeCycleActivity is custom Activity inherited with AppCompatActivity and LifeCycleActivity's feature. Create a class and Named as AppCompatLifeCycleActivity.class and paste the following code.
public class AppCompatLifeCycleActivity extends AppCompatActivity 
                   implements LifecycleRegistryOwner {

    private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);

    @Override
    public LifecycleRegistry getLifecycle() {
        return mRegistry;
    }
}
I did this, because of we cannot use setSupportActionbaras like in AppCompatActivity with NoActionBar Theme. You Can simply use LifeCycleActivitywith WithActionBar Themes.
I have added the Add Product and Update Product Activity Screens in the Samples. You Download in the Download Section. If you have any doubt regarding this, feel free to comment in the comment section.

Download Code

You can download the full source code for this tutorial from the following Github link. If you Like this tutorial, Please star it in Github.

Download From Github

SQLiteToExcel v1.0.1

SQLite2Excel
This is a Light weight Library to Convert SQLite Database to Excel and Convert Excel to SQLite. I have already released version 1.0.0. It is suitable to export SQLite Database to Excel. But, In version 1.0.1 I have Included following features

Features

  1. Added Functionality to Import Excel into SQLite Database.
  2. Added Functionality to Export Blob into Image.
  3. Added Functionality to Export List of tables specified.

Sample App

The sample app in the repository is available on Google Play:
Get it on Google Play

How to Download

Add the following library in your app level gradle file
compile 'com.ajts.androidmads.SQLite2Excel:library:1.0.1'

How to Use

Add Permission to Read External Storage in AndriodManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Export SQLite to Excel

This line is used to save the exported file in default location.
SqliteToExcel sqliteToExcel = new SqliteToExcel(this, "helloworld.db");
This line is used to save the exported file in used preferred location.
SqliteToExcel sqliteToExcel = new SqliteToExcel(this, "helloworld.db", directory_path);
This code snippet is used to Export a single table in a database to Excel Sheet
sqliteToExcel.exportSingleTable("table1", "table1.xls", new SQLiteToExcel.ExportListener() {
     @Override
     public void onStart() {

     }
     @Override
     public void onCompleted(String filePath) {

     }
     @Override
     public void onError(Exception e) {

     }
});
This following code snippet is used to Export a list of table in a database to Excel Sheet
sqliteToExcel.exportSpecificTables(tablesList, "table1.xls", new SQLiteToExcel.ExportListener() {
     @Override
     public void onStart() {

     }
     @Override
     public void onCompleted(String filePath) {

     }
     @Override
     public void onError(Exception e) {

     }
});
This code snippet is used to Export a every table in a database to Excel Sheet
sqliteToExcel.exportAllTables("table1.xls", new SQLiteToExcel.ExportListener() {
     @Override
     public void onStart() {

     }
     @Override
     public void onCompleted(String filePath) {

     }
     @Override
     public void onError(Exception e) {

     }
});

Import Excel into Database

The following snippet is used to initialize the library for Importing Excel
ExcelToSQLite excelToSQLite = new ExcelToSQLite(getApplicationContext(), "helloworld.db");
The following code is used to Import Excel from Assets
excelToSQLite.importFromAsset("assetFileName.xls", new ExcelToSQLite.ImportListener() {
    @Override
    public void onStart() {

    }

    @Override
    public void onCompleted(String dbName) {

    }

    @Override
    public void onError(Exception e) {

    }
});
The following code is used to Import Excel from user directory
excelToSQLite.importFromAsset(directory_path, new ExcelToSQLite.ImportListener() {
    @Override
    public void onStart() {

    }

    @Override
    public void onCompleted(String dbName) {

    }

    @Override
    public void onError(Exception e) {

    }
});
Please Visit the Wiki Link for full Guidance on SQLite2XL(v1.0.1).

Github Wiki Link

You can Download Full source code from Github. If you Like this library, Please star it in Github.

Github Link for Repo

How to use External SQLite DB in Android

How to use External SQLite DB in Android

In this Post, I will explain how to import and use External SQLite DB in Android.
You can import and use SQLite database with the extensions like .db, .db3,sqlite and sqlite3.
The External DB is created with some desktop applications like SQLite Browser, SQLite Converter and so on.
After Generating the DB paste that into your App's assets folder.
Code:
DBHelper.class
Create a class named as DBHelper extending with SQLiteHelper. Paste the following code in that class.
public class DBHelper extends SQLiteOpenHelper {
    Context context;
    String DB_PATH;
    String divider = "/";
    String DB_NAME;

    public DBImporterExporter(Context context, String DB_NAME) {
        super(context, DB_NAME, null, 1);
        this.context = context;
        this.DB_NAME = DB_NAME;
        DB_PATH = divider + "data" + divider + "data" + divider + context.getPackageName() + divider + "databases/";
    }

    public boolean isDataBaseExists() {
        File dbFile = new File(DB_PATH + DB_NAME);
        return dbFile.exists();
    }

    public void importDataBaseFromAssets() throws IOException {

        this.getReadableDatabase();

        InputStream myInput = context.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream myOutput = new FileOutputStream(outFileName);
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
        Toast.makeText(context.getApplicationContext(), "Successfully Imported", Toast.LENGTH_SHORT).show();
        // Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();

    }

    @Override
    public void onCreate(SQLiteDatabase arg0) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
    }
 
}
The DB is Imported by using the following code
DBImporterExporter dbImporterExporter = new DBImporterExporter(getApplicationContext(), "external_db_android.sqlite");
 try {
  dbImporterExporter.importDataBaseFromAssets();
    } catch (IOException e) {
  e.printStackTrace();
}
To Check the Existence of DB use the following snippet in your class
dbImporterExporter.isDataBaseExists()
Download Source Code



Having trouble while using this code or any doubt, comment me