Cant get a database connection as I cant pass context to DBManager - java

I have a Dummy Data manager that will populate an ArrayList with the content of a SQLite database. When I try to create a DB object I get an error stating Says 'com.example.listview.manager.ActivityDummyDataManager.this' cannot be referenced from a static context.
package com.example.listview.manager;
import android.database.Cursor;
import com.example.listview.DBManager;
import com.example.listview.model.ActivityItem;
import java.util.ArrayList;
public class ActivityDummyDataManager {
public static ArrayList<ActivityItem> getActivityItemList() {
DBManager db = new DBManager(this);
Cursor cursor = db.fetch();
ArrayList<com.example.listview.model.ActivityItem> list = new ArrayList<>();
while (cursor.moveToNext()) {
int index;
index = cursor.getColumnIndexOrThrow("id");
Long id = cursor.getLong(index);
index = cursor.getColumnIndexOrThrow("activity");
String activity = cursor.getString(index);
index = cursor.getColumnIndexOrThrow("description");
String description = cursor.getString(index);
index = cursor.getColumnIndexOrThrow("description");
String date = cursor.getString(index);
ActivityItem item = new ActivityItem();
item.setId(id);
item.setActivity(activity);
item.setDescription(description);
item.setDate(date);
list.add(item);
}
return list;
}
}
I have a DBManager class I would normally access using DBManager db = new DBManager(this) but for some reason, this will not work from this class.
package com.example.listview;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class DBManager {
private DatabaseHelper dbHelper;
private Context context;
private SQLiteDatabase database;
public DBManager(Context c) {
context = c;
}
public DBManager open() throws SQLException {
dbHelper = new DatabaseHelper(context);
database = dbHelper.getWritableDatabase();
return this;
}
public void close() {
dbHelper.close();
}
public void insert(String activity, String description, String date) {
ContentValues contentValue = new ContentValues();
contentValue.put(DatabaseHelper.ACTIVITY, activity);
contentValue.put(DatabaseHelper.DESCRIPTION, description);
contentValue.put(DatabaseHelper.DATE, date);
database.insert(DatabaseHelper.TABLE_NAME, null, contentValue);
}
public Cursor fetch() {
String[] columns = new String[] {
DatabaseHelper._ID,
DatabaseHelper.ACTIVITY,
DatabaseHelper.DESCRIPTION,
DatabaseHelper.DATE
};
Cursor cursor = database.query(DatabaseHelper.TABLE_NAME, columns, null,
null, null, null, "DATE DESC");
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
}
public Cursor fetchForEdit(String id) {
String[] columns = new String[] {
DatabaseHelper._ID,
DatabaseHelper.ACTIVITY,
DatabaseHelper.DESCRIPTION,
DatabaseHelper.DATE
};
String [] args = new String [] {id};
Cursor cursor = database.query(DatabaseHelper.TABLE_NAME, columns, "_ID=?",
args, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
Log.d("DATABASE", "cursor= "+cursor.getColumnName(1));
return cursor;
}
public int update(long _id, String activity, String description, String date) {
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseHelper.ACTIVITY, activity);
contentValues.put(DatabaseHelper.DESCRIPTION, description);
contentValues.put(DatabaseHelper.DATE, date);
int i = database.update(
DatabaseHelper.TABLE_NAME, contentValues,
DatabaseHelper._ID + " = " + _id,
null);
return i;
}
public void delete(long _id) {
database.delete(DatabaseHelper.TABLE_NAME,
DatabaseHelper._ID + "=" + _id,
null);
}
}
Why can't I set the DBManager db = new DBManager(this); to get a DB connection.
Says 'com.example.listview.manager.ActivityDummyDataManager.this'
cannot be referenced from a static context.
Could someone also explain the context argument as I don't really understand it.

Your Constructor DBManager(Context c) expects a context as parameter, If you call this constructor from Activity or Service class it will work as both Activity and Service are sub-classes of Context, So passing this should suffice. As ActivityDummyDataManager does not handle context you need to pass Context either from activity or you can pass application context getApplicationContext().
Change your method as below
public static ArrayList<ActivityItem> getActivityItemList() {
DBManager db = new DBManager(mContext);
//rest of your code.
}
and while calling it use activity or application context whichever is suitable.

