I'm experimenting with using an existing database that is provided to the app in the Assets folder.
When I run the app for the very first time, I get an NullPointerException on an InputSteam object.
If I run the app a second time, then the input stream is not null but this time, I get an SQLiteException: no such table.
Very unusual, I'm wondering if anyone could help find the cause.
In this project, I created a simple SQLite database file and stored it in the Assets folder. It is called
Customers.db
and contains one table calledCustomerList
. The table columns are ID (integer primary key), CustomerName and Country.In the DatabaseHelper object, the method
loadDatabase()
loads the database from the assets folder into the phone's internal memory.DatabaseHelper method
getRecords()
returns an Array of Customer objects and these are the fields of these customer objects are listed in a RecyclerView in the MainActivity. To simply the experiment, as a first step, thegetRecords()
method return all the rows of the table.
When run for the first time the following exception is reported:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mo.useexistingdatabasedemo/com.mo.useexistingdatabasedemo.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.read(byte[], int, int)' on a null object reference
And the second time it's run, the input stream seems to be no longer null, but instead an sqliteexception is reported:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mo.useexistingdatabasedemo/com.mo.useexistingdatabasedemo.MainActivity}: android.database.sqlite.SQLiteException: no such table: CustomerList (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM CustomerList
In ,my project class DatabaseHelper is defined as follows (and its methods are called from the MainActivity).
package com.mo.useexistingdatabasedemo;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import androidx.annotation.Nullable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.Buffer;
import java.util.ArrayList;
public class DatabaseHelper extends SQLiteOpenHelper {
public static ArrayList<Customer> arrayList = new ArrayList<>();
public static final String DATABASE_NAME = "Customers.db";
public static final String TABLE_NAME = "CustomerList";
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_DIRECTORY_PATH = "data/data/com.mo" +
".useexistingdatabasedemo/databases";
public static final String DATABASE_FILE_PATH = DATABASE_DIRECTORY_PATH + DATABASE_NAME;
Context context;
InputStream inputStream;
OutputStream outputStream;
Buffer buffer;
public static final String SELECT_ALL_TABLE = "SELECT * FROM " + TABLE_NAME;
public DatabaseHelper(@Nullable Context context) {
super(context, DATABASE_NAME, null, 2);
this.context = context;
}
public void loadDatabase() {
String path = DATABASE_DIRECTORY_PATH + DATABASE_NAME;
File dbFile = new File(path); // the descriptor of a file in internal memory to which
// we will write the db in the assets folder.
// if the database isn't already in internal memory, copy it over from assets.
if (!dbFile.exists()) {
try {
inputStream = context.getAssets().open(DATABASE_NAME);
} catch (IOException e) {
Log.e("IOException input stream: ",
"Exception opening input stream " + e.getMessage());
}
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(path);
} catch (FileNotFoundException e) {
Log.e("IOException, output stream: ",
"Exception creating output stream " + e.getMessage());
}
// create a buffer of 1024 bytes length
byte[] buffer = new byte[1024];
int len;
try {
while ((len = inputStream.read(buffer, 0, 1024)) > 0)
outputStream.write(buffer, 0, len);
outputStream.flush();
inputStream.close();
} catch (IOException e) {
Log.e("IOException", "Exception occurred in while block" + e.getMessage());
}
}
Log.i("Load database", "The method public loadDatabase() executed succesffully");
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public ArrayList getRecords() {
SQLiteDatabase database = getWritableDatabase();
Log.i("The attached database is :", database.getAttachedDbs().toString());
Cursor cursor = database.rawQuery("SELECT * FROM " + TABLE_NAME, null);
while (cursor.moveToNext()) {
Customer customer = new Customer();
customer.customerName = cursor.getColumnName(1).toString();
customer.country = cursor.getColumnName(2).toString();
arrayList.add(customer);
}
return arrayList;
}
}