unknown os platform
how to store images in SQLite database in Android and display in listview | Whats-online.info
whats-online-info

how to store images in SQLite database in Android and display in listview


how
2017/02/06 / Science and Tutorials

Android code: Learn how to store images in SQLite database from gallery or camera capture, retrieve the images from the database and display in a listview. See example





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


 Android platform provides several ways to store data in our application.
1. SQLite database
2. SharedPreferences etc



For our post, we will only work with SQLite database.
First and foremost, we need to understand what an SQLite database is?
SQLite database is an open source SQL database that stores data to a text file on a device. It executes SQL Commands to perform a set of functions, that is, create, read, update and delete operations.

On my previous post, I showed how to store data in SQLite database from edit text, retrieve and populate it in a listview. For this post, I will show the SQLite CRUD operations with images from gallery and text from EditText.

We need to understand this; images are stored in SQLite database as BLOB data type.
A BLOB is a large binary object that can hold a variable amount of data. 
Note, we can only store images in the database as BLOB data type. We need to convert our image path to a bitmap then to bytes.
Also, note, storing image path to our database as a string is not a good way to save images to the SQLite database in Android programmatically.

I believe everybody reading through this tutorial, is an experienced programmer, so I will not show the procedures of creating a new project. 
Then create a new project to demonstrate our tutorial.
Now let us lay out our interface to explain this android post. The following are the list of our project files.

list of our activity classes
Contact.java
dataAdapter.java
DatabaseHandler.java
MainActivity.java

list of our XML files
activity_main.xml
listcontacts.xml

activity_main.xml

This XML file provides the interface for selecting our images from the gallery or captured images. It contains the following widgets. 
ImageView widget - to select our image from the gallery
Edittext widget- to key in text.
Listview widget - display the data from the database
save and display button - save button - to  send the data to the database and display button - to populate the data to the listview
Entire activity_main.xml 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"     tools:context=".MainActivity">     <TextView android:text="Profile"         android:layout_gravity="center"         android:textSize="30dp"         android:layout_width="wrap_content"         android:layout_height="wrap_content" />     <ImageView         android:layout_width="match_parent"         android:layout_height="100dp"         android:onClick="buttonClicked"         android:id="@+id/pic"         android:src="@drawable/choose_up"/>     <EditText         android:layout_width="match_parent"         android:layout_height="50dp"         android:id="@+id/txt1"         android:hint="Enter your first name"         android:layout_margin="10dp"/>     <LinearLayout         android:layout_width="match_parent"         android:orientation="horizontal"         android:gravity="center"         android:layout_height="wrap_content">         <Button             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:onClick="buttonClicked"             android:id="@+id/save"             android:text="Save"/>         <Button             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:onClick="buttonClicked"             android:id="@+id/display"             android:text="Display"/>     </LinearLayout>     <LinearLayout         android:layout_width="match_parent"         android:layout_height="match_parent">         <ListView             android:layout_width="match_parent"             android:layout_height="match_parent"             android:id="@+id/list1"/>     </LinearLayout> </LinearLayout>

listcontacts.xml

This XML file Lays out the interface for the items of the listview. Determines how the populated data is displayed from the SQLite database to the listview.
Entire listcontacts.xml code 

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:orientation="vertical"     android:layout_width="match_parent"     android:layout_height="match_parent">     <TextView         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_margin="5dp"         android:id="@+id/txtViewer"         />    <ImageView        android:layout_width="match_parent"        android:layout_height="100dp"        android:id="@+id/imgView"/> </LinearLayout>

MainActivity.java

Entire code. 

