Hi I am struggling with these two:
i) I created sqlite database for my android app. And added rows through Main Activity. Now, whenever I am running my program, everytime the same rows getting added in database. How to ensure only one time database gets created with all these rows.
ii) I made id (int type) as primary key and made it auto-increment.I don't want primary ID to be auto-incremental and can be set manually for each row. How I can do it?
1. All database related functions have been in this code:
public class DataBaseHandlerActivity extends SQLiteOpenHelper {
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "shopsManager";
// Shop table name
private static final String TABLE_SHOPS = "shops";
// Shop Table Columns names
private static final String KEY_ID = "shopid";
private static final String KEY_NAME = "shopname";
private static final String KEY_ADDRESS = "shopaddress";
private static final String KEY_CAT1="category1";
private static final String KEY_CAT2="category2";
private static final String KEY_CAT3="category3";
private static final String KEY_CAT4="category4";
private static final String KEY_IMAGE="shopimage";
public DataBaseHandlerActivity(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Creating Tables
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_SHOPS_TABLE="CREATE TABLE "+TABLE_SHOPS+"("+KEY_ID+" INTEGER PRIMARY KEY,"+KEY_NAME+" TEXT,"+
KEY_IMAGE+" TEXT,"+
KEY_ADDRESS+" TEXT,"+KEY_CAT1+" TEXT,"+KEY_CAT2+" TEXT,"+KEY_CAT3+" TEXT,"+KEY_CAT4+" TEXT"+
")";
db.execSQL(CREATE_SHOPS_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_SHOPS);
//CREATE TABLE AGAIN
onCreate(db);
}
/**
* All CRUD(Create, Read, Update, Delete) Operations
*/
//Add a new shop row
void addShop(Shop shop){
SQLiteDatabase db=this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME,shop.getShopName());
values.put(KEY_IMAGE,shop.getShopImage());
values.put(KEY_ADDRESS,shop.getShopAddress());
values.put(KEY_CAT1,shop.getShopCat1());
values.put(KEY_CAT2,shop.getShopCat2());
values.put(KEY_CAT3,shop.getShopCat3());
values.put(KEY_CAT4,shop.getShopCat4());
//Inserting row
db.insert(TABLE_SHOPS,null,values);
db.close(); //Close db connection
}
//Get a shop items corresponding to a primary key
Shop getShop(int id){
SQLiteDatabase db=this.getReadableDatabase();
Cursor cursor=db.query(TABLE_SHOPS,new String[]{KEY_ID,KEY_NAME,KEY_IMAGE,KEY_ADDRESS,KEY_CAT1,KEY_CAT2,KEY_CAT3,KEY_CAT4},
KEY_ID +"=?",new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
Shop shop = new Shop(Integer.parseInt(cursor.getString(0)),
cursor.getString(1), cursor.getString(2),cursor.getString(3),cursor.getString(4),cursor.getString(5),
cursor.getString(6),cursor.getString(7));
// return shop
return shop;
}
// Getting All Shops
public List<Shop> getAllShops() {
List<Shop> shopList = new ArrayList<Shop>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_SHOPS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Shop shop = new Shop();
shop.setShopId(Integer.parseInt(cursor.getString(0)));
shop.setShopName(cursor.getString(1));
shop.setShopImage(cursor.getString(2));
shop.setShopAddress(cursor.getString(3));
shop.setShopCat1(cursor.getString(4));
shop.setShopCat2(cursor.getString(5));
shop.setShopCat3(cursor.getString(6));
shop.setShopCat4(cursor.getString(7));
// Adding contact to list
shopList.add(shop);
} while (cursor.moveToNext());
}
// return shop list
return shopList;
}
// Updating single shop
public int updateShop(Shop shop) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME,shop.getShopName());
values.put(KEY_IMAGE,shop.getShopImage());
values.put(KEY_ADDRESS,shop.getShopAddress());
values.put(KEY_CAT1,shop.getShopCat1());
values.put(KEY_CAT2,shop.getShopCat2());
values.put(KEY_CAT3,shop.getShopCat3());
values.put(KEY_CAT4,shop.getShopCat4());
// updating row
return db.update(TABLE_SHOPS, values, KEY_ID + " = ?",
new String[] { String.valueOf(shop.getShopId()) });
}
// Deleting single shop
public void deleteShop(Shop shop) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_SHOPS, KEY_ID + " = ?",
new String[] { String.valueOf(shop.getShopId()) });
db.close();
}
// Getting shops Count
public int getShopsCount() {
String countQuery = "SELECT * FROM " + TABLE_SHOPS;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int count=cursor.getCount();
cursor.close();
db.close() ;
// return count
return count;
}
}
2. Main Activity where I pass data to create table:
package com.trillbit.databaseactivity;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.List;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DataBaseHandlerActivity db=new DataBaseHandlerActivity(this);
/**
* CRUD Operations
* */
// Inserting Shops
Log.d("Insert: ", "Inserting ..");
db.addShop(new Shop("Shoppers Stop","shopperstop","1st Floor,Forum Mall","Fashion","Clothes","Home","Shoes"));
db.addShop(new Shop("LifeStyle", "lifestyle", "2nd Floor, Forum Mall", "Fashion", "Clothes","Home", "Mobile"));
db.addShop(new Shop("Ezone", "ezone","3rd Floor, Forum Mall","Mobile","Electronics","Apppliances","Home"));
db.addShop(new Shop("Dominos", "dominos","1st Floor,Forum Mall","Food","Pizza","Cake","Pastery"));
// Reading all shops
Log.d("Reading: ", "Reading all shops..");
List<Shop> shops = db.getAllShops();
for (Shop shop : shops) {
String log = "Id: " + shop.getShopId() + " ,Name: " + shop.getShopName() + " ,Image: " + shop.getShopImage()
+ ",Address: " + shop.getShopAddress() + ",Categort1: " + shop.getShopCat1() + ", Category2: " + shop.getShopCat2()
+ ",Category3: " + shop.getShopCat3() + ",Catgeory4: " + shop.getShopCat4();
// Writing Shops to log
Log.d("Name: ", log);
}
}
}
3.Output in logcat:
D/Name:: Id: 5 ,Name: Shoppers Stop ,Image: shopperstop,Address: 1st Floor,Forunm Mall,Categort1: Fashion, Category2: Clothes,Category3: Home,Catgeory4: Shoes
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 6 ,Name: LifeStyle ,Image: lifestyle,Address: 2nd Floor, Forum Mall,Categort1: Fashion, Category2: Clothes,Category3: Home,Catgeory4: Mobile
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 7 ,Name: Ezone ,Image: ezone,Address: 3rd Floor, Forum Mall,Categort1: Mobile, Category2: Electronics,Category3: Apppliances,Catgeory4: Home
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 8 ,Name: Dominos ,Image: dominos,Address: 1st Floor,Forum Mall,Categort1: Food, Category2: Pizza,Category3: Cake,Catgeory4: Pastery
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 9 ,Name: Shoppers Stop ,Image: shopperstop,Address: 1st Floor,Forum Mall,Categort1: Fashion, Category2: Clothes,Category3: Home,Catgeory4: Shoes
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 10 ,Name: LifeStyle ,Image: lifestyle,Address: 2nd Floor, Forum Mall,Categort1: Fashion, Category2: Clothes,Category3: Home,Catgeory4: Mobile
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 11 ,Name: Ezone ,Image: ezone,Address: 3rd Floor, Forum Mall,Categort1: Mobile, Category2: Electronics,Category3: Apppliances,Catgeory4: Home
01-14 16:07:49.687 7993-7993/com.trillbit.databaseactivity D/Name:: Id: 12 ,Name: Dominos ,Image: dominos,Address: 1st Floor,Forum Mall,Categort1: Food, Category2: Pizza,Category3: Cake,Catgeory4: Pastery
You add the those rows every single time your Activity is created.
Use SharedPreferences to mark a boolean that says your app started once
Create a UNIQUE CONSTRAINT in the database table definition.
It will automatically prevent duplicate entries.
OR
Instead of
INSERT ...
do
INSERT OR IGNORE ...
This means that instead of returning an error code if you violate a constraint, SQLite just returns SQLITE_OK as if the command succeeded.
For others benefit, I am writing how I solved using shared preferences as suggested by cricket-007. At start of main activity, created database when application gets installed and run first time.
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if(!prefs.getBoolean("firstTime", false)) {
// run your one time code
// Inserting Shops
Log.d("Insert: ", "Inserting ..");
db.addShop(new Shop("01","Shoppers Stop","shopperstop","1st Floor,Forum Mall","Fashion","Clothes","Home","Shoes"));
db.addShop(new Shop("02","LifeStyle", "lifestyle", "2nd Floor, Forum Mall", "Fashion", "Clothes","Home", "Mobile"));
db.addShop(new Shop("03","Ezone", "ezone","3rd Floor, Forum Mall","Mobile","Electronics","Apppliances","Home"));
db.addShop(new Shop("04","Dominos", "dominos","1st Floor,Forum Mall","Food","Pizza","Cake","Pastery"));
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("firstTime", true);
editor.commit();
}
Related
I have created one listview where I want to retrieve the items from sqlite database. So I have created one method as a List named as getrequestitems where I will map the details and add to a arraylist.
public List<Map<String, String>> getrequestitems() {
List<Map<String, String>> data = null;
data = new ArrayList<Map<String, String>>();
try {
SQLiteDatabase db = dbHandler.getReadableDatabase();
String sql = "SELECT * from request WHERE time > date('now','-1 day')";
Cursor rs = db.rawQuery(sql,null);
if(rs.moveToFirst()) {
do {
Map<String, String> dtname = new HashMap<String, String>();
dtname.put("bloodgrp", rs.getString(rs.getColumnIndex("bloodgrp")));
dtname.put("date", "Date:- " + rs.getString(rs.getColumnIndex("Datetime1")));
dtname.put("time", "Time:- " + rs.getString(rs.getColumnIndex("time")));
dtname.put("name", "Name:- " + rs.getString(rs.getColumnIndex("Name")));
dtname.put("Username", rs.getString(rs.getColumnIndex("Username")));
data.add(dtname);
}
while (rs.moveToNext());
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
return data;
}
But When I open that activity It doesn't displayed any records. I have debug the code but can't any exception. I have written wrong query? as "SELECT * from request WHERE time > date('now','-1 day')";
Here is my complete code.
public class request extends AppCompatActivity {
SimpleAdapter ad;
TextView list3;
private SlidrInterface slidr;
private DBHandler dbHandler;
private static ArrayList<String> arrayList = new ArrayList<>();
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_request);
slidr = Slidr.attach(this);
slidr.unlock();
dbHandler = new DBHandler(this);
list3 = findViewById(R.id.list3);
TextView txt = findViewById(R.id.list4);
ListView lst1 = (ListView) findViewById(R.id.list2);
List<Map<String, String>> MyDataList = null;
MyDataList = getrequestitems();
String[] from = {"bloodgrp", "date", "time", "name", "Username"};
int[] to = {R.id.listt, R.id.date, R.id.time1, R.id.name3, R.id.user};
ad = new SimpleAdapter(request.this, MyDataList, R.layout.listrequest, from, to);
lst1.setAdapter(ad);
lst1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
List<Map<String, String>> MyDataList1 = null;
MyDataList1 = getrequestitems();
String[] from = {"Username"};
int[] to = {R.id.user};
Toast.makeText(getApplicationContext(), MyDataList1.toString(), Toast.LENGTH_SHORT).show();
ad = new SimpleAdapter(request.this, MyDataList1, R.layout.listrequest, from, to);
if(ad.getCount()==0){
Toast.makeText(getApplicationContext(), "No requests are currently visible", Toast.LENGTH_SHORT).show();
}
HashMap<String, String> obj = (HashMap<String, String>) ad.getItem(i);
String name = (String) obj.get("Username");
try {
SQLiteDatabase db = dbHandler.getReadableDatabase();
String sql = "select * from request where Username = '" + name + "'";
Cursor rs = db.rawQuery(sql,null);
if (rs.moveToFirst()) {
do {
runOnUiThread(new Runnable() {
#SuppressLint("Range")
#Override
public void run() {
try {
final AlertDialog.Builder alert = new AlertDialog.Builder(request.this);
View mView = getLayoutInflater().inflate(R.layout.custom_dialog3, null);
final TextView txt_inputText = (TextView) mView.findViewById(R.id.name1);
txt_inputText.setText(rs.getString(rs.getColumnIndex("Name")));
final TextView txt_inputText2 = (TextView) mView.findViewById(R.id.contactno1);
txt_inputText2.setText(rs.getString(rs.getColumnIndex("contactNo")));
final TextView txt_inputText3 = (TextView) mView.findViewById(R.id.message1);
txt_inputText3.setText(rs.getString(rs.getColumnIndex("message")));
Button btn_cancel = (Button) mView.findViewById(R.id.btn_cancel);
Button btn_okay = (Button) mView.findViewById(R.id.btn_okay);
alert.setView(mView);
final AlertDialog alertDialog = alert.create();
alertDialog.setCanceledOnTouchOutside(false);
btn_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
alertDialog.dismiss();
}
});
btn_okay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String number = txt_inputText2.getText().toString();
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + number));// Initiates the Intent
startActivity(intent);
alertDialog.dismiss();
}
});
alertDialog.show();
alertDialog.getWindow().setLayout(730, 850); //Controlling width and height.
} catch (Exception e) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
}
});
}while (rs.moveToNext());
}
} catch (Exception e) {
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
}
});
}
#SuppressLint("Range")
public List<Map<String, String>> getrequestitems() {
List<Map<String, String>> data = null;
data = new ArrayList<Map<String, String>>();
try {
SQLiteDatabase db = dbHandler.getReadableDatabase();
String sql = "SELECT * from request WHERE time > date('now','-1 day')";
Cursor rs = db.rawQuery(sql,null);
if(rs.moveToFirst()) {
do {
Map<String, String> dtname = new HashMap<String, String>();
dtname.put("bloodgrp", rs.getString(rs.getColumnIndex("bloodgrp")));
dtname.put("date", "Date:- " + rs.getString(rs.getColumnIndex("Datetime1")));
dtname.put("time", "Time:- " + rs.getString(rs.getColumnIndex("time")));
dtname.put("name", "Name:- " + rs.getString(rs.getColumnIndex("Name")));
dtname.put("Username", rs.getString(rs.getColumnIndex("Username")));
data.add(dtname);
}
while (rs.moveToNext());
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
return data;
}
}
But When I open that activity It doesn't displayed any records. I have debug the code but can't any exception. I have written wrong query?
probably as it appears that you are very likely comparing the anecdotal oranges and apples (see explanation/example) that is, at a guess you are comparing the time and a date (see Possible fix below BUT this very much depends upon what you are actually storing in the time column, see Possible debug action below that would allow you to see a) if you are extracting any data and if applying the get all (no WHERE clause) to see the actual underlying data)
format is yyyy-MM-dd –
That seems unlikely or if not a waste seeing that you have a column for the date and a column for the time.
If the time contains just the time hh:mm or even hh:mm:ss, as an example then extracting the date is going to result in unintended results.
Consider the following that highlights the issues that you may encounter:-
DROP TABLE IF EXISTS request;
CREATE TABLE IF NOT EXISTS request (booldgrp TEXT, Datetime1 TEXT, time TEXT, Name TEXT, Username TEXT);
INSERT INTO request VALUES
('O','2023-01-01 10:10','2023-01-01 10:10','FRED','USER001')
,('O','2023-01-01 10:10','10:10','FRED','USER002')
,('O','2023-01-01 10:10','2023-01-01 23:11','FRED','USER003')
,('O','2023-01-01 10:10','23:59','FRED','USER004')
,('O','2023-01-01 10:10','21:59','FRED','USER005')
,('O','2023-01-01 10:10','22:00','FRED','USER006')
,('O','2023-01-01 10:10','20:00','FRED','USER007')
,('O','2023-01-01 10:10','20:01','FRED','USER008')
,('O','2023-01-01 10:10','19:59:59','FRED','USER009')
;
SELECT *, date('now','-1 day') AS comparedate, time > date('now','-1 day') AS comparison FROM request;
SELECT *, date('now','-1 day') AS comparedate, datetime1 > date('now','-1 day') AS comparison FROM request;
DROP table IF EXISTS request;
that you can run in your favourite SQLite tool (Navicat was used)
The resultant output (what would be in the Cursor) is :-
As can be seen if the time is actually stored as hh:mm or hh:mm:ss (or similar where you just have the time and not the date) then the first 2 characters are significant, so if the year of the current date - 1 day is in the 21st century that only times that are 8 pm (20:00) or greater would be selected.
Possible fix (if date column has the date only or the date and time and the time column has the time)
Perhaps you want "SELECT * from request WHERE datetime1 > date('now','-1 day')"
Possible debug action
If the above is not the fix for your situation then consider changing your code to :-
SQLiteDatabase db = dbHandler.getReadableDatabase();
String sql = "SELECT * from request /* WHERE time > date('now','-1 day') */"; // <<<<<<<<<< WHERE clause commented out to get ALL data, try also with WHERE clause */
Cursor rs = db.rawQuery(sql,null);
DatabaseUtils.dumpCursor(rs); /* ADDED FOR DEBUG, run and check the LOG */
if(rs.moveToFirst()) {
see comments
The log would include either something like (where data is extracted ):-
2022-07-19 13:21:50.995 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor#31816bf
2022-07-19 13:21:50.996 I/System.out: 0 {
2022-07-19 13:21:50.996 I/System.out: bloodgrp=O
2022-07-19 13:21:50.996 I/System.out: Datetime1=2023-01-01
2022-07-19 13:21:50.996 I/System.out: time=10:30
2022-07-19 13:21:50.996 I/System.out: Name=FRED
2022-07-19 13:21:50.996 I/System.out: Username=USER001
2022-07-19 13:21:50.996 I/System.out: }
2022-07-19 13:21:50.996 I/System.out: <<<<<
or (where no data has been extracted) :-
2022-07-19 13:24:12.216 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor#30380ea
2022-07-19 13:24:12.217 I/System.out: <<<<<
Note
The getColumnIndex index method is case sensitive (or at least was) and as such if any of the column names mismatch, even if only due to the case, then the trapped exception row 0 column -1 will also result in no result (only a short while to notice this with a Toast). I would suggest:-
using Constants for column names and ALWAYS using those Constants to refer to column names i.e. only ever hard code each column name once. Incorrect variables names will not compile. Coded incorrect column names will happily compile and may not be noticed.
consider using e.printStackTrace() as well as or even instead of the Toast
trapping and catching SQLite errors can so easily mask issues
Example
based upon your code, but with :-
DBhandler and layouts composed from what can be gleaned from your code AND
with it inserting a row when the database is created as per :-
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
REQUEST_COLUMN_BLOODGROUP + " TEXT" +
"," + REQUEST_COLUMN_DATE + " TEXT" +
"," + REQUEST_COLUMN_TIME + " TEXT" +
"," + REQUEST_COLUMN_NAME + " TEXT " +
"," + REQUEST_COLUMN_USERNAME + " TEXT" +
"," + REQUEST_COLUMN_CONTACTNo + " TEXT" +
"," + REQUEST_COLUMN_MESSAGE + " TEXT" +
")");
ContentValues cv = new ContentValues();
cv.put(REQUEST_COLUMN_BLOODGROUP,"O");
cv.put(REQUEST_COLUMN_DATE,"2023-01-01");
cv.put(REQUEST_COLUMN_TIME,"10:30");
cv.put(REQUEST_COLUMN_NAME,"FRED");
cv.put(REQUEST_COLUMN_USERNAME,"USER001");
cv.put(REQUEST_COLUMN_CONTACTNo,"0000000000");
cv.put(REQUEST_COLUMN_MESSAGE,"MESSAGE X");
db.insert(TABLE_NAME,null,cv);
}
with the Request (changed to capitalise) Activity started directly from the MainActivity
and with the possible fix applied to the WHERE clause (i.e. Datetime column used for the comparison rather than the time column)
The ListView with a Teal background (to distinguish it)
Then when run :-
and then when the item is clicked:-
and if OK is clicked :-
so I'm having some trouble with SQLLite/Android studio, I have an activity that lets me update a user's password through an SQLLite function but it doesn't seem to be working, when I press the update password button, nothing happens, and the database doesn't update.
SQLLITE Update:
public int updateShopper(Shopper shopper)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COL_SPPASS, shopper.getShopperPS());
String[] l = {shopper.getShopperID()+""};
return db.update(TABLE_NAME, values, COL_SPID + " =? ",l);
}
Get all shoppers :
public ArrayList<Shopper> getAllShoppers()
{
ArrayList splist = new ArrayList();
String selectQuery = "SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, null);
if(c.moveToFirst())
{
do {
Shopper shopper = new Shopper();
shopper.setShopperUN(c.getString((c.getColumnIndex(COL_SPNAME))));
shopper.setShopperPS(c.getString(c.getColumnIndex(COL_SPPASS)));
splist.add(shopper);
} while(c.moveToNext());
}
return splist;
}
}
Activity Button :
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String username = ed1.getText().toString();
String password = ed2.getText().toString();
SQLShop sqlsp2 = new SQLShop(getApplicationContext());
ArrayList splist=sqlsp2.getAllShoppers();
for(int i=0;i<splist.size();i++)
{
Shopper sp=(Shopper) splist.get(i);
if(username.equalsIgnoreCase(sp.getShopperUN()))
{
Shopper shopper = new Shopper();
shopper.setShopperUN(username);
shopper.setShopperPS(password);
shopper.setShopperID(shopper.getShopperID());
sqlsp2.updateShopper(shopper);
break;
}
}
Intent i = new Intent(getApplicationContext(), MainActivity.class);
startActivity(i);
}
});
In your getAllShoppers() you're not setting the shopper id and it remains as 0. Trying to update a row with id 0 matches no rows, so no rows are updated.
After adding reading the shopper id from the database, fix this part too:
shopper.setShopperID(shopper.getShopperID());
Here you're assigning the id of a new Shopper back to itself so it stays as 0 default value. Change shopper.getShopperID() to sp.getShopperID().
I am having trouble getting my database to effectively store information. I am using Android Studio and I am trying to create a sqlite db on the fly and insert information into it.
I am not able to insert information into my table ( I am returning a -1), however, I am not sure if the problem is the insert statement or the table/db creation.
Here is the code. Any help would be appreciated.. I have been banging my head on this for a while now.
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "DatabaseHelper";
SQLiteDatabase database;
private static final String Database_Name = "CISP_340.db";
private static final String Table_Name = "ANIMALS";
private static final String col1 = "_ID";
private static final String col2 = "ANIMAL_TYPE_CD";
private static final String col3 = "COUNT_NO";
private static final String col4 = "SEENON_DTM";
private static final String col5 = "COMMENTS_TXT";
public DatabaseHelper(Context context){
super(context, Table_Name, null, 1);
database = getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + Table_Name + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, "+
col2 + " INTEGER DEFAULT 0, " +
col3 +" INTEGER, " +
col4 + " TEXT, " +
col5 + " TEXT)";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP IF TABLE EXISTS " + Table_Name);
onCreate(db);
}
public boolean addData(Animal animal){
ContentValues contentValues = new ContentValues();
contentValues.put(col5, animal.getComments());
Log.d(TAG, "addData: Adding " + animal.toString() + " to " + Table_Name);
long result = database.insert(Table_Name, null, contentValues);
if (result == -1) {
return false;
}else{
return true;
}
}
public Cursor getData(){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + Table_Name;
Cursor data = db.rawQuery(query, null);
return data;
}
}
Here is my animal Class:
public class Animal {
Animal(){
//Blank
}
Animal(int animalType, int count, String seenOn, String comments){
this.animalType = animalType;
this.count = count;
this.seenOn = seenOn;
this.comments = comments;
}
private int animalType;
private int count;
private String seenOn;
private String comments;
public int getAnimalType() {
return animalType;
}
public void setAnimalType(int type){
this.animalType = type;
}
public int getCount() {
return count;
}
public void setCount(int count){
this.count = count;
}
public String getSeenOn() {
return seenOn;
}
public void setSeenOn(String seenOn){
this.seenOn = seenOn;
}
public String getComments() {
return comments;
}
public void setComments(String comments){
this.comments = comments;
}
#Override
public String toString(){
return "Animal type: " + animalType + ", Animal count: " + count + ", Animal was seen on: " + seenOn + ", Comments about encounter: " + comments;
}
}
Here is my MainActivity:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
DatabaseHelper dataBaseHelper;
private Button btnAdd, btnView;
private EditText editText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText);
btnAdd = (Button) findViewById(R.id.btnAdd);
btnView = (Button) findViewById(R.id.btnView);
dataBaseHelper = new DatabaseHelper(this);
Animal myAnimal = new Animal(1, 0, "Yes", "Raining");
Animal myAnimal2 = new Animal(1, 0, "No", "");
addAnimal(myAnimal);
addAnimal(myAnimal2);
btnAdd.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
Animal animal = new Animal();
animal.setComments(editText.getText().toString());
if (editText.length() != 0){
addAnimal(animal);
editText.setText("");
}else{
returnMessage("You must put something into this field");
}
}
});
btnView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
Intent intent = new Intent(MainActivity.this, ListDataActivity.class);
startActivity(intent);
}
});
}
public void addAnimal( Animal animal ){
boolean insertData = dataBaseHelper.addData(animal);
if (insertData){
returnMessage("Success");
}else{
returnMessage("Fail");
}
}
private void returnMessage(String message){
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
}
Output in LogCat when attempting to insert in the constructor:
12-02 17:20:23.624 4100-4100/edu.davenport.cisp340.animaltracker E/SQLiteDatabase: Error inserting COUNT_NO=0 ANIMAL_TYPE_CD=1 SEENON_DTM=Yes COMMENTS_TXT=Raining
android.database.sqlite.SQLiteException: table ANIMALS has no column named SEENON_DTM (code 1): , while compiling: INSERT INTO ANIMALS(COUNT_NO,ANIMAL_TYPE_CD,SEENON_DTM,COMMENTS_TXT) VALUES (?,?,?,?)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1472)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1343)
at edu.davenport.cisp340.animaltracker.DatabaseHelper.addData(DatabaseHelper.java:59)
at edu.davenport.cisp340.animaltracker.MainActivity.addAnimal(MainActivity.java:65)
at edu.davenport.cisp340.animaltracker.MainActivity.onCreate(MainActivity.java:32)
at android.app.Activity.performCreate(Activity.java:6980)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6540)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Edit
Now that you added the log. The issue is that column SEENON_DTM doesn't exist.
As per :-
table ANIMALS has no column named SEENON_DTM
You have probably added the column since running the App. Just amending the SQL used by the onCreate method isn't enough to change the structure of the database. That is onCreate is only run once when the database is created, the database is then saved to a file and hence how it stays around. Subequent instantation of the DatabaseHelper, find the file and doesn't call onCreate.
The fix, if losing any data (no useful data would likely exist) isn't an issue is to do one of the following;
delete the App's data (from settings), or
uninstall the App, or
increase the database version i.e. change super(context, Table_Name, null, 1); to super(context, Table_Name, null, 2); (1 to 2)
(this will result in the onUpgrade method running which should drop the table (see note below about using DROP TABLE IF EXISTS and not DROP IF TABLE EXISTS))
and then rerun the App.
I believe that you code is not an issue (the only issue in the code is with DROP IF TABLE EXISTS, it should be DROP TABLE IF EXISTS ).
Your code works as expected (see below), so the issue is either how you are checking the data or that the Animal class is the cause.
Below is code that uses you DatabaseHelper code and invokes it from an Activity (the Animal class may be different to yours).
I'd suggest trying the code below, suitably adjusted for your DatabaseHelper class (i.e. change AnimalDBhelper to DatabaseHelper) and then checking the log. The output should be as below (perhaps with more rows if you have added rows and the database hasn't been deleted).
Testing
Using a copy of your code (renaming the class to AnimalDBhelper to suit my testing environment) and then using the following code in an activity (the invoking code) :-
public class MainActivity extends AppCompatActivity {
AnimalDBhelper mADBHlpr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
// Create two animals
mADBHlpr = new AnimalDBhelper(this);
Animal myanimal1 = new Animal(1,0,"Yes","Raining");
Animal myanimal2 = new Animal(1,0,"No","");
mADBHlpr.addData(myanimal1); // Add the first animal
Cursor csr = mADBHlpr.getData(); get the data
DatabaseUtils.dumpCursor(csr); dump the data (write it to the log)
mADBHlpr.addData(myanimal2); // Add the 2nd
csr = mADBHlpr.getData();
DatabaseUtils.dumpCursor(csr);
csr.close(); // Done with the cursor so close
}
}
Result :-
12-02 19:37:54.040 1172-1172/? D/DatabaseHelper: addData: Adding ?.Animal#534af570 to ANIMALS
12-02 19:37:54.044 1172-1172/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor#534a5df8
12-02 19:37:54.044 1172-1172/? I/System.out: 0 {
12-02 19:37:54.044 1172-1172/? I/System.out: ID=1
12-02 19:37:54.044 1172-1172/? I/System.out: ANIMAL_TYPE_CD=0
12-02 19:37:54.044 1172-1172/? I/System.out: COUNT_NO=null
12-02 19:37:54.044 1172-1172/? I/System.out: SEENON_DTM=null
12-02 19:37:54.044 1172-1172/? I/System.out: COMMENTS_TXT=Raining
12-02 19:37:54.044 1172-1172/? I/System.out: }
12-02 19:37:54.044 1172-1172/? I/System.out: <<<<<
12-02 19:37:54.044 1172-1172/? D/DatabaseHelper: addData: Adding ?.Animal#534af5c4 to ANIMALS
12-02 19:37:54.048 1172-1172/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor#534ab7d4
12-02 19:37:54.048 1172-1172/? I/System.out: 0 {
12-02 19:37:54.048 1172-1172/? I/System.out: ID=1
12-02 19:37:54.048 1172-1172/? I/System.out: ANIMAL_TYPE_CD=0
12-02 19:37:54.048 1172-1172/? I/System.out: COUNT_NO=null
12-02 19:37:54.048 1172-1172/? I/System.out: SEENON_DTM=null
12-02 19:37:54.048 1172-1172/? I/System.out: COMMENTS_TXT=Raining
12-02 19:37:54.048 1172-1172/? I/System.out: }
12-02 19:37:54.048 1172-1172/? I/System.out: 1 {
12-02 19:37:54.048 1172-1172/? I/System.out: ID=2
12-02 19:37:54.048 1172-1172/? I/System.out: ANIMAL_TYPE_CD=0
12-02 19:37:54.048 1172-1172/? I/System.out: COUNT_NO=null
12-02 19:37:54.048 1172-1172/? I/System.out: SEENON_DTM=null
12-02 19:37:54.048 1172-1172/? I/System.out: COMMENTS_TXT=
12-02 19:37:54.048 1172-1172/? I/System.out: }
12-02 19:37:54.048 1172-1172/? I/System.out: <<<<<
You haven't really described what's going wrong (are you querying the Cursor and not finding the data you expect?), but you need to close the cursor somewhere (see this answer), and you don't need to get the database in getComment() since you already have it. Here's a version that ought to work in your example class.
public String getComment(){
String query = "SELECT * FROM " + Table_Name;
String comments = "";
Cursor data = database.rawQuery(query, null);
if( data.moveToFirst() ) { // iterate all the rows of the table
do {
String val = data.getString(4); // pull out column 5
// String val = data.getString(data.getColumnIndex(col5)); // or this way if you prefer
comments += val; // do something with the data - e.g. rebuild Animal object
} while (data.moveToNext());
}
data.close();
return comments;
}
When I call function 'test' my app crashes. Any ideas why does that happen?
DB class
package com.example.paulcosma.app2;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DB extends SQLiteOpenHelper{
public static final String
dbName = "foods.db",
tableName = "foods",
colId = "id",colName = "name",colCarbs = "carbs";
public DB(Context context) {
super(context, dbName, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + dbName + "( " + colId + " INTEGER PRIMARY KEY AUTOINCREMENT," + colName + " TEXT," + colCarbs + " REAL)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists " + dbName);
onCreate(db);
}
public boolean addFood(String Name, float Carbs){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(colName,Name);
contentValues.put(colCarbs,Carbs);
long result = db.insert(tableName,null,contentValues);
return result != -1; // -1 == not inserted
}
}
MainActivity
package com.example.paulcosma.app2;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
DB db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new DB(this);
}
public void test(View v){
boolean insertedSuccessfully = db.addFood("Milk",4); // crashes when called
if(insertedSuccessfully)
Toast.makeText(this,"inserted",Toast.LENGTH_LONG).show();
else Toast.makeText(this,"not inserted",Toast.LENGTH_LONG).show();
}
}
logcat
01-20 19:59:47.888 9565-9565/com.example.paulcosma.app2 E/InstantRun:
Could not find slices in APK; aborting. 01-20 19:59:47.988
9565-9565/com.example.paulcosma.app2 E/dalvikvm: Could not find class
'android.graphics.drawable.RippleDrawable', referenced from method
android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
01-20 19:59:48.005 9565-9565/com.example.paulcosma.app2 E/TextView:
zhangcl: get font resource from application failed. 01-20
19:59:48.013 9565-9565/com.example.paulcosma.app2 E/TextView: zhangcl:
get font resource from application failed -- 2. 01-20 19:59:48.045
9565-9565/com.example.paulcosma.app2 E/TextView: zhangcl: get font
resource from application failed. 01-20 20:00:02.211
9565-9565/com.example.paulcosma.app2 E/SQLiteLog: (10) Failed to do
file read, got: 0, amt: 100, last Errno: 2 01-20 20:00:02.244
9565-9565/com.example.paulcosma.app2 E/SQLiteLog: (1) unknown database
foods 01-20 20:00:02.263 9565-9565/com.example.paulcosma.app2
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.paulcosma.app2, PID: 9565
java.lang.IllegalStateException: Could not execute method for
android:onClick
You've got a typo in onCreate(). You're using dbName instead of tableName to create your table, therefore when you're running your query which is looking up the correct name, you're looking up a table that doesn't exist. So:
db.execSQL("create table " + dbName + "( " + colId + " INTEGER PRIMARY KEY AUTOINCREMENT," + colName + " TEXT," + colCarbs + " REAL)");
needs to become:
db.execSQL("create table " + tableName + "( " + colId + " INTEGER PRIMARY KEY AUTOINCREMENT," + colName + " TEXT," + colCarbs + " REAL)");
so in my app i am using get and set methods. when it executes the set method, the app doesnt crash but when it gets to the get method, it crashes. i worked out that it crashes when it gets to the db.query() line in the get method but i think the problem could also be in the set method since they both give error messages.
here is my code:
public class MyDBHandler extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static final String COLUMN_ID = "_id";
public static final String TABLE_VALUES = "values";
public static final String COLUMN_TARGET = "target";
public static final String COLUMN_CURRENT = "current";
public MyDBHandler(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String query1 = "CREATE TABLE " + TABLE_VALUES + " (" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
COLUMN_TARGET + " INT, " +
COLUMN_CURRENT + " INT);";
db.execSQL(query1);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_VALUES);
onCreate(db);
}
public void setTarget(int tar){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_TARGET, tar);
values.put(COLUMN_CURRENT, 0);
db.insert(TABLE_VALUES, null, values);
db.close();
}
public int getTarget() {
SQLiteDatabase db = this.getReadableDatabase();
int targetVal=0;
String[] columns = {COLUMN_TARGET};
Cursor c = db.query(TABLE_VALUES, columns, null, null, null, null, String.valueOf(1));
if(c.getCount()>0)
{
c.moveToFirst();
targetVal=c.getInt(0);
}
db.close();
c.close();
return targetVal;
}
}
the set function is used here:
public class home extends AppCompatActivity {
MyDBHandler db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
db = new MyDBHandler(this);
}
public void enter(View view)
{
EditText target = (EditText) findViewById(R.id.target);
TextView warning = (TextView) findViewById(R.id.warning);
String check = target.getText().toString();
if(check.equals("")) {
// Intent a = new Intent(this, MainActivity.class);
//startActivity(a);
warning.setText("Please enter a value");
return;
}
else {
int input = Integer.parseInt(check);
Log.d("tag", "111\n");
db.setTarget(input);
Log.d("tag", "222\n");
//int i = db.getTarget();
//Log.d("tag","input is " + i );
Intent a = new Intent(this, MainActivity.class);
startActivity(a);
}
}
}
the get function is used here:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onTrack(View view){
Log.d("tag", "traaaack\n");
Intent i = new Intent(this, Track.class);
startActivity(i);
}
}
and here are the error messages parts from the log.
this is when the set method is called:
E/SQLiteLog: (1) near "values": syntax error
E/SQLiteDatabase: Error inserting current=0 target=2000
android.database.sqlite.SQLiteException: near "values": syntax error (code 1): , while compiling: INSERT INTO values(current,target) VALUES (?,?)
this is when the get method is called:
E/SQLiteLog: (1) near "values": syntax error
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.user.calorietracker/com.example.user.calorietracker.Track}: android.database.sqlite.SQLiteException: near "values": syntax error (code 1): , while compiling: SELECT target FROM values LIMIT 1
I have tried so many things to fix it but cant work out what i am doing wrong. literally any suggestion would be helpful! thanks
According to the list of SQLite Keywords - the word values is one of the words that you can't use for the name of your table (or column or many other things).
There are several ways to fix this:
Don't use this word. You can always use tbl_values for example.
You can quote that word:
'keyword' A keyword in single quotes is a string literal.
"keyword" A keyword in double-quotes is an identifier.
[keyword] A keyword enclosed in square brackets is an identifier. This is not standard SQL. This quoting mechanism is used by MS Access and SQL Server and is included in SQLite for compatibility.
`keyword` A keyword enclosed in grave accents (ASCII code 96) is an identifier. This is not standard SQL. This quoting mechanism is used by MySQL and is included in SQLite for compatibility.