Showing posts with label 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.

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.0

SQLite2Excel
SQLiteToExcel is a Light weight Library to Convert SQLite Database to Excel. I have Released Newer Version for this Library. If your Requirement is only to export your SQLite Database, then this library is very much suitable. Otherwise you requirement is to import or export excel to db or vice-versa, then you go for my newer release. Please visit here to see about SQLite2XL Version 1.0.1

How to Download

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

How to Use

1.AndroidManifest.xml
Add the following line in your Manifest file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2.Library Initialization 
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);
3.Export DB to Excel 
This code snippet is used to Export a single table in a database to Excel Sheet
sqliteToExcel.startExportSingleTable("table1", "table1.xls", new ExportListener() {
   
 @Override
 public void onStart() {
  
 }
   
 @Override
 public void onError() {
  
 }
   
 @Override
 public void onComplete() {
  
 }
});
This code snippet is used to Export a every table in a database to Excel Sheet
sqliteToExcel.startExportAllTables("helloworlddb.xls", new ExportListener() {
   
 @Override
 public void onStart() {
  
 }
   
 @Override
 public void onError() {
  
 }
   
 @Override
 public void onComplete() {
  
 }
});
Please Visit the Wiki Link for full Guidance on SQLite2XL(v1.0.0). If you Like this library, Please star it in Github.

Github Wiki Link

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

CRUD Operation using Active Android

CRUD Operation using Active Android
Hello friends, today we will see a simple CRUD Example in Android using Active Android Library.This is a perfect alternate for SQLite in Android.

About Active Android

ActiveAndroid is an active record style ORM (object relational mapper). What does that mean exactly? Well, ActiveAndroid allows you to save and retrieve SQLite database records without ever writing a single SQL statement. ActiveAndroid takes care of all the setup for Accessing the database in android.

Project Setup

In the project you just created go to the app level build.gradle file and add these lines.
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'

    //Add this line
    compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
}

repositories {
    jcenter()
    //Add these two lines
    mavenCentral()
    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}

AndroidManifest.xml
Don't forget to add the following lines in your manifest fileAdd the following lines to initialize the ActiveAndroid.
<meta-data
    android:name="AA_DB_NAME"
    android:value="test.db" />
<meta-data
    android:name="AA_DB_VERSION"
    android:value="5" />
<meta-data
    android:name="AA_MODELS"
    android:value="com.androidmads.actvieandroidexample.Details" />
Create a class named MyApplication to initialize ActiveAndroid library. Add this Class in manifest file within application tag.
package com.androidmads.actvieandroidexample.app;

import android.app.Application;
import com.activeandroid.ActiveAndroid;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        //Initializing Active Android
        ActiveAndroid.initialize(this);
    }
}
Create a Model class for Each table extended with activeandroid
package com.androidmads.actvieandroidexample;

import com.activeandroid.Model;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;

/**
 * Created by Mushtaq on 27-05-2016.
 */
@Table(name = "Details")
public class Details extends Model {

    @Column(name = "Name")
    public String name;

    @Column(name = "Age")
    public String age;

}
Create a layout file and paste the following lines
<?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:layout_margin="5dp"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="5dp"
        android:text="@string/app_name"
        android:textSize="16sp"
        android:background="@drawable/tv_bg"/>

    <EditText
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:hint="@string/hint_enter_name"
        android:inputType="textPersonName" />

    <EditText
        android:id="@+id/age"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:hint="@string/hint_enter_age"
        android:inputType="number" />

    <EditText
        android:id="@+id/id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:hint="@string/hint_enter_id"
        android:inputType="number" />

    <Button
        android:id="@+id/insert"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:text="@string/insert" />

    <Button
        android:id="@+id/readAll"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:text="@string/read_all" />

    <Button
        android:id="@+id/read"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:text="@string/read_one" />

    <Button
        android:id="@+id/deleteAll"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:text="@string/delete_all" />

    <Button
        android:id="@+id/delete"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:text="@string/delete" />

    <Button
        android:id="@+id/update"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:text="@string/update" />
