Create or Copy Database in Android

Yesterday i spent whole day behind using my database i mean database is created i just require to use it in app. And i came across many problems, Some of them were really annoying and confusing. For some of them you can find online solution but some are really unknown like null pointer exception or getWritableDatabase method called recursively etc. even if there is table and also data in it.   some times it also happens you can not copy big database and it is also big problem in android. 
For that you have to dig up in to your code. You have to debug your app and in android studio it is also tedious task.  so to save your time and without doing all this you can copy database from assets folder to internal storage. Just go through the full tutorial and i hope it will solve all problems regarding coping database.

Step - 1.  Put below code in your SQLiteOpenHelper Class file. you have to put this code in onCreate method. if you have done some other task in oncreate method then rearrange it after this code. this code will check if database exist then do nothing because if you won't check it will overwrite your database every time you call   getWritableDatabase Or getReadableDatabase Method. beacuse it call onCreate method internally.

Step - 2. From your Main Activity only first time call Oncreate method of  SQLiteOpenHelper Class. so for the first time it will create or copy your database. if your database is big you can display progress bar for loading process.

DbHelper.java

package com.androprogrammer.dbdemo;

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

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;


public class DbHelper extends SQLiteOpenHelper 
{
 public static final String DB_NAME = "mydb.db";
 public static final int version = 1;
 public static final String product_table = "tblproduct";
 public static final String order_id = "_id";
 public static final String pname = "pname";
 public static final String desc = "desc";
 public static final String quantity = "quantity";
 public static final String rating = "rating";
 
 private SQLiteDatabase ourdb;
 public Context cont;

 public DbHelper(Context context)
 {
  // TODO Auto-generated constructor stub
  super(context, DB_NAME, null, version);
  this.cont = context;
 }

 @Override
 public void onCreate(SQLiteDatabase db)
    {
        try
        {
            File dbFile = cont.getDatabasePath(DB_NAME);

            if (dbFile.exists())
            {
                //Toast.makeText(cont, "Database Already Exist..." , Toast.LENGTH_LONG).show();
            }
            else
            {
                this.getReadableDatabase();

                InputStream input = cont.getAssets().open(DB_NAME);
                int size = input.available();
                input.close();

                if (size > 0)
                {

                    Log.d("file" , dbFile.getPath());

                    copyDataBase(dbFile);
                    //this.close();
                }
                else
                {
                    // TODO Auto-generated method stub
                    db.execSQL("create table " + product_table +" ( "+ order_id + " INTEGER PRIMARY KEY AUTOINCREMENT , " + pname + " TEXT NOT NULL ," + desc + " TEXT ,"
                            + rating + " INTEGER ," + quantity +" INTEGER );");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        this.ourdb = db;

 }

 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  // TODO Auto-generated method stub
  
 }

    /**
     * Copies your database from your local assets-folder to the just created empty database in the
     * system folder, from where it can be accessed and handled.
     * This is done by transfering bytestream.
     *
     * @param dbFile*/
    private void copyDataBase(File dbFile) throws IOException {

        //Open your local db as the input stream
        InputStream myInput = cont.getAssets().open(DB_NAME);

        //Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(dbFile);

        //transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer))>0)
        {
            myOutput.write(buffer, 0, length);
            Log.d("buf", "" + length);
        }

        //Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();

    }
  
 public DbHelper open() throws SQLException
 {
        if (this.ourdb == null)
        {
           this.ourdb = this.getWritableDatabase();
        }

  return this;
 }

 public synchronized void close()
 {
        if(this.ourdb.isOpen())
      this.ourdb.close();
 }

 public long insert(String name, String des, Float ratings, int quan) throws SQLException
 {
  // TODO Auto-generated method stub
  ContentValues cv = new ContentValues();
  cv.put(pname, name);
  cv.put(desc, des);
  cv.put(rating, ratings);
  cv.put(quantity, quan);
  return this.ourdb.insertOrThrow(product_table, null, cv);

 }

 public Cursor getAllData() throws SQLException
 {
  // TODO Auto-generated method stub
  String [] colums = new String[]{order_id ,pname ,desc ,rating ,quantity};
  Cursor c = this.ourdb.query(product_table,colums, null, null, null, null, null, null);
  return c;
 }

}



As you can see i have even checked if there is no file in assets folder it will create blank database so application won't crash. because it create bad impect when you publish your app in Google play store and it crash so for safety side you can do this. then you can update it later on. now from your main activity just call the onCreate method for that put below code in it.

SQLiteDatabase db = null;
DbHelper helper = new DbHelper(Main.this);
helper.onCreate(db);

Now your database file created or copied so just check it if you have created display method or activity then open it and check it. you can see in debug window also because i have used Logger to know weather database is copied or not so check debug window in editor. now from all other class or activity just call open method. for that put below code in it.

DbHelper helper = new DbHelper(this);
helper.open();

The open method will return instance of database after checking weather it is opened or not. ok now run your app and see the result. if you find any error or if you have any query let me know. Comment in below comment box. it may happen you may find some new error then also let me know so other can also solve that and i will try my best to solve that problem. i have also written tutorial about add, update and display records from database so if you have any query regarding that also check this out.
Keep coding ...  

2 comments :

  1. nice tutorial.
    can you please add some comments in it.

    ReplyDelete
  2. Very Useful tutorial
    Thank you Very Much....

    ReplyDelete