Search code examples
javaandroidandroid-sqliteandroid-database

Using existing database to display data in Android app


Hi I am new to android development. I have already created SQLite Database and saved it in my assets folder in Android Studio. My app has to use the existing database instead of creating a new one. The problem that I am facing is that when I want to display the data on the screen it is throwing an error at the Cursor that is executing the SQL statement. Kindly help.

The name of the database is test.db and the table name is MASTER. This is my DataBaseHelper class

public class DataBaseHelper extends SQLiteOpenHelper {
    private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
    //destination path (location) of our database on device
    private static String DB_PATH = "";
    private static String DB_NAME ="test,db";// Database name
    private SQLiteDatabase mDataBase;
    private final Context mContext;

    public DataBaseHelper(Context context)
    {
        super(context, DB_NAME, null, 1);// 1? Its database Version
        if(android.os.Build.VERSION.SDK_INT >= 17){
            DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
        }
        else
        {
            DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
        }
        this.mContext = context;
    }

    public void createDataBase() throws IOException
    {
        //If the database does not exist, copy it from the assets.

        boolean mDataBaseExist = checkDataBase();
        if(!mDataBaseExist)
        {
            this.getReadableDatabase();
            this.close();
            try
            {
                //Copy the database from assests
                copyDataBase();
                Log.e(TAG, "createDatabase database created");
            }
            catch (IOException mIOException)
            {
                throw new Error("ErrorCopyingDataBase");
            }
        }
    }

    //Check that the database exists here: /data/data/your package/databases/Da Name
    private boolean checkDataBase()
    {
        File dbFile = new File(DB_PATH + DB_NAME);
        //Log.v("dbFile", dbFile + "   "+ dbFile.exists());
        return dbFile.exists();
    }

    //Copy the database from assets
    private void copyDataBase() throws IOException
    {
        InputStream mInput = mContext.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream mOutput = new FileOutputStream(outFileName);
        byte[] mBuffer = new byte[1024];
        int mLength;
        while ((mLength = mInput.read(mBuffer))>0)
        {
            mOutput.write(mBuffer, 0, mLength);
        }
        mOutput.flush();
        mOutput.close();
        mInput.close();
    }

    //Open the database, so we can query it
    public boolean openDataBase() throws SQLException
    {
        String mPath = DB_PATH + DB_NAME;
        //Log.v("mPath", mPath);
        mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
        //mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
        return mDataBase != null;
    }

    @Override
    public synchronized void close()
    {
        if(mDataBase != null)
            mDataBase.close();
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

This is my TestAdapter class

public class TestAdapter
    {
        protected static final String TAG = "DataAdapter";

        private final Context mContext;
        private SQLiteDatabase mDb;
        private DataBaseHelper mDbHelper;

        public TestAdapter(Context context)
        {
            this.mContext = context;
            mDbHelper = new DataBaseHelper(mContext);
        }

        public TestAdapter createDatabase() throws SQLException
        {
            try
            {
                mDbHelper.createDataBase();
            }
            catch (IOException mIOException)
            {
                Log.e(TAG, mIOException.toString() + "  UnableToCreateDatabase");
                throw new Error("UnableToCreateDatabase");
            }
            return this;
        }

        public TestAdapter open() throws SQLException
        {
            try
            {
                mDbHelper.openDataBase();
                mDbHelper.close();
                mDb = mDbHelper.getReadableDatabase();
            }
            catch (SQLException mSQLException)
            {
                Log.e(TAG, "open >>"+ mSQLException.toString());
                throw mSQLException;
            }
            return this;
        }

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

        public Cursor getTestData() {
            try
            {
                String sql ="SELECT * FROM MASTER;";

                Cursor mCur = mDb.rawQuery(sql, null);
                if (mCur!=null)
                {
                    mCur.moveToNext();
                }
                return mCur;
            }
            catch (SQLException mSQLException)
            {
                Log.e(TAG, "getTestData >>"+ mSQLException.toString());
                throw mSQLException;
            }
        }
    }

This is my MainActivity class

public class MainActivity extends AppCompatActivity {

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

        Button button=findViewById(R.id.submit);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                TestAdapter mDbHelper = new TestAdapter(MainActivity.this);
                mDbHelper.createDatabase();
                mDbHelper.open();
                Cursor testdata = mDbHelper.getTestData();
                Toast.makeText(MainActivity.this,testdata.getString(0),Toast.LENGTH_SHORT).show();
                mDbHelper.close();
            }
        });

    }
}

And this is the logcat

2019-02-04 15:47:30.227 2594-2594/com.example.myapplication E/SQLiteLog: (1) no such table: MASTER
2019-02-04 15:47:30.228 2594-2594/com.example.myapplication E/DataAdapter: getTestData >>android.database.sqlite.SQLiteException: no such table: MASTER (code 1): , while compiling: SELECT * FROM MASTER;
2019-02-04 15:47:30.228 2594-2594/com.example.myapplication D/AndroidRuntime: Shutting down VM
2019-02-04 15:47:30.242 2594-2594/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myapplication, PID: 2594
    android.database.sqlite.SQLiteException: no such table: MASTER (code 1): , while compiling: SELECT * FROM MASTER;
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:890)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:501)
        at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
        at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
        at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
        at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
        at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1392)
        at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1331)
        at com.example.myapplication.TestAdapter.getTestData(TestAdapter.java:63)
        at com.example.myapplication.MainActivity$1.onClick(MainActivity.java:38)
        at android.view.View.performClick(View.java:6297)
        at android.view.View$PerformClick.run(View.java:24797)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6626)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)

The logcat says that there is no MASTER table but when I viewed the database via SQLiteDB Browser it was there at that time.


Solution

  • set your data path directly as a string, hope it will work

     private final static String DATABASE_PATH ="/data/data/com.yourpackagename/databases/";
    public SQLiteDatabase openDatabase() throws SQLException
        {   String myPath = DATABASE_PATH + "DB_NAME";myDataBase = SQLiteDatabase.openOrCreateDatabase(myPath, null, null);
            return myDataBase;
        }`