</LinearLayout>
To insert data into the Database use Model.save()
// Save Data
public void insertData(Details details){
    id = details.save();
    Log.v("id_value", String.valueOf(id));
    recreate();
}
To read all data from the Database use query as in the following
// Read All Data
Select().from(Details.class).orderBy("id ASC").execute();
To read data from the Database use query as in the following
// Read Data
Select().from(Details.class).where("id = ?", id).executeSingle();
To delete or delete All data from the Database use new Delete() query as in the following
// delete all 
new Delete().from(Details.class).execute();
// delete particular data 
Details.delete(Details.class , id);// where id is long type data
To update data from the Database use save() as in insert query as in the following. But, you have to get Primary id
// Update Data
Details details = Select().from(Details.class).where("id = ?", id).executeSingle();
details.name = holder.edt_name.getText().toString().trim();
details.age = holder.edt_age.getText().toString().trim();
details.save();

Download Full Source Code

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

Post your doubts and comments in the comments section.  

How to perform CRUD Operations in Android SQLite with Blob

How to perform CRUD Operations in Android SQLite with Blob

In this post, I will show you how to perform CRUD (Create,Read, Update and Delete) operation with Images from Gallery in SQLite which is embedded in Android devices.
Codes:
AndroidManifest.xml
Don't forget to add the following permission in your manifest file.

DBHelper.java
Open DBHelper.java and replace it with the following code.
package com.example.blob.helper;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
 
public class DBHelper extends SQLiteOpenHelper {

 static DBHelper dbhelper;
 static final String DATABASE_NAME = "IMAGE_EX";
 static final int DATABASE_VERSION = 1;
 public static final String IMAGE_TABLE="image_table";
 public static final String IMAGE_="image";
 public static final String IMAGE_NAME="image_name";
 public static final String IMAGE_ID="id";

 public static final String IMAGE_EX = "CREATE TABLE "+IMAGE_TABLE+" ("+IMAGE_ID + " INTEGER PRIMARY KEY,"+IMAGE_NAME+ " VARCHAR(55) DEFAULT NULL," + IMAGE_+" BLOB DEFAULT NULL);";

 public DBHelper(Context context) {
  super(context, DATABASE_NAME, null, DATABASE_VERSION);
 }

 @Override
 public void onCreate(SQLiteDatabase db) {

  db.execSQL(IMAGE_EX);

 }
  
 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  Log.w(DBHelper.class.getName(), "Upgrading database from version " + oldVersion + " to " + newVersion+ ". Old data will be destroyed");
  db.execSQL("DROP TABLE IF EXISTS"+ IMAGE_TABLE);
  }
  
 }


InsertHelper.java

Open InsertHelper.java and replace it with the following code.
package com.example.blob.helper;
 
import android.content.ContentValues;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
 
public class InsertHelper {

 private Context context;
 private SQLiteDatabase mDb;
 private DBHelper dbHelper;

 public InsertHelper(Context context) {
  this.context = context;
 }

 public InsertHelper open() throws SQLException {
  dbHelper = new DBHelper(context);
  mDb = dbHelper.getWritableDatabase();
  return this;
 }

 public void close() {
  dbHelper.close();
 }

 public long insert_profile(byte[] byteImage, String data){

  ContentValues values = new ContentValues();
  values.put(DBHelper.IMAGE_, byteImage);
  values.put(DBHelper.IMAGE_NAME, data);

  Log.w("Position: ", "Inserted Values-->" + values);

  return mDb.insert(DBHelper.IMAGE_TABLE, null, values);

 }
}

UpdateHelper.java

Open UpdateHelper.java and replace it with the following code.
package com.example.blob.helper;
 
import android.content.ContentValues;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
 
public class UpdateHelper {

 private Context context;
 private SQLiteDatabase mDb;
 private DBHelper dbHelper;

 public UpdateHelper(Context context) {
  this.context = context;
 }

 public UpdateHelper open() throws SQLException {
  dbHelper = new DBHelper(context);
  mDb = dbHelper.getWritableDatabase();
  return this;
 }

 public void close() {
  dbHelper.close();
 }

 public long update_profile(String id, byte[] byteImage, String data) {

  ContentValues Values = new ContentValues();
  Values.put(DBHelper.IMAGE_NAME,data);
  Values.put(DBHelper.IMAGE_,byteImage);
         return mDb.update(DBHelper.IMAGE_TABLE, Values, DBHelper.IMAGE_ID + "=" + id, null);

 }
}