Related

Querying already exsiting database returns empty cursor

I'm not very familiar with sql but what I'm am simply trying to do is get two values from an already created database file."Balance" and "VoucherBalance". While I attempt to query the database I get either get back an empty cursor when I add the third and forth params to the query method, or if I leave third and forth params as null I get back a count of 1 which is just the names of the two columns I'm trying to acquire.
Why am I not getting the values when I am specifying which ones I want?
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import android.widget.Toast;
import java.util.Arrays;
public class DataBaseReader extends SQLiteOpenHelper
{
private static final String TAG = "DataBaseReader";
private static String DB_PATH = "/data/data/PACKAGENAME/databases/DATABAENAME.db";
private static String DB_NAME = "TABLENAME";
private SQLiteDatabase database;
public double balance;
public int voucher;
private final Context myContext;
public String text = "";
public DataBaseReader(Context context)
{
super(context, DB_NAME, null, 1);
this.myContext = context;
}
public void getWireAccountBalance()
{
String[] projection = {DatabaseContract.Database.COLUMN_BALANCE, DatabaseContract.Database.COLUMN_VOUCHER};
String[] selectionArgs = {"Balance", "VoucherBalance"};
String selection = DatabaseContract.Database.COLUMN_BALANCE + "=?" + " AND " + DatabaseContract.Database.COLUMN_VOUCHER + "=?";
SQLiteDatabase db = SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READONLY);
Cursor cursor = db.query(DatabaseContract.Database.TABLE_NAME, projection, selection, selectionArgs, null, null, null);
Log.d(TAG, "Cursor count is " + String.valueOf(cursor.getCount()));
text = Arrays.toString(cursor.getColumnNames());
Toast.makeText(myContext, text, Toast.LENGTH_LONG).show();
if (cursor.moveToFirst())
{
while (!cursor.moveToNext())
{
balance = cursor.getFloat(cursor.getColumnIndex(DatabaseContract.Database.COLUMN_BALANCE));
voucher = cursor.getInt(cursor.getColumnIndex(DatabaseContract.Database.COLUMN_VOUCHER));
}
} else
{
Log.d(TAG, "Cursor count is " + String.valueOf(cursor.getCount()));
}
}
#Override
public synchronized void close()
{
super.close();
if (database != null)
{
close();
}
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase)
{
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1)
{
}
}
Using moveTofirst moves to the first row, you then use moveToNext, which will return false (when there is just the one row), skipping the first row.
I'd suggest using :-
while(cursor.moveToNext()) {
balance = cursor.getFloat(cursor.getColumnIndex(DatabaseContract.Database.COLUMN_BALANCE));
voucher = cursor.getInt(cursor.getColumnIndex(DatabaseContract.Database.COLUMN_VOUCHER));
}
instead of :-
if (cursor.moveToFirst())
{
while (!cursor.moveToNext())
{
balance = cursor.getFloat(cursor.getColumnIndex(DatabaseContract.Database.COLUMN_BALANCE));
voucher = cursor.getInt(cursor.getColumnIndex(DatabaseContract.Database.COLUMN_VOUCHER));
}
} else
{
Log.d(TAG, "Cursor count is " + String.valueOf(cursor.getCount()));
}

Unable to delete data from SQLite

