1

I am currently building a password manager app for myself. I plan to save the passwords in a SQLite database. For that I use this code:

package com.example.passwordmanager;

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

import androidx.annotation.Nullable;

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String COLUMN_PASSWORD = "password";
    public static final String PASSWORDS_TABLE = COLUMN_PASSWORD + "s_table";
    public static final String COLUMN_ID = "id";
    public static final String COLUMN_SERVICE = "service";
    public static final String COLUMN_CREATION_DATE = "creation_date";
    public static final String COLUMN_USED_NAME = "used_name";
    public static final String COLUMN_USED_EMAIL = "used_email";


    public DatabaseHelper(@Nullable Context context) {
        super(context,  "passwordManager.db", null,1);
        Log.d("DatabaseHelper","Constructor reached");

    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String createTableStatement = "CREATE TABLE "+ PASSWORDS_TABLE + " ( " + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_SERVICE + " VARCHAR(40), " + COLUMN_PASSWORD + " VARCHAR(40), " + COLUMN_CREATION_DATE + " VARCHAR(11), " + COLUMN_USED_NAME + " VARCHAR(40), " + COLUMN_USED_EMAIL + " VARCHAR(40), master VARCHAR(20), firstTime BOOLEAN)";
        Log.d("DatabaseHelper","OnCreate1 reached");
        db.execSQL(createTableStatement);
        Log.d("DatabaseHelper","OnCreate2 reached");
    }

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

        db.execSQL("DROP TABLE IF EXISTS "+PASSWORDS_TABLE);
        onCreate(db);

    }


    public boolean addToTable(Registration profile){

        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();

        cv.put(COLUMN_PASSWORD,profile.hashedPassword);
        cv.put(COLUMN_SERVICE,profile.service);
        cv.put(COLUMN_CREATION_DATE,profile.creation_date);
        cv.put(COLUMN_USED_NAME,profile.used_name);
        cv.put(COLUMN_USED_EMAIL,profile.used_email);

        long insert = db.insert(PASSWORDS_TABLE, null, cv);

        if(insert==-1){
            return true;
        }else{
            return false;
        }


    }
}

The problem with this code is, it just doesn't create the database or the folder of the database in data\data\com.example.passwordmanager. I tried outputting which methods it will reached when the constructor is called and I realized that it never reaches the onCreate method.

The DatabaseHelper class is only called once so for:

package com.example.passwordmanager;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.hardware.input.InputManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.Toast;

public class CreatingNewEntryActivity extends AppCompatActivity {
   

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


        DatabaseHelper dh = new DatabaseHelper(CreatingNewEntryActivity.this);
}

Is this a problem with the code? Do I have to give permissions in the manifest.xml? Did I mess something up with the emulator? The App starts fine, it just doesn't create the database.

Dboy0Z
  • 43
  • 1
  • 1
  • 8

1 Answers1

1

You need to call getWritableDatabase() or getReadableDatabase() on your database helper to make the framework create the database file and trigger onCreate(). Just calling the constructor is not enough.

See also: When is SQLiteOpenHelper onCreate() / onUpgrade() run?

laalto
  • 150,114
  • 66
  • 286
  • 303
  • But that doesn't explain why the database.db file and the folder for it are not created. The super in the constructor should create the database file (?) , but it doesn't – Dboy0Z Nov 17 '20 at 21:31
  • "The super in the constructor should create the database file" what makes you think that? – njzk2 Nov 17 '20 at 21:37
  • Oh you were right @laalto, I just tested it again and now its working. I thought the super creates the database because I read in the documentation that the constructor of SQLiteOpenHelper would create it, but I misread it. – Dboy0Z Nov 18 '20 at 08:24
  • Yeah. The constructor docs also say "The database is not actually created or opened until one of getWritableDatabase() or getReadableDatabase() is called." https://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper#SQLiteOpenHelper(android.content.Context,%20java.lang.String,%20android.database.sqlite.SQLiteDatabase.CursorFactory,%20int) – laalto Nov 18 '20 at 09:15