Android Studio, Java and SQLite issue creating a database - java

The issue im having is when I attempt to execute the query it doesn't have access to the execSQL part of the command, ive been stuck on this for around an hour.
package com.androstock.myweatherapp;
import android.database.sqlite.SQLiteDatabase;
import static android.database.sqlite.SQLiteDatabase.openOrCreateDatabase;
public class Database {
SQLiteDatabase mydatabase = openOrCreateDatabase("database.db", null);
public void onCreate() {
mydatabase.execSQL("CREATE TABLE IF NOT EXISTS TutorialsPoint(Username VARCHAR,Password VARCHAR);");
mydatabase.execSQL("INSERT INTO TutorialsPoint VALUES('admin','admin');");
}
}
If somebody would be able to shed some light on where im going wrong with this that would be great thanks in advance

You are getting a little mixed up with your code.
I'd suggest making the Database class extend (be a subclass of) the SQLiteOpenHelper class and overriding the onCreate method to create the tables in the database.
e.g.
public class Database extends SQLiteOpenHelper {
// define constants so all names can be defined just once
public static final String DBNAME = "database.db"; // The database name
public static final int DBVERSION = 1; // The version (increase it to invoke the onUpgrade method to alter the DB structure)
public static final String TABLE_TUTORIALSPOINT = "tutorialspoint"; // The table name
public static final String COLUMN_USERNAME = "username"; // Columns
public static final String COLUMN_PASSWORD = "password";
SQLiteDatabase mDB; //Variable to hold the SqliteDatabase
//The Database class constructor
public Database(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase(); //<<<<<<<<<< store the Sqlite Database opening it, (if it doesn't exist then onCreate will be called)
}
#Override
public void onCreate(SQLiteDatabase db) {
String crt_tutorialspoint_table = "CREATE TABLE IF NOT EXISTS " + TABLE_TUTORIALSPOINT + "(" +
COLUMN_USERNAME + " VARCHAR, " +
COLUMN_PASSWORD + " VARCHAR" +
")";
db.execSQL(crt_tutorialspoint_table); // Create the table
// Preapre to insert a row using the SQLiteDatabase convenience insert method
ContentValues cv = new ContentValues();
cv.put(COLUMN_USERNAME,"admin");
cv.put(COLUMN_PASSWORD,"admin");
db.insert(TABLE_TUTORIALSPOINT,null,cv);
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
}
You could then use this in an activity; something like :-
public class MainActivity extends AppCompatActivity {
Database mMYDatabaseHelper; // Declare a Database object called mMyDatabaseHelper <<< Note will be null untill instantiated (constructed)
SQLiteDatabase mMySQliteDatabase; // Declares an SQliteDatabase object again will be null
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mMYDatabaseHelper = new Database(this); // Construct the mMyDatabaseHelper (will create the database an insert the row)
mMySQliteDatabase = mMYDatabaseHelper.getWritableDatabase(); // Set/assign sqlite database from the helper to the SqliteDatabase object
// retrieve the rows in the table into a Cursor so the data can be extracted
// Note how the names are obtained from the constants as setup in the Database class.
Cursor mycursor = mMySQliteDatabase.query(Database.TABLE_TUTORIALSPOINT,null,null,null,null,null,null);
// loop through all rows of the cursor
while (mycursor.moveToNext()) {
String username = mycursor.getString(mycursor.getColumnIndex(Database.COLUMN_USERNAME)); // get the username from the current row
String password = mycursor.getString(mycursor.getColumnIndex(Database.COLUMN_PASSWORD)); // get the password from the current row
Log.d("TABLEINFO", "Row " + String.valueOf(mycursor.getPosition() + 1) + " has a username of " + username + " and a password of " + password);
}
mycursor.close(); // Done with the Cursor so close it
//ALL DONE if there are any rows in the table then there should be some output in the Log.
}
Note typically you would have a method in the the Database class (or elsewhere depedning upon coding conventions) such that returns a Cursor rather than access the database in the activities.
Output in the Log :-
D/TABLEINFO: Row 1 has a username of admin and a password of admin

Related

How to return all database results row by row using Cursor - SQLite database *Working*

Currently using an SQlite database with Android studio to build a login app. I am currently trying to retrieve the data from the database row by row and comparing the username and password to the input username and password of the user. Doing this I want to find the matching username and password and then output the corresponding user information.
I am unsure what the best method is for this. I have used a cursor but only seem to be able to return the first values in the database. Would it be best to use an ID column that autoincrements and compare a count value to the ID in a for loop? Or would it be better to output the entire database into an array and then use a count value on the main activity to comb through the array for the necessary information.
Database code:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "BIOSECURE";
public static final String TABLE_NAME = "USER";
public static final String COL_1 = "USERNAME";
public static final String COL_2 = "PASSWORD";
public static final String COL_3 = "FIRSTNAME";
public static final String COL_4 = "SECONDNAME";
public static final String COL_5 = "FINGERPRINT";
public static final String COL_6 = "FACE";
// Basic database
public DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("CREATE TABLE USER ( USERNAME TEXT PRIMARY KEY, PASSWORD TEXT, FIRSTNAME TEXT, SECONDNAME TEXT, FINGERPRINT BLOB, FACE BLOB)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE IF EXISTS USER");
}
// Inserting into database
public boolean insertUserData (String inputUsername, String inputPassword, String inputFirstName, String inputSecondName)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COL_1, inputUsername);
cv.put(COL_2, inputPassword);
cv.put(COL_3, inputFirstName);
cv.put(COL_4, inputSecondName);
// contentValues.put(COL_5, inputFingerprint);
// contentValues.put(COL_6, inputFace);
long result = db.insert(TABLE_NAME,null, cv);
db.close();
return result!= -1;
}
// Not working yet
public Cursor CompareUserData () {
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
return cursor;
Main activity code:
// CHECKING USER LOGIN DETAILS
Cursor cursor = db.CompareUserData();
for (count = 0; count<=cursor.getCount();count++)
{
if (cursor.moveToPosition(count))
{
if (UsernameInput.getText().toString().equals(cursor.getString(0))&&PasswordInput.getText().toString().equals(cursor.getString(1)))
{
passUser = cursor.getString(0);
passPass = cursor.getString(1);
passFirst = cursor.getString(2);
passSecond = cursor.getString(3);
getUser();
getPass();
getFirst();
getSecond();
Toast.makeText(getApplicationContext(), "Successfully logged in", Toast.LENGTH_SHORT).show();
LoginValidation();
}
}
}
if (count > cursor.getCount())
{
Toast.makeText(getApplicationContext(),"Incorrect Username or password",Toast.LENGTH_SHORT).show();
}
A cursor is used to iterate over rows, but will only show one row at a time and must be moved to a different row, which is why it seems to just be showing the first row. You call cursor.moveToFirst(), but you never call any other move*() methods like cursor.moveToNext() or cursor.moveToPosition().
That said, if you want to get the user that was provided by login from your database, getting all the records and iterating is really not the best way to do that. Your second query (SELECT * FROM user WHERE id =) is the right idea. If I understand your goals properly, you want to get one row back and then check the details against that one row. Database engines exist for the purpose of filtering data to return just what you want, don't duplicate its efforts here. Tell it what user id you want, and it will give you back the one user with that id.

Android - SQLite issue with adding more tables to database

First of all I created my prescription_table and that worked.
Then I tried to add a second table to the database called patient_table.
However I am getting this error "
Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
(no such table: patient_table (code 1): , while compiling: INSERT INTO patient_table(PPS,CARINGID,DOB,ADDRESS,SNAME,PATIENTTYPE,PATIENTMEDCON,FNAME) VALUES (?,?,?,?,?,?,?,?))
I tried changing the database version number from 1 to 2 however this made my app crash. I have also tried to uninstall the application from my android device however it is still giving me the same error.
Any help would be grateful.
package com.example.medicationmanagementsystem.DAO;
//code below is based on AndroidSQLite Tutorial Android CRUD Tutorial with SQLite (Create, Read, Update, Delete), ProgrammingKnowledge, https://www.youtube.com/watch?v=kDZES1wtKUY
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DatabaseHelper extends SQLiteOpenHelper {
//Create Database
public static final String DATABASE_NAME = "ManagementSystem.db";
//Create patient table
public static final String TABLE_PATIENT = "patient_table";
public static final String COL_PATIENT_PATIENTID = "PATID";
public static final String COL_PATIENT_FNAME = "FNAME";
public static final String COL_PATIENT_SNAME = "SNAME";
public static final String COL_PATIENT_PPS = "PPS";
public static final String COL_PATIENT_DOB = "DOB";
public static final String COL_PATIENT_ADDRESS = "ADDRESS";
public static final String COL_PATIENT_TYPE = "PATIENTTYPE";
public static final String COL_PATIENT_MEDCOND = "PATIENTMEDCON";
public static final String COL_PATIENT_CARINGID = "CARINGID";
//Create prescription table
public static final String TABLE_PRESCRIPTION = "prescription_table";
public static final String COL_PRESCRIPTION_ID = "PRESCRIPTIONID";
public static final String COL_PRESCRIPTION__PATIENTID = "PATIENTID";
public static final String COL_PRESCRIPTION__DATE = "DATE";
public static final String COL_PRESCRIPTION__DRUGNAME = "DRUGNAME";
public static final String COL_PRESCRIPTION__CONCENTRATION = "CONCENTRATION";
public static final String COL_PRESCRIPTION__DOSAGE = "DOSAGE";
public static final String COL_PRESCRIPTION__PREPARATION = "PREPARATION";
public static final String COL_PRESCRIPTION__STARTDATE = "STARTDATE";
public static final String COL_PRESCRIPTION__ENDDATE = "ENDDATE";
public static final String COL_PRESCRIPTION__DOCTORID = "DOCTORID";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate (SQLiteDatabase db) {
String patienttable = "CREATE TABLE " + TABLE_PATIENT + "(PATID INTEGER PRIMARY KEY AUTOINCREMENT, FNAME TEXT, SNAME TEXT, PPS TEXT, DOB TEXT, ADDRESS TEXT, PATIENTTYPE TEXT, PATIENTMEDCON TEXT, CARINGID INTEGER)";
String prescriptiontable = "CREATE TABLE " + TABLE_PRESCRIPTION + "(PRESCRIPTIONID INTEGER PRIMARY KEY AUTOINCREMENT, PATIENTID INTEGER, DATE TEXT, DRUGNAME TEXT, CONCENTRATION TEXT, DOSAGE TEXT, PREPARATION TEXT, STARTDATE TEXT, ENDDATE TEXT, DOCTORID INTEGER)";
db.execSQL(patienttable);
db.execSQL(prescriptiontable);
this.getReadableDatabase();
this.getWritableDatabase();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+ TABLE_PATIENT);
db.execSQL("DROP TABLE IF EXISTS "+ TABLE_PRESCRIPTION);
onCreate(db);
}
//insert patient data
public boolean insertPatientData(String fname, String sname, String pps, String dob, String address, String patienttype, String patientmedcon, String caringid) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues1 = new ContentValues();
contentValues1.put(COL_PATIENT_FNAME, fname);
contentValues1.put(COL_PATIENT_SNAME, sname);
contentValues1.put(COL_PATIENT_PPS, pps);
contentValues1.put(COL_PATIENT_DOB, dob);
contentValues1.put(COL_PATIENT_ADDRESS, address);
contentValues1.put(COL_PATIENT_TYPE, patienttype);
contentValues1.put(COL_PATIENT_MEDCOND,patientmedcon);
contentValues1.put(COL_PATIENT_CARINGID, caringid);
long result= db.insert(TABLE_PATIENT,null, contentValues1);
if (result == 1)
return false;
else
return true;
}
//insert prescription data
public boolean insertData(String patientid, String date, String drugname, String concentration,String dosage, String preparation, String startdate, String enddate, String doctorid) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues2 = new ContentValues();
contentValues2.put(COL_PRESCRIPTION__PATIENTID, patientid);
contentValues2.put(COL_PRESCRIPTION__DATE, date);
contentValues2.put(COL_PRESCRIPTION__DRUGNAME, drugname);
contentValues2.put(COL_PRESCRIPTION__CONCENTRATION, concentration);
contentValues2.put(COL_PRESCRIPTION__DOSAGE, dosage);
contentValues2.put(COL_PRESCRIPTION__PREPARATION, preparation);
contentValues2.put(COL_PRESCRIPTION__STARTDATE, startdate);
contentValues2.put(COL_PRESCRIPTION__ENDDATE, enddate);
contentValues2.put(COL_PRESCRIPTION__DOCTORID, doctorid);
long result= db.insert(TABLE_PRESCRIPTION,null, contentValues2);
if (result == 1)
return false;
else
return true;
//END
}
//Coding with mitch tutorial
public Cursor getListContents() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor data = db.rawQuery("SELECT * FROM " + TABLE_PRESCRIPTION, null);
return data;
}
}
You should not be trying to open the database (using this.getReadableDatabase or this.getWritableDatabase) in the onCreate method as at this stage a getWritableDatabase is underway and as such you will get an java.lang.IllegalStateException: getDatabase called recursively.
That is when you get an instance of the DatabaseHelper, the database is not created or opened. It's not until you invoke getWritableDatabase (implicitly (e.g. via an insert) or explicitly) that an attempt is made to open the database and create it if it doesn't already exist. Thus calling get????ableDatabase will be a recursion since it is already getting the database.
I tried changing the database version number from 1 to 2 however this
made my app crash.
As onUpgrade is also invoked when getting the database, it calling onCreate also fails because of the recursion.
As such change the onCreate method to be :-
#Override
public void onCreate (SQLiteDatabase db) {
String patienttable = "CREATE TABLE " + TABLE_PATIENT + "(PATID INTEGER PRIMARY KEY AUTOINCREMENT, FNAME TEXT, SNAME TEXT, PPS TEXT, DOB TEXT, ADDRESS TEXT, PATIENTTYPE TEXT, PATIENTMEDCON TEXT, CARINGID INTEGER)";
String prescriptiontable = "CREATE TABLE " + TABLE_PRESCRIPTION + "(PRESCRIPTIONID INTEGER PRIMARY KEY AUTOINCREMENT, PATIENTID INTEGER, DATE TEXT, DRUGNAME TEXT, CONCENTRATION TEXT, DOSAGE TEXT, PREPARATION TEXT, STARTDATE TEXT, ENDDATE TEXT, DOCTORID INTEGER)";
db.execSQL(patienttable);
db.execSQL(prescriptiontable);
//this.getReadableDatabase(); //<<<<< MUST NOT BE USED In onCreate
//this.getWritableDatabase(); //<<<<< MUST NOT BE USED in onCreate
}
Of cousre you would likely delete the lines rather than comment them out.
Before running the App it would be best to uninstall the App (this should overcome the initial issue which is due to onCreate only being called once for the lifetime of the database).
As such, if you change the schema, when developing the App, you would typicaly delete the database (uninstalling the App or deleting the App's data will do this).
Making the amendments above to the onCreate method would also allow increasing the version number to work as it calls onCreat.
P.S. checking the return value from the insert for 1 will only return true for the very fist insert, as only at that stage is the return value (the rowid (PATID and PRESCRIPTIONID will be aliases of the rowid)), for subsquent inserts the value be will be greater than 1.
I'd suggest that instead of using :-
long result= db.insert(.........);
if (result == 1)
return false;
else
return true;
That you use :-
return (db.insert(......) > 0);
or
return (db.insert(......) != -1)
(-1 indicates that no row was inserted).
TESTING
The above has been tested using you Database helper with rows being succesfully inserted.
The following code in an activity was used for the test :-
public class MainActivity extends AppCompatActivity {
DatabaseHelper mDBHlpr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDBHlpr = new DatabaseHelper(this);
mDBHlpr.insertData("1234567890","2018-01-01","X","50","4 times daily","Shake","2018-01-01","2018-03-01","DOC001");
mDBHlpr.insertPatientData("Fred","Bloggs","pps001","1974-01-01","1 Somewhere Street","X","MECON001","001");
Cursor csr = mDBHlpr.getListContents();
while (csr.moveToNext()) {
Log.d("SCRIPTINFO","ID is " +csr.getString(csr.getColumnIndex(DatabaseHelper.COL_PRESCRIPTION_ID)));
}
csr = mDBHlpr.getWritableDatabase().query(DatabaseHelper.TABLE_PATIENT,null,null,null,null,null,null);
while (csr.moveToNext()) {
Log.d("PATIENTINFO","Patient Name is " + csr.getString(csr.getColumnIndex(DatabaseHelper.COL_PATIENT_FNAME)));
}
}
}
The result (from an initial run after uninstalling the App) was :-
2019-11-18 12:57:10.362 D/SCRIPTINFO: ID is 1
2019-11-18 12:57:10.363 D/PATIENTINFO: Patient Name isFred

