I am new to Android Studio and I am trying to create an Inventory App that allows users to create their own inventory items. I am using SQlite database to do this. I've created my DBHelper class and Item class that stores results.
However, I am unsure how to continue this in my DisplayInventory class (MainActivity) I've written in some FIXME comments to help show where I am talking about.
DisplayInventory class
// TESTING SQLite CODE HERE
public void insertItem(int position) {
//FIXME: This is where I need to ADD items to the database
// inventoryDB.addItem();
mInventoryItemList.add(position, new InventoryItem(R.drawable.ic_delete, "Tap to Edit", "Items: ", (android.widget.Button) Button, (android.widget.Button) Button));
mAdapter.notifyItemInserted(position);
}
public void removeItem(int position) {
// FIXME: This is where I DELETE items from database
// inventoryDB.deleteItem(); <== This method needs to be written in InventoryDBHelper class
mInventoryItemList.remove(position);
mAdapter.notifyItemRemoved(position);
}
public void createExampleList() {
mInventoryItemList = new ArrayList<>();
// get all items from the database
Item[] items = inventoryDB.getAllItems();
// loop through all items to build the array list
for (int i = 0; i < items.length; ++i){
// FIXME: this is where I need to build my ArrayList based on the contents of the DB
// for new users this will be empty. However, as they add items then the database
// will be populated and this will return data the next time.
}
}
//TESTING CODE ENDS HERE
InventoryDBHelper
public class InventoryDBHelper extends SQLiteOpenHelper {
private Context context;
private static final String DATABASE_NAME = "InventoryList.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "my_inventory";
private static final String COLUMN_ID = "_id";
private static final String COLUMN_TITLE = "item_name";
private static final String COLUMN_OWNER = "item_owner";
private static final String COLUMN_ITEMNUMBER = "number_items";
public InventoryDBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
String query = "CREATE TABLE " + TABLE_NAME +
" (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
COLUMN_TITLE + " TEXT, " +
COLUMN_OWNER + " TEXT, " +
COLUMN_ITEMNUMBER + " INTEGER);";
sqLiteDatabase.execSQL(query);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(sqLiteDatabase);
}
void addItem(String title, String owner, int numItem) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COLUMN_TITLE, title);
cv.put(COLUMN_OWNER, owner);
cv.put(COLUMN_ITEMNUMBER, numItem);
long result = db.insert(TABLE_NAME, null, cv);
if(result == -1) {
Toast.makeText(context, "FAILED", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(context, "Added Successful", Toast.LENGTH_SHORT).show();
}
}
public Item[] getAllItems(){
// list of items to return
Item[] returnItems;
// initialize a readable database connection
SQLiteDatabase db = this.getReadableDatabase();
String query = "SELECT " +
COLUMN_ID + "," +
COLUMN_TITLE + "," +
COLUMN_OWNER + "," +
COLUMN_ITEMNUMBER +
" FROM " + TABLE_NAME + ";";
Cursor cursor = db.rawQuery(query, null);
returnItems = unpackRecordData(cursor);
cursor.close();
return returnItems;
}
private Item[] unpackRecordData(Cursor cursor){
Item[] items = new Item[cursor.getCount()];
int i = 0;
while (cursor.moveToNext()){
Item item = new Item(
// Item.id
cursor.getInt(
cursor.getColumnIndexOrThrow(COLUMN_ID)
),
// Item.title
cursor.getString(
cursor.getColumnIndexOrThrow(COLUMN_TITLE)
),
// Item.owner
cursor.getString(
cursor.getColumnIndexOrThrow(COLUMN_OWNER)
),
// Item.itemNumber
cursor.getInt(
cursor.getColumnIndexOrThrow(COLUMN_ITEMNUMBER)
)
);
// add Item to the list of items
items[i] = item;
}
return items;
}
}
Item Class
public class Item {
// Item Database columns to properties
private int id;
private String title;
private String owner;
private int itemNumber;
// class constructor
public Item(int id, String title, String owner, int itemNumber){
this.id = id;
this.title = title;
this.owner = owner;
this.itemNumber = itemNumber;
}
// getters and setters
public void setId(int id){
this.id = id;
}
public int getId(){
return this.id;
}
public void setTitle(String title){
this.title = title;
}
public String getTitle(){
return this.title;
}
public void setOwner(String owner){
this.owner = owner;
}
public String getOwner(){
return this.owner;
}
public void setItemNumber(int itemNumber){
this.itemNumber = itemNumber;
}
public int getItemNumber(){
return this.itemNumber;
}
}
Here's an example that shows all three types of actions being undertake. It's based upon your code and has some comments to explain suggested changes, additions (commented out) and removal of code.
First InventoryDBHelper
public class InventoryDBHelper extends SQLiteOpenHelper {
private Context context;
private static final String DATABASE_NAME = "InventoryList.db";
private static final int DATABASE_VERSION = 1;
private SQLiteDatabase db; //<<<<<<<< ADDED
/*
CHANGED to public (can be useful)
*/
public static final String TABLE_NAME = "my_inventory";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_TITLE = "item_name";
public static final String COLUMN_OWNER = "item_owner";
public static final String COLUMN_ITEMNUMBER = "number_items";
private static volatile InventoryDBHelper instance;
private InventoryDBHelper(Context context) { //<<<<<<<<<< CHANGED TO PRIVATE
super(context, DATABASE_NAME, null, DATABASE_VERSION);
db = this.getWritableDatabase(); // Instantiates db variable that has full scope
this.context = context;
}
/*
ADDED so a singleton is used
*/
public static InventoryDBHelper getInstance(Context context) {
if (instance == null) {
instance = new InventoryDBHelper(context);
}
return instance;
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
String query = "CREATE TABLE " + TABLE_NAME +
" (" + COLUMN_ID + " INTEGER PRIMARY KEY," + //" INTEGER PRIMARY KEY AUTOINCREMENT," <<<<<<<<<< NO NEED FOR AUTOINCREMENT (has overheads)
COLUMN_TITLE + " TEXT, " +
COLUMN_OWNER + " TEXT, " +
COLUMN_ITEMNUMBER + " INTEGER);";
sqLiteDatabase.execSQL(query);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(sqLiteDatabase);
}
long addItem(String title, String owner, int numItem) { //<<<<<<<<<< CHANGED so result can be returned
// SQLiteDatabase db = this.getWritableDatabase(); //<<<<<<<<<< NOT NEEDED with db as class variable
ContentValues cv = new ContentValues();
cv.put(COLUMN_TITLE, title);
cv.put(COLUMN_OWNER, owner);
cv.put(COLUMN_ITEMNUMBER, numItem);
long result = db.insert(TABLE_NAME, null, cv);
if(result == -1) {
Toast.makeText(context, "FAILED", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(context, "Added Successful", Toast.LENGTH_SHORT).show();
}
return result; //<<<<<<<< ADDED might as well return the result
}
/*
ADDED so you can add from a passed item
*/
long addItem(Item item) {
return addItem(item.getTitle(),item.getOwner(),item.getItemNumber());
}
public Item[] getAllItems(){
// list of items to return
Item[] returnItems;
// initialize a readable database connection
//SQLiteDatabase db = this.getReadableDatabase(); //<<<<<<<<<< NOT NEEDED HERE
// PS getReadable gets a writeable database in most situations
/* NOT NEEDED HERE
String query = "SELECT " +
COLUMN_ID + "," +
COLUMN_TITLE + "," +
COLUMN_OWNER + "," +
COLUMN_ITEMNUMBER +
" FROM " + TABLE_NAME + ";";
*/
// ADDED use the convienence query method equivalent to SELECT * FROM my_inventory (SQL is built for you)
Cursor cursor = db.query(TABLE_NAME,null,null,null,null,null,null);
//Cursor cursor = db.rawQuery(query, null);
returnItems = unpackRecordData(cursor);
cursor.close();
return returnItems;
}
/*
ADDED to remove an item from
*/
long removeItem(long itemId) {
return db.delete(TABLE_NAME,COLUMN_ID+"=?",new String[]{String.valueOf(itemId)});
}
/*
ADDED to allow removal of an Item via Item object
*/
long removeItem(Item item) {
return removeItem(item.getId());
}
private Item[] unpackRecordData(Cursor cursor){
Item[] items = new Item[cursor.getCount()];
int i = 0;
while (cursor.moveToNext()){
Item item = new Item(
// Item.id
cursor.getInt(
cursor.getColumnIndexOrThrow(COLUMN_ID)
),
// Item.title
cursor.getString(
cursor.getColumnIndexOrThrow(COLUMN_TITLE)
),
// Item.owner
cursor.getString(
cursor.getColumnIndexOrThrow(COLUMN_OWNER)
),
// Item.itemNumber
cursor.getInt(
cursor.getColumnIndexOrThrow(COLUMN_ITEMNUMBER)
)
);
// add Item to the list of items
items[i++] = item; //ERROR FIXED was i so i was always 0 not 0 1 2 etc
}
return items;
}
}
see AUTOINCREMENT for further reason why not to use AUTOINCREMENT
Item has not been changed (although I would suggest using long instead of int for id)
SQLite rowid (your id columns is an alias of rowid) can be 64-bit signed integer (too large for int).
The examples of Adding, Extracting and Removal of Items from the Database is as per :-
public class MainActivity extends AppCompatActivity {
InventoryDBHelper inventoryDBHelper; //<<<<<<<<< Want to use the Database in this activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inventoryDBHelper = InventoryDBHelper.getInstance(this); // Gets an instance of the Database
//EXAMPLE Examples of Adding Items
inventoryDBHelper.addItem("MyItem","Fred",1);
inventoryDBHelper.addItem(new Item(-1000 /* irrelevant when adding*/,"Another Item","Mary",2));
//EXAMPLE Get a list of all Items
Item[] items = inventoryDBHelper.getAllItems();
//EXAMPLE Remove all Items
for(Item i: items) {
Log.d("INVENTRYINFO","Attempting to remove Item " + i.getTitle());
if (inventoryDBHelper.removeItem(i) > 0) {
Toast.makeText(this,"Item " + i.getTitle() + " deleted",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this,"Item " + i.getTitle() + " NOT DELETED",Toast.LENGTH_LONG).show();
}
// could use inventoryDBHelper.removeItem(i.getId()); //instead
}
}
}
You just need to adapt this for your needs.
The above is a working example (designed to be run once) it Adds 2 Items, Extracts them as an array of Items and then uses that list to Remove them all.
With a breakpoint at the for each loop that removes the items the following can be seen :-
i.e. the 2 Items have been added and extracted
After the proceeding (after the items have all been removed) then the Log contains :-
D/INVENTRYINFO: Attempting to remove Item MyItem
D/INVENTRYINFO: Attempting to remove Item Another Item
Related
how to add second column value of same or other table in another spinner from sqlite database using button click in android studio
retrievebtn.setOnClickListener(arg0 -> {
// TODO Auto-generated method stub
nos.clear();
names.clear();
//OPEN
db.openDB();
//RETRIEVE
Cursor c = db.getAllValues();
c.moveToFirst();
while(!c.isAfterLast())
{
String no = c.getString(0);
nos.add(no);
String name = c.getString(1);
names.add(name);
c.moveToNext();
}
//CLOSE
c.close();
db.close();
//SET IT TO SPINNER
sp1.setAdapter(adapter);
sp2.setAdapter(adapter);
});
Perhaps consider the following working example.
This consists of 2 spinners and 3 buttons. The buttons controlling from which of the 3 tables the data is extracted for the 2nd spinner.
The trick, as such, used is to use AS to utilise a standard column name, irrespective of the actual column name. The one difference is that this rather than using a normal adapter, it utilises a CursorAdapter (SimpleCursorAdapter as it's quite flexible) and thus you can extract the data directly.
First the SQLite side i.e. the class that extends SQLiteOpenHelper :-
class DBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "the_database.db";
public static final int DATABASE_VERSION = 1;
public static final String TABLE1_TABLE = "_table1";
public static final String TABLE1_ID_COL = BaseColumns._ID;
public static final String TABLE1_NAME_COL = "_name";
public static final String TABLE1_DESC_COL = "_desc";
private static final String TABLE1_CREATE_SQL =
"CREATE TABLE IF NOT EXISTS " + TABLE1_TABLE + "(" +
TABLE1_ID_COL + " INTEGER PRIMARY KEY" +
"," + TABLE1_NAME_COL + " TEXT UNIQUE" +
"," + TABLE1_DESC_COL + " TEXT " +
");";
public static final String TABLE2_TABLE = "_table2";
public static final String TABLE2_ID_COL = BaseColumns._ID;
public static final String TABLE2_TABLE1_ID_MAP_COL = "_table1_id_map";
public static final String TABLE2_NAME_COL = "_name";
private static final String TABLE2_CREATE_SQL =
"CREATE TABLE IF NOT EXISTS " + TABLE2_TABLE + "(" +
TABLE2_ID_COL + " INTEGER PRIMARY KEY" +
"," + TABLE2_TABLE1_ID_MAP_COL + " INTEGER " +
"," + TABLE2_NAME_COL + " TEXT" +
");";
public static final String TABLE3_TABLE = "_table3";
public static final String TABLE3_ID_COL = BaseColumns._ID;
public static final String TABLE3_TABLE2_ID_MAP_COL = "_table2_id_map";
public static final String TABLE3_NAME_COL = "_name";
private static final String TABLE3_CREATE_SQL =
"CREATE TABLE IF NOT EXISTS " + TABLE3_TABLE +"(" +
TABLE3_ID_COL + " INTEGER PRIMARY KEY" +
"," + TABLE3_TABLE2_ID_MAP_COL + " INTEGER " +
"," + TABLE3_NAME_COL + " TEXT " +
");";
private static volatile DBHelper INSTANCE;
private SQLiteDatabase db;
public static final String SPINNER_COLUMN1 = "_spc1";
public static final String SPINNER_COLUMN2 = "_spc2";
private DBHelper(Context context) {
super(context,DATABASE_NAME,null,DATABASE_VERSION);
db = this.getWritableDatabase();
}
public static DBHelper getInstance(Context context) {
if (INSTANCE==null) {
INSTANCE = new DBHelper(context);
}
return INSTANCE;
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(TABLE1_CREATE_SQL);
db.execSQL(TABLE2_CREATE_SQL);
db.execSQL(TABLE3_CREATE_SQL);
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
public long insertTable1Row(String name,String description) {
ContentValues cv = new ContentValues();
cv.put(TABLE1_NAME_COL,name);
cv.put(TABLE1_DESC_COL,description);
return db.insert(TABLE1_TABLE,null,cv);
}
public long insertTable2Row(String name, long table1_id) {
ContentValues cv = new ContentValues();
cv.put(TABLE2_NAME_COL,name);
cv.put(TABLE2_TABLE1_ID_MAP_COL,table1_id);
return db.insert(TABLE2_TABLE,null,cv);
}
public long insertTable3Row(String name, long table2_id) {
ContentValues cv = new ContentValues();
cv.put(TABLE3_NAME_COL,name);
cv.put(TABLE3_TABLE2_ID_MAP_COL,table2_id);
return db.insert(TABLE3_TABLE,null,cv);
}
public Cursor getSpinnerData(String table, long map) {
String[] columns = new String[]{};
String whereClause = "";
String[] whereArgs = new String[]{String.valueOf(map)};
switch (table) {
case TABLE1_TABLE:
columns = new String[]{TABLE1_ID_COL,TABLE1_NAME_COL + " AS " + SPINNER_COLUMN1,TABLE1_DESC_COL + " AS " + SPINNER_COLUMN2};
whereClause = "";
break;
case TABLE2_TABLE:
columns = new String[]{TABLE2_ID_COL ,TABLE2_NAME_COL + " AS " + SPINNER_COLUMN1,"'-' AS " + SPINNER_COLUMN2};
whereClause = TABLE2_TABLE1_ID_MAP_COL + "=?";
break;
case TABLE3_TABLE:
columns = new String[]{TABLE3_ID_COL, TABLE3_NAME_COL + " AS " + SPINNER_COLUMN1,"'~' AS " + SPINNER_COLUMN2};
whereClause = TABLE3_TABLE2_ID_MAP_COL + "=?";
break;
}
if (map < 0) {
whereClause="";
whereArgs = new String[]{};
}
if (columns.length > 0) {
return db.query(table,columns,whereClause,whereArgs,null,null,null);
} else {
return db.query(TABLE1_TABLE,new String[]{"0 AS " + TABLE1_ID_COL + ",'ooops' AS " + SPINNER_COLUMN1,"'ooops' AS " + SPINNER_COLUMN2},null,null,null,null,null,"1");
}
}
}
as said there are three tables
a singleton approach has been utilised for the DBHelper
the most relevant aspect in regards to switching spinner data is the getSpinnerData function, which takes two parameters, the most relevant being the first the tablename which drives the resultant query.
Note the use of BaseColumns._ID ALL Cursor adapters must have a column name _id (which is what BaseColumns._ID resolves to). The column should be an integer value that uniquely identifies the row.
the 2nd parameter caters for the selection of only related data, but a negative is used to ignore this aspect.
The Activity "MainActivity" used to demonstrate is :-
public class MainActivity extends AppCompatActivity {
Button btn1, btn2, btn3;
Spinner sp1,sp2;
String[] spinnerColumns = new String[]{DBHelper.SPINNER_COLUMN1,DBHelper.SPINNER_COLUMN2};
SimpleCursorAdapter sca1,sca2;
String sp1_table_name = DBHelper.TABLE1_TABLE;
String sp2_table_name = DBHelper.TABLE2_TABLE;
Cursor csr1, csr2;
DBHelper dbHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = this.findViewById(R.id.button1);
btn2 = this.findViewById(R.id.button2);
btn3 = this.findViewById(R.id.button3);
sp1 = this.findViewById(R.id.spinner1);
sp2 = this.findViewById(R.id.spinner2);
dbHelper = DBHelper.getInstance(this);
Cursor test4Data = dbHelper.getWritableDatabase().query(DBHelper.TABLE1_TABLE,null,null,null,null,null,null, "1");
if (test4Data.getCount() < 1) {
addSomeData();
}
test4Data.close();
sp1_table_name = DBHelper.TABLE1_TABLE;
sp2_table_name = DBHelper.TABLE2_TABLE;
setUpButtons();
setOrRefreshSpinner1();
setOrRefreshSpinner2();
}
void setUpButtons() {
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sp2_table_name = DBHelper.TABLE1_TABLE;
setOrRefreshSpinner2();
setOrRefreshSpinner1();
}
});
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sp2_table_name = DBHelper.TABLE2_TABLE;
setOrRefreshSpinner2();
setOrRefreshSpinner1();
}
});
btn3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sp2_table_name = DBHelper.TABLE3_TABLE;
setOrRefreshSpinner2();
setOrRefreshSpinner1();
}
});
}
void setOrRefreshSpinner1() {
csr1 = dbHelper.getSpinnerData(sp1_table_name,-1);
if (sca1==null) {
sca1 = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_2,
csr1,
spinnerColumns,
new int[]{android.R.id.text1, android.R.id.text2},0
);
sp1.setAdapter(sca1);
} else {
sca1.swapCursor(csr1);
}
}
void setOrRefreshSpinner2() {
csr2 = dbHelper.getSpinnerData(sp2_table_name,-1);
if (sca2==null) {
sca2 = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_2,
csr2,
spinnerColumns,
new int[]{android.R.id.text1, android.R.id.text2},0
);
sp2.setAdapter(sca2);
} else {
sca2.swapCursor(csr2);
}
}
private void addSomeData() {
long n1 = dbHelper.insertTable1Row("NAME001","The first name.");
long n2 = dbHelper.insertTable1Row("NAME002","The second name.");
long n3 = dbHelper.insertTable1Row("NAME003","The third name");
long t2n1 = dbHelper.insertTable2Row("CHILDNAME001",n1);
long t2n2 = dbHelper.insertTable2Row("CHILDNAME002",n2);
long t2n3 = dbHelper.insertTable2Row("CHILDNAME003", n3);
dbHelper.insertTable3Row("GRANDCHILDNAME001",t2n1);
dbHelper.insertTable3Row("GRANDCHILDNAME002",t2n1);
dbHelper.insertTable3Row("GRANDCHILDNAME003",t2n1);
dbHelper.insertTable3Row("GRANDCHILDNAME004",t2n2);
dbHelper.insertTable3Row("GRANDCHILDNAME005",t2n3);
}
}
Result
The above when run starts of with :-
With the first spinner dropdown shown :-
With the second spinner dropdown shown :-
If Button1 is clicked then both spinners (i.e. spinner2 has been changed to select data from Table1 rather than Table2) show data from Table1 (useless but for demonstration) :-
If Button3 is clicked then data from Table3 is displayed in the second spinner:-
Clicking Button2 shows data from Table2.
Of course the principle could be applied in many different ways.
My adapters were not set so I made below changes and got expected result.
// RETRIEVE
retrievebtn.setOnClickListener(arg0 -> {
// TODO Auto-generated method stub
nos.clear();
names.clear();
//OPEN
db.openDB();
//RETRIEVE
Cursor c = db.getAllValues();
c.moveToFirst();
while(!c.isAfterLast())
{
String no = c.getString(0);
nos.add(no);
String name = c.getString(1);
names.add(name);
c.moveToNext();
}
//CLOSE
c.close();
db.close();
//SET IT TO SPINNER
ArrayAdapter<String> adapter1 = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, nos);
ArrayAdapter<String> adapter2 = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, names);
sp1.setAdapter(adapter1);
sp2.setAdapter(adapter2);
});
I spend much time on SQLite and I have a problem in deleting an item if it exist!
I'm working in Bookmark App that save links from webview into listview using SQLite, my problem is can't check if the item is exist > don't create a link.
this is my BookmarksDatabase used for sqlite:
public class BookmarksDatabase extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "bookmarks.db";
private static final String TABLE_NAME = "bookmarks_data";
private static final String COL1 = "ID";
private static final String COL2 = "ITEM1";
private static final String COL3 = "ITEM2";
public BookmarksDatabase(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, " + " ITEM1 TEXT, " + " ITEM2 TEXT)";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean addData(String item1, String item2) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL2, item1);
contentValues.put(COL3, item2);
long result = db.insert(TABLE_NAME, null, contentValues);
// if date as inserted incorrectly it will return -1
return result != -1;
}
public Cursor getListContents() {
SQLiteDatabase db = this.getWritableDatabase();
return db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
}
public ArrayList<Bookmarks> getAllData() {
ArrayList<Bookmarks> arrayList = new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor data = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
while (data.moveToNext()) {
int id = data.getInt(0);
String title = data.getString(1);
String link = data.getString(2);
Bookmarks bookmarks = new Bookmarks(id, title, link);
arrayList.add(bookmarks);
}
return arrayList;
}
public int deleteSpecificContents(int id) {
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TABLE_NAME, COL1 + "=?", new String[]{Integer.toString(id)});
}
}
this is my code used in MainActivity to fetch items on listview
/*---------------- Bookmark Tab, sqlite databases integrated ---------------*/
private void showBookmarksScreen() {
// initialize a dialog in the main activity
final Dialog bookmarksScreen = new Dialog(this);
bookmarksScreen.requestWindowFeature(Window.FEATURE_NO_TITLE);
bookmarksScreen.setContentView(R.layout.activity_bookmark);
bookmarksScreen.setCancelable(true);
final ListView listView = bookmarksScreen.findViewById(R.id.bookmark_list);
RelativeLayout bookmarkEmpty = bookmarksScreen.findViewById(R.id.bookmark_empty);
// create an array and call bookmark
// database to retrive data then
// fetch it into list view
arrayList = new ArrayList<>();
arrayList = bookmarkDB.getAllData();
// get all data from sqlite database
Cursor data = bookmarkDB.getListContents();
// check if no bookmarks
// then show view that inform
// user that there is no bookmarks
if(data.getCount() == 0 ) {
bookmarkEmpty.setVisibility(View.VISIBLE);
}
bookmarkListAdpater = new BookmarkListAdpater(this, arrayList);
listView.setAdapter(bookmarkListAdpater);
bookmarkListAdpater.notifyDataSetChanged();
// load link on item click
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView link = view.findViewById(R.id.list_link);
String convertedLink = link.getText().toString();
webView.loadUrl(convertedLink);
bookmarksScreen.dismiss();
}
});
// ask user to delete bookmark on item long click
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
// initialize a dialog in the main activity
final Dialog deleteDialog = new Dialog(MainActivity.this);
deleteDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
deleteDialog.setContentView(R.layout.activity_confirm);
// confirm message or dialog can't be
// canceled so we set it to false
deleteDialog.setCancelable(false);
TextView deleteMessage = deleteDialog.findViewById(R.id.confirm_text);
TextView deleteConfirm = deleteDialog.findViewById(R.id.confirm_allow);
TextView deleteCancel = deleteDialog.findViewById(R.id.confirm_deny);
deleteMessage.setText(getString(R.string.delete_bookmark));
// confirm button
deleteConfirm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Cursor data = bookmarkDB.getListContents();
int i = 0;
while(data.moveToNext()){
if(i == position){
break;
}
i++;
}
bookmarkDB.deleteSpecificContents(data.getInt(0));
deleteDialog.dismiss();
bookmarksScreen.dismiss();
customToast(getString(R.string.bookmark_deleted), 0);
}
});
// confirm cancel
deleteCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
deleteDialog.dismiss();
}
});
deleteDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
deleteDialog.show();
return true;
}
});
bookmarksScreen.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
bookmarksScreen.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
bookmarksScreen.show();
}
My Model
public class Bookmarks {
int id;
String title, link;
public Bookmarks(int id, String title, String link) {
this.id = id;
this.title = title;
this.link = link;
}
public Bookmarks() {}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
}
any ideas? thanks.
Try using below to delete item from DB
bookmarkDB.deleteSpecificContents(arrayList.get(position).getId(0));
If you want to check item exists or not before adding then add below code in your BookmarksDatabase
public boolean isExists(String link) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE " + COL3 + "='" + link + "'", null);
return cursor.getCount() > 0;
}
And then check
if(bookmarkDB.isExists(link))
//Already Exist
else
//Not Exist, add now
With the same logic you're using:
SQLiteDatabase db = new DatabaseManager(context).getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME + " WHERE " + ID_KEY + " = ?";
Cursor cursor = db.rawQuery(query, new String[]{Integer.toString(id)});
if(cursor.moveToFirst()){
db.delete(TABLE_NAME, ID_KEY + " = ?", new String[]{Integer.toString(id)});
}
cursor.close();
db.close();
Another possibility is changing the method return type to boolean and verifying the return count from the delete command:
public boolean deleteSpecificContents(int id) {
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TABLE_NAME, COL1 + "=?", new String[]{Integer.toString(id)}) > 0;
}
I'm currently working an application on Android Studio and I have a little problem, hope you can help me. This application is made using Model-View-Presenter and in the Login activity (the main activity). I call a REST service to get data and save it in the data base, in the interactor class I have this mehtod to save the data of the JSON object in the database
private long insertLoginData() throws JSONException {
HelperDB dbObj = new HelperDB(_ctx);
ContentValues values = new ContentValues();
String firstName = "";
String lastName = "";
values.put(userTableFields[1], _objJson.getString(userTableFields[1]));
if (_objJson.has("fullName")){
JSONObject objFullName = _objJson.getJSONObject("fullName");
firstName = (objFullName.has(userTableFields[2]) ? objFullName.getString(userTableFields[2]) : "");
lastName = (objFullName.has(userTableFields[3]) ? objFullName.getString(userTableFields[3]) : "");
}
values.put(userTableFields[2], firstName);
values.put(userTableFields[3], lastName);
values.put(userTableFields[4], (_objJson.has(userTableFields[4]) ? _objJson.getString(userTableFields[4]) : ""));
values.put(userTableFields[5], true);
values.put(userTableFields[6], _userName);
values.put(userTableFields[7], _Password);
long localId = dbObj.insertStatement(0, values);
dbObj.closeDB();
return localId;
}
_ctx is a local variable of Context in the Presenter, it comes from Main Activity. And userTableFields Array contains the name of fields of my table users and it comes from the strings resource.
I know, this is a manual way to do it, I could use POJO to cast in classes the model of the JSON data, but this is no the problem. I use the debug console to check localId variable is returning a value different to -1, so record is inserting ok in the database.
After validate the user and insert the user records (user informations and its notifications) to data base I open a new Activity (the second activity) and then I call a method in the Presenter to get the user data and trying to show it in this new activity.
public class Home extends AppCompatActivity implements HomeView{
private HomePresenter presenter;
private ListView lvNotifications;
private TextView tvWelcome;
private ProgressBar pbHome;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
presenter = new HomePresenterImpl(this);
lvNotifications = (ListView)findViewById(R.id.lvNotifications);
tvWelcome = (TextView)findViewById(R.id.tvWelcome);
pbHome = (ProgressBar)findViewById(R.id.pbHome);
setTitle(getResources().getString(R.string.titleHome));
presenter.getNotificationsDataPresenter(getApplicationContext());
lvNotifications.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//presenter.getSelectedItem(position, _linkResource);
}
});
}
#Override
public void setDataSourceListView(String[] itemArray, String[] linkResource) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, itemArray);
lvNotifications.setAdapter(adapter);
}}
The problem is here. In the Presenter of the second activity I call a method in the database to get the notifications of users, even, if I change the sentence directly to "SELECT * FROM users" it always comes empty, I searched lot of topics about it but do not get solution.
This is the method to get data of users and does not work although inserts are happening satisfactorily in the first activity.
private void getNotificationsData(String query){
HelperDB dbObj = new HelperDB(_ctx);
Cursor cursor = dbObj.getQueryStatement(query, null);
itemArray = new String[cursor.getCount()];
linkResource = new String[cursor.getCount()];
int i = 0;
if (cursor.getCount() > 0)
{
cursor.moveToFirst();
try{
while(cursor.moveToNext()){
itemArray[i] = cursor.getString(0);
linkResource[i] = cursor.getString(1);
i++;
}
}
finally {
cursor.close();
dbObj.close();
}
}
}
I was thinking it could be an issue about the Context, because en the first Activity I execute other functions in the data base and there are no problems, but in the second activity data of any kind is returned, the Cursor does not break or throw error, its variable mCount always is -1 and size is 0.
The following is the SQLiteOpenHelper that I'm using to connect the database.
public class HelperDB extends SQLiteOpenHelper{
private static final String DBName = "MyDb";
private static String createUserTableStatement = "";
private static String createNotificationsTableStatement = "";
String[] tableNames, userTableFields, notificationsTableFields;
public HelperDB(Context context) {
super(context, DBName, null, 1);
tableNames = context.getResources().getStringArray(R.array.tableNames);
userTableFields = context.getResources().getStringArray(R.array.userTableFields);
notificationsTableFields = context.getResources().getStringArray(R.array.notificationsTableFields);
createUserTableStatement = "CREATE TABLE " + tableNames[0] + " (" + userTableFields[0] + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ userTableFields[1] + " TEXT, " + userTableFields[2] + " TEXT, " + userTableFields[3]
+ " TEXT, " + userTableFields[4] + " TEXT, " + userTableFields[5] + " BOOLEAN, " + userTableFields[6] + " TEXT, "
+ userTableFields[7] + " TEXT)";
createNotificationsTableStatement = "CREATE TABLE " + tableNames[1] + " (" + notificationsTableFields[0]
+ " INTEGER PRIMARY KEY AUTOINCREMENT, " + notificationsTableFields[1] + " TEXT, "
+ notificationsTableFields[2] + " TEXT, " + notificationsTableFields[3]
+ " TEXT, " + notificationsTableFields[4] + " TEXT, " + notificationsTableFields[5] + " TEXT)";
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(createUserTableStatement);
db.execSQL(createNotificationsTableStatement);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
for (int i = 0; i < tableNames.length; i++)
db.execSQL("DROP TABLE IF EXISTS " + tableNames[i]);
onCreate(db);
}
public void closeDB() {
SQLiteDatabase db = this.getWritableDatabase();
if (db != null && db.isOpen())
db.close();
}
public long insertStatement(int tableIndex, ContentValues values){
SQLiteDatabase db = this.getWritableDatabase();
long userId;
try{
db.beginTransaction();
userId = db.insert(tableNames[tableIndex], null, values);
db.setTransactionSuccessful();
}
finally {
db.endTransaction();
db.close();
}
return userId;
}
public Cursor getQueryStatement(String queryStatement, String[] fieldsArray){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(queryStatement, fieldsArray);
return cursor;
}
}
The question is what I'm doing wrong when I want to get data records in a second activity that previously in a prevoius activity were inserted?
Note: I always send getApplicationContext as parameter to the Presenter because methods in the SqliteOpenHelper needs the context in the construtor.
You should make POJO class and implement Parcelable like below code just modify your params
public class User implements Parcelable {
private Integer id;
private String userName;
private Integer age;
public User() {
}
protected User(Parcel in) {
userName = in.readString();
age = in.readInt();
}
public static final Creator<User> CREATOR = new Creator<User>() {
#Override
public User createFromParcel(Parcel in) {
return new User(in);
}
#Override
public User[] newArray(int size) {
return new User[size];
}
};
public Integer getId() {
return id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(userName);
parcel.writeInt(age);
}
Then using intent put your model into intent and getIntent in another activity where you want like:
Intent intent = new Intent(mContext,//your activity name);
intent.putExtra("yourModekey",userModel);
startActivities(intent);
in other activity get like
getIntent().getParcelableExtra("yourModelkey");
I am developing an app for listing details in database. The listing is not working. but it is showing in log as fine. Why my recyclerview listling is not working. when i am using bean1 = new Bean(cn.getName(), cn.getNumber(), cn.getSpeeddial()) it shows error.
My codes are shown below.
SpeedDialViewActivity.java
public class SpeedDialViewActivity extends AppCompatActivity {
private List<Bean> beanList = new ArrayList<>();
private RecyclerView recyclerView;
private ViewAdapter mAdapter;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_speed_dial_view);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mAdapter = new ViewAdapter(beanList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
prepareData();
}
private void prepareData() {
DatabaseHandler handler = new DatabaseHandler(getApplicationContext());
Log.d("Reading: ", "Reading all contacts..");
List<Bean> beanList = handler.getAllContacts();
//Cursor cursor = (Cursor) handler.getAllContacts();
//Bean bean1;
for (Bean cn : beanList) {
String log = "Id: " + cn.getId() + " ,Name: " + cn.getName() + " ,Phone: " + cn.getNumber();
// Writing Contacts to log
Log.d("Name: ", log);
// bean1 = new Bean(cn.getName(), cn.getNumber(), cn.getSpeeddial()); // Error occurring
// beanList.add(bean1);
}
}
}
DatabaseHandler.java
public class DatabaseHandler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "speeddial";
private static final String TABLE_CONTACTS = "contacts";
private static final String KEY_ID = "id";
private static final String KEY_NAME = "name";
private static final String KEY_PH_NO = "phone_number";
private static final String KEY_SPEED_DIAL = "speed_dial_number";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
+ KEY_PH_NO + " TEXT" + KEY_SPEED_DIAL + " TEXT" + ")";
db.execSQL(CREATE_CONTACTS_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);
// Create tables again
onCreate(db);
}
void addContact(Bean bean) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, bean.getName()); // Contact Name
values.put(KEY_PH_NO, bean.getNumber()); // Contact Phone
values.put(KEY_PH_NO, bean.getSpeeddial()); // Contact Phone
// Inserting Row
db.insert(TABLE_CONTACTS, null, values);
db.close(); // Closing database connection
}
Bean getBean(int id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,
KEY_NAME, KEY_PH_NO }, KEY_ID + "=?",
new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
Bean bean = new Bean(Integer.parseInt(cursor.getString(0)),cursor.getString(1), cursor.getString(2), cursor.getString(3));
// return contact
return bean;
}
public List<Bean> getAllContacts() {
List<Bean> contactList = new ArrayList<Bean>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_CONTACTS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Bean contact = new Bean();
contact.setId(Integer.parseInt(cursor.getString(0)));
contact.setName(cursor.getString(1));
contact.setNumber(cursor.getString(2));
// Adding contact to list
contactList.add(contact);
} while (cursor.moveToNext());
}
// return contact list
return contactList;
}
}
ViewAdapter.java
public class ViewAdapter extends RecyclerView.Adapter<ViewAdapter.MyViewHolder> {
private List<Bean> beanList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView name, number, speeddial_number;
public MyViewHolder(View view) {
super(view);
name = (TextView) view.findViewById(R.id.name);
number = (TextView) view.findViewById(R.id.number);
speeddial_number = (TextView) view.findViewById(R.id.speeddialNumber);
}
}
public ViewAdapter(List<Bean> beanList){
this.beanList = beanList;
}
#Override
public ViewAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.speeddial_list_row, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewAdapter.MyViewHolder holder, int position) {
Bean bean = beanList.get(position);
holder.name.setText(bean.getName());
holder.number.setText(bean.getNumber());
holder.speeddial_number.setText(bean.getSpeeddial());
}
#Override
public int getItemCount() {
return beanList.size();
}
}
Bean.java
public class Bean{
private int id;
private String name;
private String number;
private String speeddial;
public Bean(int id, String name, String number, String speeddial) {
this.id=id;
this.name=name;
this.number=number;
this.speeddial=speeddial;
}
public Bean(String name, String number, String speeddial) {
this.name=name;
this.number=number;
this.speeddial=speeddial;
}
public Bean() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getSpeeddial() {
return speeddial;
}
public void setSpeeddial(String speeddial) {
this.speeddial = speeddial;
}
}
The error is java.lang.RuntimeException: Unable to start activity ComponentInfo{com.app.appname/com.app.appname}: java.util.ConcurrentModificationException
Please help me
You are not adding the contacts you are fetching in the list and not doing notify data set changed. Change your onPrepare() method as follows
private void prepareData() {
DatabaseHandler handler = new DatabaseHandler(getApplicationContext());
Log.d("Reading: ", "Reading all contacts..");
List<Bean> beanList = handler.getAllContacts();
this.beanList.addAll(beanList);
mAdapter.notifyDatasetChanged();
}
pass the same list in prepareData(beanList) and add items in this list. And change your method to something likeprepareData(List<Bean> beanList>).after successfully adding, simply call mAdapter.notifyDataSetChanged() method so your adapter could know that some items have been added into the list.
You have not mention android:name in application tag in manifest file.
So you simple use context object or use SpeedDialViewActivity.this
DatabaseHandler handler = new DatabaseHandler(mContext);
or
DatabaseHandler handler = new DatabaseHandler(SpeedDialViewActivity.this);
private void prepareData() {
DatabaseHandler handler = new DatabaseHandler(SpeedDialViewActivity.this);
Log.d("Reading: ", "Reading all contacts..");
List<Bean> beanList = handler.getAllContacts();
//Cursor cursor = (Cursor) handler.getAllContacts();
//Bean bean1;
for (Bean cn : beanList) {
String log = "Id: " + cn.getId() + " ,Name: " + cn.getName() + " ,Phone: " + cn.getNumber();
// Writing Contacts to log
Log.d("Name: ", log);
// bean1 = new Bean(cn.getName(), cn.getNumber(), cn.getSpeeddial()); // Error occurring
// beanList.add(bean1);
}
}
When I add data into sqlite and open it for the first time, the data inside will be displayed. However, if I try opening it again nothing will show up even though there is data inside. May I know what is the problem?
Class that performs the activity:
public class Watchlist extends ListActivity {
private ArrayList<String> results = new ArrayList<String>();
private String tableName = DatabaseHandler.TABLE_ITEM;
private SQLiteDatabase newDB;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
openAndQueryDatabase();
displayResultList();
}
private void displayResultList() {
TextView tView = new TextView(this);
tView.setText("This data is retrieved from sqlite");
getListView().addHeaderView(tView);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, results));
getListView().setTextFilterEnabled(true);
}
private void openAndQueryDatabase() {
try {
DatabaseHandler db = new DatabaseHandler(this.getApplicationContext());
newDB = db.getWritableDatabase();
Cursor c = newDB.rawQuery("SELECT * FROM " + tableName, null);
if (c != null ) {
if (c.moveToFirst()) {
do {
String pid = c.getString(c.getColumnIndex("id"));
String name = c.getString(c.getColumnIndex("name"));
String price = c.getString(c.getColumnIndex("price"));
String date = c.getString(c.getColumnIndex("created_at"));
Log.d("pid",pid);
results.add("Name: " + name + "\n Price: " + price + "\n Date posted: " + date);
}while (c.moveToNext());
}
}
} catch (SQLiteException se ) {
Log.e(getClass().getSimpleName(), "Could not create or Open the database");
} finally {
if (newDB != null)
newDB.execSQL("DELETE FROM " + tableName);
newDB.close();
}
}
}
Database handler:
public class DatabaseHandler extends SQLiteOpenHelper {
// All Static variables
// Database Version
private static final int DATABASE_VERSION = 2;
// Database Name
private static final String DATABASE_NAME = "itemManager";
// table name
public static final String TABLE_ITEM = "item";
// Item Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_NAME = "name";
private static final String KEY_PRICE = "price";
private static final String KEY_CREATED_AT = "created_at";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Creating Tables
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_ITEM_TABLE = "CREATE TABLE " + TABLE_ITEM + "("
+ KEY_ID + " INTEGER PRIMARY KEY autoincrement,"
+ KEY_NAME + " TEXT, "
+ KEY_PRICE + " TEXT,"
+ KEY_CREATED_AT + " TEXT" + ")";
db.execSQL(CREATE_ITEM_TABLE);
}
// Upgrading database
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_ITEM);
// Create tables again
onCreate(db);
}
/**
* Storing item details in database
* */
public void addItem(Items item) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, item.getName()); // item name
values.put(KEY_PRICE, item.getPrice()); // item price
values.put(KEY_CREATED_AT, item.getDate()); // Created At
// Inserting Row
db.insert(TABLE_ITEM, null, values);
db.close(); // Closing database connection
}
/**
* Getting item data from database
* */
public List<Items> getAllItems(){
List<Items> itemList = new ArrayList<Items>();
String selectQuery = "SELECT * FROM " + TABLE_ITEM;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// Move to first row
if (cursor.moveToFirst()) {
do {
Items item = new Items();
item.setID(Integer.parseInt(cursor.getString(0)));
item.setName(cursor.getString(1));
item.setPrice(cursor.getString(2));
item.setDate(cursor.getString(2));
// Adding item to list
itemList.add(item);
} while (cursor.moveToNext());
}
// return item list
return itemList;
}
/**
* return true if rows are there in table
* */
public int getRowCount() {
String countQuery = "SELECT * FROM " + TABLE_ITEM;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int rowCount = cursor.getCount();
db.close();
cursor.close();
// return row count
return rowCount;
}
// Updating item
public int updateItem(Items item) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, item.getName());
values.put(KEY_PRICE, item.getPrice());
values.put(KEY_CREATED_AT, item.getDate());
// updating row
return db.update(TABLE_ITEM, values, KEY_ID + " = ?",
new String[] { String.valueOf(item.getID()) });
}
// Deleting item
public void deleteItem(Items item) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_ITEM, KEY_ID + " = ?",
new String[] { String.valueOf(item.getID()) });
db.close();
}
}
Well, don't you delete all the records before closing the database?
} finally {
if (newDB != null)
newDB.execSQL("DELETE FROM " + tableName);
newDB.close();
}
That would explain that behaviour.