DeleteHelper.java

Open DeleteHelper.java and replace it with the following code.
package com.example.blob.helper;
 
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
 
public class DeleteHelper {

 private Context context;
 private SQLiteDatabase mDb;
 private DBHelper dbHelper;

 public DeleteHelper(Context context) {
  this.context = context;
 }

 public DeleteHelper open() throws SQLException {
  dbHelper = new DBHelper(context);
  mDb = dbHelper.getWritableDatabase();
  return this;
 }

 public void close() {
  dbHelper.close();
 }

 public long delete_profile(String id) {
 
  return mDb.delete(DBHelper.IMAGE_TABLE, DBHelper.IMAGE_ID + "=" + id, null);

 }
}

activity_main.xml
Create activity_main.xml and replace it with the following code.
<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:weightSum="5"
 tools:context=".MainActivity">

 <Button
  android:id="@+id/add"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_weight="0.3"
  android:background="@android:color/holo_red_dark"
  android:text="@string/add_hint"
  android:textColor="@android:color/white"/>

 <ListView
  android:id="@+id/list"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_weight="4.7"/>
 
</LinearLayout>

list_item_profile.xml
Create list_item_profile.xml and replace it with the following code.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/ll"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:gravity="center"
 android:orientation="horizontal"
 android:padding="13dp">

 <ImageView
  android:id="@+id/profile_image"
  android:layout_width="75dp"
  android:layout_height="75dp"
  android:contentDescription="@string/app_name"
  android:scaleType="fitXY"
  android:src="@mipmap/ic_launcher"/>

 <TextView
  android:id="@+id/profile_name"
  android:layout_width="250dp"
  android:layout_height="match_parent"
  android:gravity="center"
  android:padding="5dp"
  android:text="@string/app_name"/>

</LinearLayout>
MainActivity.java
Open MainActivity.java and replace it with the following code.
package com.example.blob;
 
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
 
import com.example.blob.adapter.ProfileListAdapter;
import com.example.blob.helper.DBHelper;
import com.example.blob.helper.DeleteHelper;
 
import java.util.ArrayList;
 
public class MainActivity extends AppCompatActivity {

 Button btn_add;
 ListView listView;
 ArrayList image_name = new ArrayList<>();
 ArrayList image = new ArrayList<>();
 ArrayList image_id = new ArrayList<>();
 ProfileListAdapter adapter;
 Intent intent;
 DBHelper dbHelper;
 DeleteHelper del;
 SQLiteDatabase database;

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

  btn_add = (Button) findViewById(R.id.add);
  listView = (ListView) findViewById(R.id.list);

  // Clear the ArrayLists
  image_name.clear();
  image.clear();
  image_id.clear();

  display_data();

  // the helper class for DB creation operation
  dbHelper = new DBHelper(this);

  // the helper class for doing delete operation
  del = new DeleteHelper(this);

  btn_add.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    intent = new Intent(MainActivity.this, AddUpdateActivity.class);
    intent.putExtra("update", false);
    startActivity(intent);
    finish();
   }
  });

  // click event for updating the selected profile
  listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
   @Override
   public void onItemClick(AdapterView parent, View view, int position, long id) {
    intent = new Intent(MainActivity.this, AddUpdateActivity.class);
    intent.putExtra("id", image_id.get(position));
    intent.putExtra("image", image.get(position));
    intent.putExtra("name", image_name.get(position));
    intent.putExtra("update", true);
    startActivity(intent);
   }
  });

  // long click event for deleting the selected profile
  listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
   @Override
   public boolean onItemLongClick(AdapterView parent, View view, final int position, long id) {

    del.open();
    long ret = del.delete_profile(image_id.get(position));
    del.close();

    if(ret>0){
     Toast.makeText(getApplicationContext(), "Try Again!", Toast.LENGTH_SHORT).show();
    } else {
     Toast.makeText(getApplicationContext(), "Successfully Deleted!", Toast.LENGTH_SHORT).show();
 
     // default function to call the same class
     recreate();
    }
 
    return true;
   }
  });
 
 }

 public void display_data() {

  dbHelper = new DBHelper(this);
  database = dbHelper.getWritableDatabase();

  // Query to select all profiles
  String select_data = "SELECT * FROM " + DBHelper.IMAGE_TABLE;
 
  Cursor sCursor = database.rawQuery(select_data, null);
 
  if (sCursor.moveToFirst()) {
   do { 
image_id.add(sCursor.getString(sCursor.getColumnIndex(DBHelper.IMAGE_ID)));
     image_name.add(sCursor.getString(sCursor.getColumnIndex(DBHelper.IMAGE_NAME)));
     image.add(sCursor.getBlob(sCursor.getColumnIndex(DBHelper.IMAGE_)));

    Log.v("Response:", " " + image_name + " " + image);

   } while (sCursor.moveToNext());
  }
  sCursor.close();
  adapter = new ProfileListAdapter(MainActivity.this, image_id, image_name, image);
  listView.setAdapter(adapter);
 }
}
ProfileListAdapter.java
Open ProfileListAdapter.java and replace it with the following code.
package com.example.blob.adapter;
 