Android won't save data entered to the SQLite database

I am creating an app which manages ingredients. I want to create an SQLite database which will save all the ingredients which a user enters when they click the save button. However, for some reason my data won't save to the SQLite database. I cannot see what is wrong with the code at all.
DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper
{
private static final String tag = "Database Helper";
private static final String TABLE_NAME = "products_registered";
private static final String col1 = "Name";
private static final String col2 = "Weight";
private static final String col3 = "Price";
private static final String col4 = "Description";
#Override
public void onCreate(SQLiteDatabase db)
{
String createTable = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME +
" (_id INTEGER PRIMARY KEY AUTOINCREMENT," +
col1 + " TEXT NOT NULL," +
col2 + " DOUBLE NOT NULL," +
col3 + " DOUBLE NOT NULL," +
col4 + " TEXT);";
db.execSQL(createTable);
}
public DatabaseHelper(Context context)
{
super(context, TABLE_NAME, null, 1);
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int j)
{
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean addData(String item1, String item2, String item3, String item4)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(col1, item1);
contentValues.put(col2, item2);
contentValues.put(col3, item3);
contentValues.put(col4, item4);
Log.d(tag,"Adding name " + item1 + " to " + TABLE_NAME);
long result = db.insert(TABLE_NAME, null, contentValues);
db.close();
if(result == -1)
{
return false;
}
else
{
return true;
}
}
}
The Register Product Activity
public class RegisterProduct extends AppCompatActivity
{
DatabaseHelper databaseHelper;
private Button saveProductButton;
private EditText productName;
private EditText productWeight;
private EditText productPrice;
private EditText productDescription;
DatabaseHelper mDatabaseHelper;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register_product);
saveProductButton = (Button) findViewById(R.id.saveButton);
productName = (EditText) findViewById(R.id.enterName);
productWeight = (EditText) findViewById(R.id.enterWeight);
productPrice = (EditText) findViewById(R.id.enterPrice);
productDescription = (EditText) findViewById(R.id.enterDescription);
mDatabaseHelper = new DatabaseHelper(this);
try
{
saveProductButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
String nameEntered = productName.getText().toString();
String weightEntered = productWeight.getText().toString();
String priceEntered = productPrice.getText().toString();
String descriptionEntered = productDescription.getText().toString();
addData(nameEntered, weightEntered, priceEntered, descriptionEntered);
productName.setText("");
}
});
}
finally
{
mDatabaseHelper.close();
}
}
public void addData(String newEntry1, String newEntry2, String newEntry3, String newEntry4)
{
mDatabaseHelper.addData(newEntry1, newEntry2, newEntry3, newEntry4);
}
I created a seperate class to create the database and table itself and then created the activity where I called the methods to save the data input in the activity displayed below.
Image of activity display
Your issue is most likely that you have changed the structure/schema of the database probably adding a column since running the App.
Typically you would get an SQLite exception when running the App indicating that the column was not found. However, as you have wrapped the addData in a try/finally construct the exception has been suppressed thus it appears that all is fine as the App doesn't crash or show anything in the log.
Wrapping database code in try constructs and trapping errors, as you have found can be confusing and it is suggested that you don't.
The reason why changing the schema/structure within the code for the onCreate method (the likely root cause of the issue), is that the onCreate method ONLY RUNS automatically when the database is created.
If the schema/structure of the database is changed then you need some way of either forcing the structure change or when developing an App, as the underlying data, should not need to be saved, then the easiest way is to delete the database and then rerun the App.
The database can be deleted by either deleting the App's data or by uninstalling the App (noting that any existing data will be lost).
An alternative, is to DROP the respective table(s) and recreate them. Frequently the onUpgrade method will written to do this. If this is the case (it is in your case) then another way of changing the structure is to trigger the onUpgrage method by increasing the version number pass to the SQLiteOpenHelper constructor (the super call). In your case you could change super(context, TABLE_NAME, null, 1); to be super(context, TABLE_NAME, null, 2);
After deleting the database or increasing the version number (preferably removing the try/finally construct from around the call to addData) and reunning the App, it may well just work. If not then the log should show any exceptions and problems can then be pinpointed.

