Reputation: 97
I created a database containing several tables.
I have this database saved in the assets folder.
I am trying to simply access the EXERCISESTABLE from this database and then display its values in a modified listView. However, I keep getting the error:
W/System.err: java.io.FileNotFoundException.
Here is my MainActivity extends Activity Class:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lvExercise = (ListView)findViewById(R.id.listView_exercises);
mDBHelper = new DatabaseHelper(this);
//Check exists database
File database = getApplicationContext().getDatabasePath(DatabaseHelper.DBNAME);
if(false == database.exists()){
mDBHelper.getReadableDatabase();
// Copy Database
if(copyDatabase(this)){
Toast.makeText(this, "Copy database success", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this, "Copy data error", Toast.LENGTH_SHORT).show();
return;
}
}
//Get exercise List in db when db exists
mExercisesList = mDBHelper.getListExercise();
//Init adapter
adapter = new ListExerciseAdapter(this, mExercisesList);
//Set adapter for list view
lvExercise.setAdapter(adapter);
}
private boolean copyDatabase(Context context){
try{
InputStream inputStream = context.getAssets().open(DatabaseHelper.DBNAME);
String outFileName = DatabaseHelper.DBLOCATION + DatabaseHelper.DBNAME;
OutputStream outputStream = new FileOutputStream(outFileName);
byte[]buff = new byte[1024];
int length =0;
while ((length = inputStream.read(buff)) >0){
outputStream.write(buff, 0, length);
}
outputStream.flush();
outputStream.close();
Log.w("MainActivity", "DB copied");
return true;
}catch(Exception e){
e.printStackTrace();
return false;
}
}
I have my workout_program.db database file located in the assets folder, however I cant seem to access it even though it all looks correct to me.
Here is my DBHelper extends SQLiteOpenHelper Code:
private Context mContext;
private SQLiteDatabase mDatabase;
public DatabaseHelper(Context context){
super(context, DBNAME, null, 1);
this.mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void openDatabase() {
String dbPath = mContext.getDatabasePath(DBNAME).getPath();
if(mDatabase != null && mDatabase.isOpen()){
return;
}
mDatabase = SQLiteDatabase.openDatabase(dbPath,null,SQLiteDatabase.OPEN_READWRITE);
}
public void closeDatabase(){
if(mDatabase!=null){
mDatabase.close();
}
}
public List<Exercise> getListExercise(){
Exercise exercise = null;
List<Exercise> exerciseList = new ArrayList<>();
openDatabase();
Cursor cursor = mDatabase.rawQuery("SELECT * FROM EXERCISESTABLE ", null);
cursor.moveToFirst();
while(!cursor.isAfterLast()){
exercise = new Exercise(cursor.getInt(0),cursor.getString(1), cursor.getInt(2), cursor.getInt(3));
exerciseList.add(exercise);
cursor.moveToNext();
closeDatabase();
}
return exerciseList;
}
Here is my exercise class:
public class Exercise {
private int exercise_id;
private String exercise_name;
private int exercise_type_id;
private int exercise_equipment_id;
public Exercise(int exercise_id, String exercise_name, int exercise_type_id, int exercise_equipment_id) {
this.exercise_id = exercise_id;
this.exercise_name = exercise_name;
this.exercise_type_id = exercise_type_id;
this.exercise_equipment_id = exercise_equipment_id;
}
public int getExercise_id() {
return exercise_id;
}
public void setExercise_id(int exercise_id) {
this.exercise_id = exercise_id;
}
public String getExercise_name() {
return exercise_name;
}
public void setExercise_name(String exercise_name) {
this.exercise_name = exercise_name;
}
public int getExercise_type_id() {
return exercise_type_id;
}
public void setExercise_type_id(int exercise_type_id) {
this.exercise_type_id = exercise_type_id;
}
public int getExercise_equipment_id() {
return exercise_equipment_id;
}
public void setExercise_equipment_id(int exercise_equipment_id) {
this.exercise_equipment_id = exercise_equipment_id;
}
}
Here is my ListExerciseAdapter extends BaseAdapter class:
public ListExerciseAdapter(Context mContext, List<Exercise> exercisesList) {
this.mContext = mContext;
this.mExercisesList = exercisesList;
}
@Override
public int getCount() {
return mExercisesList.size();
}
@Override
public Object getItem(int position) {
return mExercisesList.get(position);
}
@Override
public long getItemId(int position) {
return mExercisesList.get(position).getExercise_id();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = View.inflate(mContext, R.layout.exercises_listview_layout, null);
TextView exercise_name = (TextView)v.findViewById(R.id.exercise_name);
TextView exercise_type_id = (TextView)v.findViewById(R.id.exercise_type_id);
TextView exercise_equipment_id = (TextView)v.findViewById(R.id.exercise_equipment_id);
exercise_name.setText(mExercisesList.get(position).getExercise_name());
exercise_type_id.setText(String.valueOf(mExercisesList.get(position).getExercise_type_id()));
exercise_equipment_id.setText(String.valueOf(mExercisesList.get(position).getExercise_equipment_id()));
return v;
}
Any help will be greatly appreciated.
Upvotes: 1
Views: 763
Reputation: 1489
According to the prepopulated Room Database from the official documentation. You have 2 options:
1) createFromAssets: in this option, you may create a directory called "databases" under assets folder so your could will be as follow:
.createFromAssets("/databases/YOUR DATABASE FILENAME")
2) createFromFile: This option may work with the file you are assigning its path.
.createFromFile(File("YOUR FILE PATH"))
if you are stuck with these two solutions, you can try the manual solution, we may call it manual solution yeah !. by accessing your database file in assets folder.
private fun copyDBFromStorage(databaseName: String) {
if (checkIfDBExists(this, databaseName)) return
val databaseFile = File(this.getDatabasePath(databaseName).toString())
val sourceLocation = assets.open("Your database file path")
try {
val inputStream = sourceLocation
val os = FileOutputStream(databaseFile)
val buffer = ByteArray(1024 * 32)
var length = inputStream.read(buffer)
while (length > 0) {
os.write(buffer, 0, length)
length = inputStream.read(buffer)
}
os.flush()
os.close()
inputStream.close()
} catch (ex: IOException) {
ex.printStackTrace();
throw RuntimeException("Error copying storage database");
}
}
private fun checkIfDBExists(
context: Context,
databaseName: String
): Boolean {
val dbfile = File(context.getDatabasePath(databaseName).toString())
if (dbfile.exists()) return true
if (!dbfile.parentFile.exists()) {
dbfile.parentFile.mkdirs()
}
return false
}
Note: you can convert this Kotlin code to java using android studio code conversion feature.
If you found any problem with that, kindly reply.
Happy coding 🤓
Upvotes: 1