import android.app.Activity;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
 
import com.example.blob.R;
 
import java.util.ArrayList;
 
public class ProfileListAdapter extends BaseAdapter {

 Context mContext;
 ArrayList image_id;
 ArrayList image_name;
 ArrayList image;
 LayoutInflater layoutInflater;
 ImageView profile;
 TextView name;
 byte[] bytes;

 public ProfileListAdapter(Context mContext, ArrayList image_id,        ArrayList image_name, ArrayList image) {
  this.mContext = mContext;
  this.image_id = image_id;
  this.image_name = image_name;
  this.image = image;
 }

 public int getCount() {
  return image_id.size();
 }

 public Object getItem(int position) {
  return position;
 }

 public long getItemId(int position) {
  return position;
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {

  layoutInflater = ((Activity) mContext).getLayoutInflater();
  convertView = layoutInflater.inflate(R.layout.list_item_profile, null);

  profile = (ImageView) convertView.findViewById(R.id.profile_image);
  name = (TextView) convertView.findViewById(R.id.profile_name);

  name.setText(image_name.get(position));
  bytes = image.get(position);

  // Decoding Bitmap from stored ByteArray
  profile.setImageBitmap(BitmapFactory.decodeByteArray(bytes, 0, bytes.length));

  return convertView;
 }
}
activity_dashboard.xml
Create activity_dashboard.xml and replace it with the following code.
<?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:gravity="center"
 android:orientation="vertical">

 <ImageView
  android:id="@+id/imageView"
  android:layout_width="200dp"
  android:layout_height="200dp"
  android:layout_gravity="center_horizontal"
  android:contentDescription="@string/iv"
  android:src="@mipmap/ic_launcher" />

 <EditText
  android:id="@+id/editText"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal"
  android:layout_margin="10dp"
  android:hint="@string/name" />

 <Button
  android:id="@+id/button"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center_horizontal"
  android:text="Insert" />
</LinearLayout>
AddUpdateActivity.java
Open AddUpdateActivity.java and replace it with the following code.
package com.example.blob;
 
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import com.example.blob.helper.DBHelper;
import com.example.blob.helper.InsertHelper;
import com.example.blob.helper.UpdateHelper;
 
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
 
public class AddUpdateActivity extends AppCompatActivity {

 ImageView img1;
 EditText edt1;
 Button btn1;
 int SELECT_PICTURE = 1;
 SQLiteDatabase db;
 DBHelper mHelper;
 String selectedImagePath;
 byte[] byteImage = null;
 Intent intent;
 boolean isUpdate;
 String id, data;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_dashboard);

  // the helper class for DB creation operation
  mHelper = new DBHelper(this);
  img1 = (ImageView) findViewById(R.id.imageView);
  edt1 = (EditText) findViewById(R.id.editText);
  btn1 = (Button) findViewById(R.id.button);

  isUpdate = getIntent().getBooleanExtra("update", false);
  if (isUpdate) {
   id = getIntent().getStringExtra("id");
   byteImage = getIntent().getByteArrayExtra("image");
   data = getIntent().getStringExtra("name");

   // Decoding Bitmap from stored ByteArray from preview the stored image
   img1.setImageBitmap(BitmapFactory.decodeByteArray(byteImage, 0, byteImage.length));
   edt1.setText(data);
   btn1.setText("Update");
  }