Method to check Login Details against SQLite database in Android Application not working

relatively new to android development. I am creating an Android Studio Application that allows a user to login to a system by checking the existing email address and password provided against a table created using SQLite. When the user provides an existing email and password an activity starts an intent to change the layout to the home screen. If incorrect an unsuccessful Login attempt Toast message appears.
The database has been created successfully, however the user is automatically signed in regardless of whether the email address or password they provide is correct OR NOT. I am not sure if the rawQuery I am using in the hasObject method is correct.
I have included the RegistrationDatabaseHelper.java class below, with the hasObject method being the final method:
public class RegistrationDatabaseHelper extends SQLiteOpenHelper {
//declaring variable so we can find the name of our database
public static final String DATABASE_NAME = "belfast.db";
public static final String TABLE_NAME = "reg_details_table";
public static final String COL_1 ="ID";
public static final String COL_2 ="EMAIL";
public static final String COL_3 ="USERNAME";
public static final String COL_4 ="PASSWORD";
public static final String COL_5 ="DOB";
public static final String COL_6 ="MOBILE";
//default constructor below
public RegistrationDatabaseHelper(Context context) {
//when the constructor is called it will create your database
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
//creating the table WITHIN the database below
db.execSQL(" create table " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT,EMAIL TEXT,USERNAME TEXT,PASSWORD STRING,DOB TEXT,MOBILE LONG) ");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
//creating a method below to insert data
public boolean insertData(String emailAddress, String userName, String password, String dob, Long mobileNumber){
//we will use this SQLDatabase instance to insert our data
SQLiteDatabase db = this.getWritableDatabase();
//now we need to create an instance of the class ContentValue
ContentValues contentValues = new ContentValues();
//we will now take this contentValues instance and insert it into the data columns
//the first arg is the column name itself, the second is the data itself.
contentValues.put(COL_2, emailAddress);
contentValues.put(COL_3, userName);
contentValues.put(COL_4, password);
contentValues.put(COL_5, dob);
contentValues.put(COL_6, mobileNumber);
//we then insert our data using the db instance created above
//this takes three arguments. The first is the table name, The second is null and the third
//is the contentValues which we have created.
long result = db.insert(TABLE_NAME,null,contentValues);
if (result==-1){
return false;
} else {
return true;
}
}
//creating a method that will show all data that has been entered into the database, using
//elements from the Cursor class. The Cursor interface allows read-write access to the result
public Cursor getAllData(){
//creating an instance of the database class firstly to allow us to get all the data
SQLiteDatabase db = this.getWritableDatabase();
//now we will create an instance of the Cursor class called result and use the
//rawQuery method. Basically creates a SQL query.
Cursor result = db.rawQuery("select * from "+ TABLE_NAME,null);
//we will now return the instance of this cursor, which is "result"
return result;
}
//creating a method that will update all data in our database, using 4 args all of which are
//string, they are id, name, surname and marks
public boolean updateData(String emailAddress, String userName, String password, String dob, Long mobileNumber){
//creating an instance of the database class firstly to allow us to get all the data
SQLiteDatabase db = this.getWritableDatabase();
//now we need to create an instance of the class ContentValue
ContentValues contentValues = new ContentValues();
//we will now take this contentValues instance and insert it into the data columns
//the first arg is the column name itself, the second is the data itself.
contentValues.put(COL_2, emailAddress);
contentValues.put(COL_3, userName);
contentValues.put(COL_4, password);
contentValues.put(COL_5, dob);
contentValues.put(COL_6, mobileNumber);
//the below update method will update any args you pass through here
//the first argument is the table name itself, the second is the contentValues, the third
//is the condition you want to impose, such as "ID = ?" where the ? is the ID provided. The
//fourth arg is the String[] array
db.update(TABLE_NAME, contentValues, "EMAIL = ?", new String[] {emailAddress});
//we will return true to see if the data is really updated or not
return true;
}
public Integer deleteData(String emailAddress){
//creating an instance of the database class firstly to allow us to get all the data
SQLiteDatabase db = this.getWritableDatabase();
//calling the delete function on our db instance. It takes 3 args, 1st is the name of the
//table, the second is the ID number represented by "ID = ?" and the third arg is the String
//Array[] of the argument type id. The return below returns the integer of the ID
return db.delete(TABLE_NAME, "EMAIL = ?", new String[] {emailAddress});
}
public boolean hasObject(String emai){
SQLiteDatabase db = this.getWritableDatabase();
String selectString = "SELECT * FROM " + TABLE_NAME + " WHERE " + COL_2 + "= ?";
Cursor cursor = db.rawQuery(selectString,null);
boolean exist;
if(cursor.getCount()>0){
exist=true;
} else {
exist=false;
}
db.close();
cursor.close();
return exist;
}
}
The SignInActivity.java class is listed below also, with the signIn method determining if the user successfully logins or not:
public class SignInActivity extends Activity {
//creating an instance of the RegistrationDatabaseHelper class
RegistrationDatabaseHelper myDb;
EditText userName;
EditText password;
Button emailSignIn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_in_screen);
myDb = new RegistrationDatabaseHelper(this);
userName = (EditText) findViewById(R.id.etUserName);
password = (EditText) findViewById(R.id.etPass);
emailSignIn = (Button) findViewById(R.id.btnSignIn);
signIn();
}
public void signIn(){
emailSignIn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
boolean recordExists = myDb.hasObject(userName.getText().toString());
if(recordExists=true){
Intent intentSignIn = new Intent(getApplicationContext(), HomePageActivity.class);
Toast.makeText(getApplicationContext(), "Login successful, redirecting to Home Page.", Toast.LENGTH_LONG).show();
startActivity(intentSignIn);
} else {
Toast.makeText(getApplicationContext(), "Invalid credentials, please try again.", Toast.LENGTH_LONG).show();
}
}
});
}
}
Does anyone know why the user is logged in regardless of the input? As I said I'm relatively new to android development and am not sure where I am going wrong, so any advice at all would be greatly appreciated. Many thanks in advance!
I am not sure if the rawQuery I am using in the hasObject method is correct. No, it's not:
Cursor cursor = db.rawQuery(selectString,null);
You're not passing the parameter (?) you intended to use in your WHERE clause.
Instead, you're passing null.
Correct implementation:
Cursor cursor = db.rawQuery(selectString, new String[]{"Your search string here"});
Don't worry about the single quotes (SQL string delimiters): they'll be added automatically as needed.