I am having issues when trying to clear the entries from a Arraylist in Android studio, not matter what code I try the app either does nothing or as with the code below crashes. I'm pulling my hair out with this as in my mind it should work.
I have also tried (not included in the code):
odb.rawquery(" delete from DATABASE_TABLE") //from memory so may not be 100%
This crashed the app and it would not reload, I'm assuming that it was successful in removing the table and not re-creating it?
It will be running on KitKat
Have I missed anything?
This is the last thing I need to make it work so any help or suggestions would be great!
TIA
Main
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class MainActivity extends Activity {
private ListView list_lv;
private EditText col2_ed;
private Button sub_btn;
Button del_btn;
private DBclass db;
private ArrayList<String> collist_2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
collist_2 = new ArrayList<String>();
items();
getData();
DeleteData();
}
private void items() {
sub_btn = (Button) findViewById(R.id.submit_btn);
del_btn = (Button) findViewById(R.id.delete_btn);
col2_ed = (EditText) findViewById(R.id.ed2);
list_lv = (ListView) findViewById(R.id.dblist);
sub_btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
submitData();
}
});
}
public void DeleteData(){
del_btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
db.deleteData();
}
});
}
protected void submitData() {
String b = col2_ed.getText().toString();
db = new DBclass(this);
long num;
db.open();
num = db.insertmaster(b);
db.close();
getData();
}
public void getData() {
collist_2.clear();
db = new DBclass(this);
try {
db.open();
Cursor cur = db.getAllTitles();
while (cur.moveToNext()) {
String valueofcol2 = cur.getString(2);
collist_2.add(valueofcol2);
}
}
finally {
db.close();
}
printList();
setDataIntoList();
}
private void printList() {
for (int i = 0; i < collist_2.size(); i++) {
}
}
private void setDataIntoList() {
// create the list item mapping
String[] from = new String[] { "col_2" };
int[] to = new int[] { R.id.col2tv };
// prepare the list of all records
List<HashMap<String, String>> fillMaps = new ArrayList<HashMap<String, String>>();
for (int i = 0; i < collist_2.size(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
map.put("col_2", collist_2.get(i));
fillMaps.add(map);
}
// fill in the grid_item layout
SimpleAdapter adapter = new SimpleAdapter(this, fillMaps,
R.layout.custom, from, to);
list_lv.setAdapter(adapter);
}
}
DBclass
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBclass {
public String KEY_ROWID = "_id";
public String KEY_COL2 = "col2";
private String DATABASE_NAME = "mydb";
private String DATABASE_TABLE = "mytable";
private int DATABASE_VERSION = 1;
private Context ourContext;
private DbHelper dbh;
private SQLiteDatabase odb;
private String USER_MASTER_CREATE =
"CREATE TABLE IF NOT EXISTS " + DATABASE_TABLE+ "("
+ KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_COL2 + " VARCHAR(15) )";
private class DbHelper extends SQLiteOpenHelper {
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(USER_MASTER_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// if DATABASE VERSION changes
// Drop old tables and call super.onCreate()999
}
}
public DBclass(Context c) {
ourContext = c;
dbh = new DbHelper(ourContext);
}
public DBclass open() throws SQLException {
odb = dbh.getWritableDatabase();
return this;
}
public void close() {
dbh.close();
}
public long insertmaster(String col2) throws SQLException{
ContentValues IV = new ContentValues();
IV.put(KEY_COL2, col2);
return odb.insert(DATABASE_TABLE, null, IV);
// returns a number >0 if inserting data is successful
}
public void updateRow(long rowID, String col2) {
ContentValues values = new ContentValues();
values.put(KEY_COL2, col2);
odb.update(DATABASE_TABLE, values, KEY_ROWID + "=" + rowID, null);
}
public void deleteData(){
odb.delete(DATABASE_TABLE, null,null);
}
public Cursor getAllTitles() {
// using simple SQL query
return odb.rawQuery("select * from " + DATABASE_TABLE, null);
}
public Cursor getallCols(String id) throws SQLException {
Cursor mCursor = odb.query(DATABASE_TABLE, new String[] { KEY_COL2 }, null, null, null, null, null);
Log.e("getallcols zmv", "opening successfull");
return mCursor;
}
public Cursor getColsById(String id) throws SQLException {
Cursor mCursor = odb.query(DATABASE_TABLE, new String[] { KEY_COL2 }, KEY_ROWID + " = " + id, null, null, null, null);
Log.e("getallcols zmv", "opening successfull");
return mCursor;
}
}
I think you're not opening the database before trying to delete.
public void DeleteData(){
del_btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Try adding these lines
try {
db = new DBclass(this);
db.open();
db.deleteData();
}catch(Exception e){
e.print
}finally{
db.close();
}
}
});
}
Add this in DBclass will delete all data from the particular table
public void deleteAll(){
SQLiteDatabase db = this.getWritableDatabase();
String deleteStmt="DELETE FROM "+TABLE_NAME;
db.execSQL(deleteStmt);
db.close();
}
Deleting a single row or single item (where item is the model class or you can pass the keyId/primarykey )
// Deleting single Item
public void deleteItem(Item item) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME, KEY_ID + " = ?",
new String[] { String.valueOf(item.getKeyId()) });
db.close();
}
Also please refer the below link :
https://www.androidhive.info/2013/09/android-sqlite-database-with-multiple-tables/