  // Onclick event to select the image from gallery
  img1.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    intent.setType("image/*");
    startActivityForResult(Intent.createChooser(intent, "Select File"), SELECT_PICTURE);
   }
  });

  // Onclick event to do insert or update the data based on isUpdate
  btn1.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    data = edt1.getText().toString();
    if (data.equals("")) {
     Toast.makeText(getApplicationContext(), "Enter Name!", Toast.LENGTH_SHORT).show();
    } else {
     if (isUpdate) {
      updateData(data, id);
     } else {
      saveData(data);
     }
    }
   }
  });

 }

 public void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (resultCode == RESULT_OK) {
   if (requestCode == SELECT_PICTURE) {
    Uri selectedImageUri = data.getData();
    String[] projection = {MediaStore.MediaColumns.DATA};
    Cursor cursor = getContentResolver().query(selectedImageUri, projection, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
    cursor.moveToFirst();
    selectedImagePath = cursor.getString(column_index);
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(selectedImagePath, options);
    int REQUIRED_SIZE = 200;
    int scale = 1;
    while (options.outWidth / scale / 2 >= REQUIRED_SIZE
      && options.outHeight / scale / 2 >=REQUIRED_SIZE)
     scale *= 2;
    options.inSampleSize = scale;
    options.inJustDecodeBounds = false;
    Bitmap bitmap = BitmapFactory.decodeFile(selectedImagePath, options);
    // Preview for Selected Image
    img1.setImageBitmap(bitmap);
   }
  }
 }

 // Function for insertion
 private void saveData(String data) {
  db = mHelper.getWritableDatabase();
  // the helper class for doing insert operation
  InsertHelper ins = new InsertHelper(this);
  ins.open();

  try {
   // Encoding the Selected Image into ByteArray
   if (selectedImagePath != null) {
    FileInputStream in_stream = new FileInputStream(selectedImagePath);
    BufferedInputStream bif = new BufferedInputStream(in_stream);
    byteImage = new byte[bif.available()];
    bif.read(byteImage);
   } else {
    Toast.makeText(getApplicationContext(), "Please Select Image!", Toast.LENGTH_SHORT).show();
   }
 
   if (byteImage != null) {
    // Function call to insert data
    long ret = ins.insert_profile(byteImage, data);
    if (ret > 0) {
     Toast.makeText(getApplicationContext(), "Error!", Toast.LENGTH_SHORT).show();
    } else {
     Toast.makeText(this.getBaseContext(), "Image Saved in DB successfully.", Toast.LENGTH_SHORT).show();
     intent = new Intent(AddUpdateActivity.this, MainActivity.class);
     startActivity(intent);
     finish();
    }
   } else {
    Toast.makeText(getApplicationContext(), "Select Image", Toast.LENGTH_SHORT).show();
   }
  } catch (IOException e) {
    Toast.makeText(getApplicationContext(), "Error Exception!", Toast.LENGTH_SHORT).show();
  }
  ins.close();
  db.close();
 }

 // Function for Updating the already stored value
 private void updateData(String data, String id) {
  db = mHelper.getWritableDatabase();
 
  UpdateHelper upd = new UpdateHelper(this);
  upd.open();
 
  try {
   // Encoding the Selected Image into ByteArray
   if (selectedImagePath != null) {
    FileInputStream in_stream = new FileInputStream(selectedImagePath);
    BufferedInputStream bif = new BufferedInputStream(in_stream);
    byteImage = new byte[bif.available()];
    bif.read(byteImage);
   }

   // Function call to update data
   long ret = upd.update_profile(id, byteImage, data);

   if (ret > 0) {
    Toast.makeText(getApplicationContext(), "Error!", Toast.LENGTH_SHORT).show();
   } else {
    Toast.makeText(this.getBaseContext(), "Image Saved in DB successfully.", Toast.LENGTH_SHORT).show();
    intent = new Intent(AddUpdateActivity.this, MainActivity.class);
    startActivity(intent);
    finish();
   }
  } catch (IOException e) {
   Toast.makeText(getApplicationContext(), "Error Exception!", Toast.LENGTH_SHORT).show();
  }
  upd.close();
  db.close();
 }
}

Download Full Source Code


Download Code