Android SQLite database sharing across activities

Background info: new to Android, not to Java.
I am writing an app that sends its own messages separately from the default Android sms app. Since my app is not the default, I can't write to Android's provider.sms.outbox, which is absolutely fine. To work around this, I am creating a SQLite database to store my app's outgoing messages (in message objects). I am struggling to find a good, detailed explanation/tutorial on how to create a SQLite database that is available across all of my activities. I only have 2 activities; one that reads the database, and one that reads/writes the database.
I know that I need to create a subclass of the SQLiteOpenHelper, and I have:
public class dbHelper extends SQLiteOpenHelper {
//Database Info
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "outgoingMsgs.db";
public static final String TABLE_MESSAGES = "messages";
//Table Info
public static final String COLUMN_ID = "id";
public static final String COLUMN_SEND_TO_NAME = "send_to_name";
public static final String COLUMN_SEND_TO_NUM = "send_to_num";
public static final String COLUMN_BODY = "msg_body";
public dbHelper(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
//table creation...
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_MESSAGES_TABLE = "CREATE TABLE " + TABLE_MESSAGES +
"(" + COLUMN_ID + " INTEGER PRIMARY KEY," + COLUMN_SEND_TO_NAME + " TEXT," +
COLUMN_SEND_TO_NUM + " TEXT," + COLUMN_BODY + " TEXT" + ")";
db.execSQL(CREATE_MESSAGES_TABLE);
}
//database version upgrade... destroys old and recreates
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_MESSAGES);
onCreate(db);
}
//adds single record
public void addRecord(myMessage msg){
SQLiteDatabase dbase = this.getWritableDatabase();
ContentValues vals = new ContentValues();
//fill vals with appropriate content
vals.put(COLUMN_SEND_TO_NAME, msg.get_name());
vals.put(COLUMN_SEND_TO_NUM, msg.get_number());
vals.put(COLUMN_BODY, msg.getBody());
//insert
dbase.insert(TABLE_MESSAGES, null, vals);
dbase.close();
}
public int getRecordCount(){
String countQuery = "SELECT * FROM " + TABLE_MESSAGES;
SQLiteDatabase dbase = this.getReadableDatabase();
Cursor cursor = dbase.rawQuery(countQuery, null);
cursor.close();
return cursor.getCount();
}
//deletes a single record
public void deleteRecord(myMessage msg){
SQLiteDatabase dbase = this.getWritableDatabase();
dbase.delete(TABLE_MESSAGES, COLUMN_ID + " = ?",
new String[] { String.valueOf(msg.get_id()) });
dbase.close();
}
}
Now, my problem is that I cannot figure out where (in which Activity or even in an Activity) or how I should create the instance of my dbHelper to make it available across my 2 activities. I know the singleton pattern is used frequently and the ContentProvider method is preferred. I don't feel that I'm ready to use ContentProviders with my very limited Android knowledge, so I would like to explore the singleton method. Can anyone please help me through this process?
how I should create the instance of my dbHelper to make it available
across my 2 activities
For what? You can just create a new instance for each Activity, since they use the very same database (outgoingMsgs.db).
For example, if you call addRecord in Activity A and use the different instance of dbHelper in Activity B to call getRecordCount, the inserted data will be selected.
You can use an Abstract class like this.
public abstract class DBAbstract extends Activity {
private DBHelper mDBHelper;
protected DBHelper getHelper(){
if(mDBHelper == null){
mDBHelper = OpenHelperManager.getHelper(this, DBHelper.class);
}
return mDBHelper;
}
protected int getDBVersion(){
return mDBHelper.getDatabaseVersion();
}
#Override
protected void onDestroy(){
super.onDestroy();
if(mDBHelper != null){
OpenHelperManager.releaseHelper();
mDBHelper = null;
}
}
And use it in your new activities.
public class YourActivity extends DBAbstract
I'm using this and it's working perfectly

Categories

Resources