package info.whats_online.sqlitedbwithimages; import android.annotation.TargetApi; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; import android.widget.Toast; import java.io.ByteArrayOutputStream; import java.util.ArrayList; public class MainActivity extends Activity {     private EditText fname;     private ImageView pic;     private DatabaseHandler db;     private String f_name;     private  ListView lv;     private dataAdapter data;     private Contact dataModel;     private Bitmap bp;     private byte[] photo;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         //Instantiate database handler         db=new DatabaseHandler(this);         lv = (ListView) findViewById(R.id.list1);         pic= (ImageView) findViewById(R.id.pic);         fname=(EditText) findViewById(R.id.txt1);     }     public void buttonClicked(View v){        int id=v.getId();         switch(id){             case R.id.save:                     if(fname.getText().toString().trim().equals("")){                         Toast.makeText(getApplicationContext(),"Name edit text is empty, Enter name", Toast.LENGTH_LONG).show();                     }  else{                         addContact();                     }                 break;             case R.id.display:                         ShowRecords();                 break;             case R.id.pic:                          selectImage();                 break;         }     }     public void selectImage(){         Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);         photoPickerIntent.setType("image/*");         startActivityForResult(photoPickerIntent, 2);     }     @Override     protected void onActivityResult(int requestCode, int resultCode, Intent data) {         switch(requestCode) {             case 2:                 if(resultCode == RESULT_OK){                     Uri choosenImage = data.getData();                     if(choosenImage !=null){                         bp=decodeUri(choosenImage, 400);                         pic.setImageBitmap(bp);                   }                 }         }     }     //COnvert and resize our image to 400dp for faster uploading our images to DB     protected Bitmap decodeUri(Uri selectedImage, int REQUIRED_SIZE) {         try {             // Decode image size             BitmapFactory.Options o = new BitmapFactory.Options();             o.inJustDecodeBounds = true;             BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);             // The new size we want to scale to             // final int REQUIRED_SIZE =  size;             // Find the correct scale value. It should be the power of 2.             int width_tmp = o.outWidth, height_tmp = o.outHeight;             int scale = 1;             while (true) {                 if (width_tmp / 2 < REQUIRED_SIZE                         || height_tmp / 2 < REQUIRED_SIZE) {                     break;                 }                 width_tmp /= 2;                 height_tmp /= 2;                 scale *= 2;             }             // Decode with inSampleSize             BitmapFactory.Options o2 = new BitmapFactory.Options();             o2.inSampleSize = scale;             return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);         }         catch (Exception e){             e.printStackTrace();         }         return null;     }     //Convert bitmap to bytes     @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)     private byte[] profileImage(Bitmap b){         ByteArrayOutputStream bos = new ByteArrayOutputStream();         b.compress(Bitmap.CompressFormat.PNG, 0, bos);         return bos.toByteArray();     }     // function to get values from the Edittext and image     private void getValues(){         f_name = fname.getText().toString();         photo = profileImage(bp);     }     //Insert data to the database     private void addContact(){         getValues();         db.addContacts(new Contact(f_name, photo));         Toast.makeText(getApplicationContext(),"Saved successfully", Toast.LENGTH_LONG).show();     }      //Retrieve data from the database and set to the list view     private void ShowRecords(){         final ArrayList<Contact> contacts = new ArrayList<>(db.getAllContacts());         data=new dataAdapter(this, contacts);         lv.setAdapter(data);         lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {             @Override             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                 dataModel = contacts.get(position);                Toast.makeText(getApplicationContext(),String.valueOf(dataModel.getID()), Toast.LENGTH_SHORT).show();             }         });     } }


MainActivity.java functions

selectImage() -navigates to the gallery on the image button click action.
onActivityResult() -returns the selected image path.
decodeUri() -converts the image path to a bitmap image. Also, it has resize function to reduce the size of selected image thus lessen the time of sending the image to the SQLite database.
getValues() - gets the values from our imageview and our edittext widgets
ShowRecords() - Populates the retrieved images and texts to the listview
addContact() - Stores our bitmap image as byte data type and text as a string in the database.
profileImage() - Convert our bitmap image to byte array data type. 

Note that, retrieving image string from the database and display it in listview might not work.  We are only storing our images as BLOB data type that is why we are converting the images to byte data type.

Contact.Java

Contains the set and get methods to set the values of our attributes and retrieve the values of our attributes
Entire code

package info.whats_online.sqlitedbwithimages; public class Contact {     //private variables     int _id;     String _fname;     byte[] _img;     // Empty constructor     public Contact(){     }     // constructor     public Contact(int id, String fname, byte[] img){         this._id = id;         this._fname = fname;         this._img = img;     }     // constructor     public Contact(String fname, byte[] img){         this._fname = fname;         this._img = img;     }     // getting ID     public int getID(){         return this._id;     }     // setting id     public void setID(int id){         this._id = id;     }     // getting first name     public String getFName(){         return this._fname;     }     // setting first name     public void setFName(String fname){         this._fname = fname;     }     //getting profile pic     public byte[] getImage(){         return this._img;     }     //setting profile pic     public void setImage(byte[] b){         this._img=b;     } }


DatabaseHandler.java

Performs all CRUD operations, that is, Insert, Read, Update, Delete.
It has the methods to insert data to the table contact, select data, update and delete data from the table.
Entire  DatabaseHandler.java code

package info.whats_online.sqlitedbwithimages; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import java.util.ArrayList; import java.util.List; /**  * Created by sada on 1/31/2017.  */ public class DatabaseHandler extends SQLiteOpenHelper {     // Database Version     private static final int DATABASE_VERSION = 1;     // Database Name     private static final String DATABASE_NAME = "contactsManager";     // Contacts table name     private static final String TABLE_CONTACTS = "contacts";     // Contacts Table Columns names     private static final String KEY_ID = "id";     private static final String KEY_FNAME = "fname";     private static final String KEY_POTO = "poto";     public DatabaseHandler(Context context) {         super(context, DATABASE_NAME, null, DATABASE_VERSION);     }     //Create tables     @Override     public void onCreate(SQLiteDatabase db) {        String CREATE_TABLE_CONTACTS="CREATE TABLE " + TABLE_CONTACTS + "("                + KEY_ID +" INTEGER PRIMARY KEY,"                + KEY_FNAME +" TEXT,"                + KEY_POTO  +" BLOB" + ")";         db.execSQL(CREATE_TABLE_CONTACTS);     }     // Upgrading database     @Override     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {         // Drop older table if existed         db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);         // Create tables again         onCreate(db);     }     /**      * All CRUD(Create, Read, Update, Delete) Operations      */     //Insert values to the table contacts     public void addContacts(Contact contact){       SQLiteDatabase db = this.getReadableDatabase();         ContentValues values=new ContentValues();         values.put(KEY_FNAME, contact.getFName());         values.put(KEY_POTO, contact.getImage() );         db.insert(TABLE_CONTACTS, null, values);         db.close();     }     /**      *Getting All Contacts      **/     public List<Contact> getAllContacts() {         List<Contact> contactList = new ArrayList<Contact>();         // Select All Query         String selectQuery = "SELECT  * FROM " + TABLE_CONTACTS;         SQLiteDatabase db = this.getWritableDatabase();         Cursor cursor = db.rawQuery(selectQuery, null);         // looping through all rows and adding to list         if (cursor.moveToFirst()) {             do {                 Contact contact = new Contact();                 contact.setID(Integer.parseInt(cursor.getString(0)));                 contact.setFName(cursor.getString(1));                 contact.setImage(cursor.getBlob(2));                 // Adding contact to list                 contactList.add(contact);             } while (cursor.moveToNext());         }         // return contact list         return contactList;     }     /**      *Updating single contact      **/     public int updateContact(Contact contact, int id) {         SQLiteDatabase db = this.getWritableDatabase();         ContentValues values = new ContentValues();         values.put(KEY_FNAME, contact.getFName());         values.put(KEY_POTO, contact.getImage());         // updating row         return db.update(TABLE_CONTACTS, values, KEY_ID + " = ?",                 new String[] { String.valueOf(id) });     }     /**      *Deleting single contact      **/     public void deleteContact(int Id) {         SQLiteDatabase db = this.getWritableDatabase();         db.delete(TABLE_CONTACTS, KEY_ID + " = ?",                 new String[] { String.valueOf(Id) });         db.close();     } }

dataAdapter.java

Contains the list adapter to display our data using a listview.
Remember, our image was saved as bytes to we need to convert our byte array image to a bitmap image.
Entire dataAdapter.java

package info.whats_online.sqlitedbwithimages;         import android.content.Context;         import android.graphics.Bitmap;         import android.graphics.BitmapFactory;         import android.view.LayoutInflater;         import android.view.View;         import android.view.ViewGroup;         import android.widget.ArrayAdapter;         import android.widget.ImageView;         import android.widget.TextView;         import java.util.ArrayList; public class dataAdapter extends ArrayAdapter<Contact>{     Context context;     ArrayList<Contact> mcontact;     public dataAdapter(Context context, ArrayList<Contact> contact){         super(context, R.layout.listcontacts, contact);         this.context=context;         this.mcontact=contact;     }     public  class  Holder{         TextView nameFV;         ImageView pic;     }     @Override     public View getView(int position, View convertView, ViewGroup parent) {         // Get the data item for this position         Contact data = getItem(position);         // Check if an existing view is being reused, otherwise inflate the view         Holder viewHolder; // view lookup cache stored in tag         if (convertView == null) {             viewHolder = new Holder();             LayoutInflater inflater = LayoutInflater.from(getContext());             convertView = inflater.inflate(R.layout.listcontacts, parent, false);             viewHolder.nameFV = (TextView) convertView.findViewById(R.id.txtViewer);             viewHolder.pic = (ImageView) convertView.findViewById(R.id.imgView);             convertView.setTag(viewHolder);         } else {             viewHolder = (Holder) convertView.getTag();         }         viewHolder.nameFV.setText("First Name: "+data.getFName());         viewHolder.pic.setImageBitmap(convertToBitmap(data.getImage()));         // Return the completed view to render on screen         return convertView;     }     //get bitmap image from byte array     private Bitmap convertToBitmap(byte[] b){         return BitmapFactory.decodeByteArray(b, 0, b.length);     } }

Thanks for your visit to our site. Subscribe to our newsletter to get the latest updates directly to your mailbox.












You may also like:


Leave a comment












Subscribe to get replies direct to your mailbox

Submit comment