Android Studio issue with static method declaration

I am currently trying to make a project which will create a database that has 3 elements, ID, NAME, and STATUS. Then I need to store all of those values into 3 list views which are all on the same activity. Here is my sqlite code:
package com.example.mikediloreto.sqliteproject;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
public class myDB extends SQLiteOpenHelper{
private static final int DB_VERSION = 1;
private static final String TB_Student = "student";
public static final String ID = "id";
public static final String NAME = "name";
public static final String STATUS = "status";
public myDB(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
super(context, name, factory, version, errorHandler);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("Create Table " + TB_Student + " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " + NAME + " TEXT NOT NULL, " + STATUS + " TEXT" + ");");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public Cursor getStudents() {
String[] cols = new String[] { ID, NAME, STATUS};
SQLiteDatabase db = getReadableDatabase();
return db.query(TB_Student, cols, null, null, null, null, NAME);
}
public Cursor getStudent(int studentId) {
String[] cols = new String[] { ID, NAME, STATUS};
String sel = ID + "=?";
String[] selArgs = new String[] { String.valueOf(studentId)};
SQLiteDatabase db = getReadableDatabase();
return db.query(TB_Student, cols, sel, selArgs, null, null, null);
}
public long numStudents() {
SQLiteDatabase db = getReadableDatabase();
SQLiteStatement st = db.compileStatement("SELECT COUNT(1) " + "FROM "+ TB_Student + ";");
return st.simpleQueryForLong();
}
public long addStudent(String name, String status) {
ContentValues cv = new ContentValues();
cv.put(NAME, name);
cv.put(STATUS, status);
SQLiteDatabase db = getWritableDatabase();
return db.insert(TB_Student, null, cv);
}
public boolean delStudent(int studentId) {
String sel = ID + "=?";
String[] selArgs = new String[] { String.valueOf(studentId) };
SQLiteDatabase db = getReadableDatabase();
return (db.delete(TB_Student, sel, selArgs) > 0);
}
}
and here is my main activity:
package com.example.mikediloreto.sqliteproject;
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.*;
public class MainActivity extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv1=(ListView)this.findViewById(R.id.leftListView);
ListView lv2=(ListView)this.findViewById(R.id.centerListView);
ListView lv3=(ListView)this.findViewById(R.id.rightListView);
setListAdapter(new SimpleCursorAdapter(this, R.layout.*, myDB.getStudents(), new String [] { myDB.ID, myDB.NAME, myDB.STATUS }, new int[] { android.R.id.text1 }, 0));
}
}
The problem I am having is that when I call myDB.getStudents(), it tells me that I need to make the method declaration static, but if I make it static, then I get an error telling me that it can't to be static for getReadableDatabase() to work. Not sure where to go from here, also if there is anything else blatantly wrong let me know.
Also the console is telling me there is an error when I use R.layout.*, and the fix is to put it after the getStudents() call.
Edit: Creating an instance variable worked. Thanks for all the help.
Your problem is that you can't use class names to access non static public methods within a class .
So you can use myDB mMyDB; and use Class object to access the getStudents method .
And you can make your method static
And in your myDB .You can change to this .
public myDB(Context contextr) {
super(context, NAME , null , DB_VERSION , mull);
}
And in your MainActivity .
public class MainActivity extends ListActivity {
myDB mMyDB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv1=(ListView)this.findViewById(R.id.leftListView);
ListView lv2=(ListView)this.findViewById(R.id.centerListView);
ListView lv3=(ListView)this.findViewById(R.id.rightListView);
mMyDB = new myDB(this);
// edited here , change the layout
setListAdapter(new SimpleCursorAdapter(this, R.layout.your_layout, mMyDB.getStudents(), new String [] { myDB.ID, myDB.NAME, myDB.STATUS }, new int[] { android.R.id.text1 }, 0));
}
}
Edit
You should change R.layout.your_layout to the layout you have .
Note
And then modify your class name, this writing is not very standardized .
Sample like MyDB
The class name of the first letter should be uppercase.

Cant validate Login on Android app using a SQLite db

I am having a problem validating my login for my android app. I have 2 fields that require user to enter email and password, if both exist in db then they will be taken to mainscreen (log in successful) if incorrect error will appear. I have tried everything but still doesnt work! Please help I have posted my code below.
package com.example.finalproject;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class LoginActivity extends Activity implements OnClickListener{
EditText mEmailAdd;
EditText mPassword;
private SQLiteAdapter mydb = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_activity);
//addListenerOnButton();
}
public void onCreateMainscreen(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.screenmain_activity);
Button mNewUser = (Button)findViewById(R.id.btnLogMain);
mNewUser.setOnClickListener(this);
}
public void onClick(View v) {
switch(v.getId()){
case R.id.btnLogMain:
mEmailAdd = (EditText)findViewById(R.id.email);
mPassword = (EditText)findViewById(R.id.password);
String uname = mEmailAdd.getText().toString();
String pass = mPassword.getText().toString();
if(uname.equals("") || uname == null){
Toast.makeText(getApplicationContext(), "email Empty", Toast.LENGTH_SHORT).show();
}else if(pass.equals("") || pass == null){
Toast.makeText(getApplicationContext(), "Password Empty", Toast.LENGTH_SHORT).show();
}else{
boolean validLogin = validateLogin(uname, pass, LoginActivity.this);
if(validLogin){
System.out.println("In Valid");
Intent i = new Intent(LoginActivity.this, MainMenuActivity.class);
startActivity(i);
finish();
}
}
break;
}
}
// #SuppressWarnings("deprecation")
public boolean validateLogin(String uemail, String pass, Context context) {
mydb = new SQLiteAdapter(this);
SQLiteAdapter db = mydb.openToWrite();
//SELECT
String[] columns = {"_id"};
//WHERE clause
String selection = "email=? AND password=?";
//WHERE clause arguments
String[] selectionArgs = {uemail,pass};
Cursor cursor = null;
try{
//SELECT _id FROM login WHERE email=uemail AND password=pass
cursor = db.query(SQLiteAdapter.MYDATABASE_TABLE, columns, selection, selectionArgs, null, null, null);
// startManagingCursor(cursor);
}catch(Exception e){
e.printStackTrace();
}
int numberOfRows = cursor.getCount();
if(numberOfRows <= 0){
Toast.makeText(getApplicationContext(), "Failed..\nTry Again", Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
public void onDestroy(){
super.onDestroy();
mydb.close();
}
}
DATABASE CLASS
package com.example.finalproject;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
public class SQLiteAdapter {
public static final String MYDATABASE_NAME = "MY_PROJECT_DATABASE";
public static final String MYDATABASE_TABLE = "MY_USERS_TABLE";
public static final int MYDATABASE_VERSION = 1;
public static final String KEY_ID = "_id";
public static final String KEY_NAME = "name";
public static final String KEY_EMAIL = "email";
public static final String KEY_PASSWORD = "password";
//create table MY_DATABASE (ID integer primary key, Content text not null);
private static final String SCRIPT_CREATE_DATABASE =
"create table " + MYDATABASE_TABLE + " ("
+ KEY_ID + " integer primary key autoincrement, "
+ KEY_NAME + " text not null, "
+ KEY_EMAIL + " text not null, "
+ KEY_PASSWORD + " text not null);";
private SQLiteHelper sqLiteHelper;
private SQLiteDatabase sqLiteDatabase;
private Context context;
public SQLiteAdapter(Context c){
context = c;
}
public SQLiteAdapter openToRead() throws android.database.SQLException {
sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null, MYDATABASE_VERSION);
sqLiteDatabase = sqLiteHelper.getReadableDatabase();
return this;
}
public SQLiteAdapter openToWrite() throws android.database.SQLException {
sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null, MYDATABASE_VERSION);
sqLiteDatabase = sqLiteHelper.getWritableDatabase();
return this;
}
public void close(){
sqLiteHelper.close();
}
public long insert(String name, String email, String password){
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_NAME, name);
contentValues.put(KEY_EMAIL, email);
contentValues.put(KEY_PASSWORD, password);
return sqLiteDatabase.insert(MYDATABASE_TABLE, null, contentValues);
}
public int deleteAll(){
return sqLiteDatabase.delete(MYDATABASE_TABLE, null, null);
}
public Cursor queueAll(){
String[] columns = new String[]{KEY_ID, KEY_NAME, KEY_EMAIL,KEY_PASSWORD};
Cursor cursor = sqLiteDatabase.query(MYDATABASE_TABLE, columns,
null, null, null, null, null);
return cursor;
}
public class SQLiteHelper extends SQLiteOpenHelper {
public SQLiteHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(SCRIPT_CREATE_DATABASE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
}
not your error, but change
if(uname.equals("") || uname == null){ // throws nullpointerexception if uname == null
to
if(uname == null || uname.length() == 0 ){ // throws no exception and also checks the " "
Not sure if this was just a copy-paste error but the code as provided not only doesn't compile, but never sets up the click listener for the login button either. Here's what I modified to make it both compile and query the database.
In SQLiteAdapter:
public SQLiteDatabase openToWrite() throws android.database.SQLException {
sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null,
MYDATABASE_VERSION);
sqLiteDatabase = sqLiteHelper.getWritableDatabase();
return sqLiteDatabase;
}
In LoginActivity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_activity);
//addListenerOnButton();
Button mNewUser = (Button)findViewById(R.id.btnLogMain);
mNewUser.setOnClickListener(this);
}
public void onCreateMainscreen(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.screenmain_activity);
Button mNewUser = (Button)findViewById(R.id.btnLogMain);
mNewUser.setOnClickListener(this);
}
public boolean validateLogin(String uemail, String pass, Context context) {
mydb = new SQLiteAdapter(this);
SQLiteDatabase db = mydb.openToWrite();
//SELECT
String[] columns = {"_id"};
//WHERE clause
String selection = "email=? AND password=?";
//WHERE clause arguments
String[] selectionArgs = {uemail,pass};
Cursor cursor = null;
try{
//SELECT _id FROM login WHERE email=uemail AND password=pass
cursor = db.query(SQLiteAdapter.MYDATABASE_TABLE, columns, selection, selectionArgs, null, null, null);
// startManagingCursor(cursor);
}catch(Exception e){
e.printStackTrace();
}
int numberOfRows = cursor.getCount();
if(numberOfRows <= 0){
Toast.makeText(getApplicationContext(), "Failed..\nTry Again", Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
Note also that this code will never insert anything into the database, either. I assume this will be done elsewhere. Further there are many naming convention and general good practices being broken here.
A few issues:
Never do database work on the main thread.
Variables prefixed with 'm' indicate they are member variables of the class.
Be sure to use the #Override notation when appropriate.

close() was not explicity called on database

I need to know where to call the db.close() in my code. I've added it on onCreate() method, but when I need to use some methods it says database not open, and then I've removed from onCreate() and it says close() was not explicity called. so where should I close, could it be inside each method of the class??
here is the code:
public class HoursPerDayDataHelper {
private static final String DATABASE_NAME = "database.db";
private static final int DATABASE_VERSION = 1;
protected static final String TABLE_NAME = "table";
protected String TAG = "HoursPerDayDataHelper";
private Context context;
private SQLiteDatabase db;
OpenHelper openHelper = null;
public HoursPerDayDataHelper(Context context) {
this.context = context;
openHelper = new OpenHelper(this.context);
this.db = openHelper.getWritableDatabase();
openHelper.onCreate(db);
}
public void close() {
if (openHelper != null) {
openHelper.close();
}
}
public void deleteAll() {
this.db.delete(TABLE_NAME, null, null);
}
public String selectDuration(String date) {
String duration = "";
Integer value = 0;
String returnment = "";
Log.i(TAG, "date do select: " + date);
Cursor cursor = this.db.query(TABLE_NAME, new String[] { "duration" },
"date = ? ", new String[]{ date }, null, null, null);
Log.i(TAG, "cursor string " + cursor);
if (cursor.moveToFirst()) {
do {
Log.i(TAG, "dentro do if cursor");
duration = cursor.getString(0);
value += Integer.parseInt(duration);
} while (cursor.moveToNext());
returnment = Integer.toString(value);
}else{
Log.i(TAG, "bla bla bla");
}
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
return returnment;
}
public ArrayList<String[]> selectTopContacts() {
ArrayList<String[]> list1 = new ArrayList<String[]>();
Cursor cursor = this.db.query(TABLE_NAME, null, null, null, null, null,
"duration desc");
if (cursor.moveToFirst()) {
do {
if (cursor.getString(2) != "") {
String[] data = new String[4];
data[0] = cursor.getString(2);
data[1] = cursor.getString(4);
data[2] = cursor.getString(5);
data[3] = cursor.getString(7);
list1.add(data);
} else {
String[] data = new String[3];
data[1] = cursor.getString(4);
data[2] = cursor.getString(5);
data[3] = cursor.getString(7);
list1.add(data);
}
} while (cursor.moveToNext());
}
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
return list1;
}
public static class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS "
+ TABLE_NAME
+ "(id INTEGER PRIMARY KEY AUTOINCREMENT, duration TIME, date DATE, current_time TIME)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w("HoursPerDay Database",
"Upgrading database, this will drop tables and recreate.");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
}
And this is my Activity:
public class HoursPerDay extends Activity{
private String LOG_TAG = "HoursPerDay";
private TextView mDateDisplay;
public String date;
private int mYear;
private int mMonth;
private int mDay;
private int newDay;
private String hpdData;
private HoursPerDayDataHelper hpd;
OpenHelper openHelper = new OpenHelper(HoursPerDay.this);
static final int DATE_DIALOG_ID = 0;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hours_per_day);
hpd = new HoursPerDayDataHelper(this);
// capture our View elements
mDateDisplay = (TextView) findViewById(R.id.dateDisplay);
// get the current date
final Calendar c = Calendar.getInstance();
mYear = c.get(Calendar.YEAR);
mMonth = c.get(Calendar.MONTH);
mDay = c.get(Calendar.DAY_OF_MONTH);
// display the current date (this method is below)
}
#Override
protected void onDestroy() {
super.onDestroy();
if (openHelper != null) {
openHelper.close();
}
if (hpd != null) {
hpd.close();
}
}
// the callback received when the user "sets" the date in the dialog
private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
mYear = year;
mMonth = monthOfYear;
mDay = dayOfMonth;
setBasicContent();
hpd.close();
}
};
protected Dialog onCreateDialog(int id) {
switch (id) {
case DATE_DIALOG_ID:
return new DatePickerDialog(this,
mDateSetListener,
mYear, mMonth, mDay);
}
return null;
}
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.layout.hoursperdaymenu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case R.id.filter_by_day:
showDialog(DATE_DIALOG_ID);
return true;
case R.id.filter_by_user:
showDialog(DATE_DIALOG_ID);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void setBasicContent() {
date = (mMonth + 1) + "/" + newDay + "/" + mYear;
hpdData = this.hpd.selectDuration(date);
mDateDisplay.setText(hpdData);
hpd.close();
}
}
I think there are 2 ways:
in onPause-method and check there isFinishing if yes -> close. Problem: if your app gets killed by app-killer, db remains open.
You open and close the DB each time (methods) you read/write.
EDIT:
Ok, I see why it could be caused. I think you misunderstood the usage of the SQLiteOpenHelper. You never have to call the onCreate-method.
Defently the better way is to make a DBHelper class and use it in a separate calls, lets say SQLDataHandler.
Your activity look good. I changed a few things, look if it helps. I'll mark them:
That's all what should be in the Helper class:
public static class OpenHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "database.db";
private static final int DATABASE_VERSION = 1;
protected static final String TABLE_NAME = "table";
protected String TAG = "HoursPerDayDataHelper";
Just leave it CREATE TABLE it gets only created/called if there isn't one existing.
I have seen errors occurring if the String is passed directly
#Override
public void onCreate(SQLiteDatabase db) {
String query = "CREATE TABLE "
+ TABLE_NAME
+ "(id INTEGER PRIMARY KEY AUTOINCREMENT, duration TIME, date DATE, current_time TIME)";
db.execSQL(query);
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
To use it:
Just call in your DataHandler class :
OpenHelper helper = new OpenHelper(ctx);
// SQLiteDatabase db = helper.getReadableDatabase();
SQLiteDatabase db = helper.getWritableDatabase();
All other stuff, like deleting, adding and so on, should be done in a "DataHandler" class.
Just use the same two methods there to get your DB. At the end, when you are finished, you call just in you DataHandler class db.close().
Like this the activity itself never uses de DB directly. Better practice I think ;)
I hope it helps. For any other questions, just ask :)
EDIT2:
First, in general it should work with a inner class.
BUT: In case you want to add another table from another class it won't work anymore. Thats why it's the better way to put it in a separate class from beginning. It's even reusable (with some smal adjustments).
Put the code I posted in your class OpenHelper. Nothing more.
Then, put the data manipulation stuff in a class called something like: DataHandlerDB.
Code example:
package ...;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class DataHandlerDB {
public static void persistAll(Context ctx, List<Module> moduleList) {
DatabaseHelper helper = new DatabaseHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
for (Module m : moduleList) {
values.put("_id", m.get_id());
values.put("name", m.getModule());
db.insert("module", null, values);
}
db.close();
}
public static List<Module> findAll(Context ctx) {
List<Module> result = new ArrayList<Module>();
DatabaseHelper helper = new DatabaseHelper(ctx);
SQLiteDatabase db = helper.getReadableDatabase();
Cursor c = db.query(ModuleDB.TABLE_NAME, new String[] { ModuleDB.ID,
ModuleDB.MODULE}, null, null, null, null, null);
while (c.moveToNext()) {
Module m = new Module(c.getInt(0), c.getString(1));
result.add(m);
}
c.close();
db.close();
return result;
}
// Update Database entry
public static void update(Context ctx, Module m) {
DatabaseHelper helper = new DatabaseHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("_id", m.get_id());
values.put("name", m.getModule());
db.update("module", values, null, null);
db.close();
}
public static void delete(Context ctx, Module m) {
DatabaseHelper helper = new DatabaseHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("_id", m.get_id());
values.put("name", m.getModule());
db.delete("module","_id = m.get_id()", null);
db.close();
}
public static void createDB(Context ctx) {
DatabaseHelper helper = new DatabaseHelper(ctx);
SQLiteDatabase db = helper.getWritableDatabase();
db.close();
}
}
In order to be more efficient the methods are static, you won't need to create objects.
Use it like this: In your activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get the a writable DB, in case it's not existing it gets created.
DataHandlerDB.createDB(this);
// get stuff out of DB
moduleList = DataHandlerDB.findAll(this);
adapter = new ArrayAdapter<Module>(this,
android.R.layout.simple_list_item_1, moduleList);
setListAdapter(adapter);
}
if you open in onCreate, then close in onDestroy

Categories