I have been following a datababse tutorial of commonsware which is the LunchList example, however i would love to know how i can add a delete button, so that i could delete a lunch item once its been created.
I have searched around and found this answer but i'm just not sure how to implement it, please could someone show me how
Add a delete() method to the RestaurantHelper class and call it from
an options menu item on the DetailForm activity.
Thanks
Lucy
ResaurantHelper.java
import android.content.Context;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
class RestaurantHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME="Lunchlist.db";
private static final int SCHEMA_VERSION=1;
public RestaurantHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE restaurants (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, address TEXT, type TEXT, notes TEXT);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// no-op, since will not be called until 2nd schema
// version exists
}
public Cursor getAll() {
return(getReadableDatabase()
.rawQuery("SELECT _id, name, address, type, notes FROM restaurants ORDER BY name",
null));
}
public void insert(String name, String address,
String type, String notes) {
ContentValues cv=new ContentValues();
cv.put("name", name);
cv.put("address", address);
cv.put("type", type);
cv.put("notes", notes);
getWritableDatabase().insert("restaurants", "name", cv);
}
public String getName(Cursor c) {
return(c.getString(1));
}
public String getAddress(Cursor c) {
return(c.getString(2));
}
public String getType(Cursor c) {
return(c.getString(3));
}
public String getNotes(Cursor c) {
return(c.getString(4));
}
}
LunchList.java
package apt.tutorial;
import android.app.TabActivity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.widget.AdapterView;
import android.widget.CursorAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.TabHost;
import android.widget.TextView;
public class LunchList extends TabActivity {
Cursor model=null;
RestaurantAdapter adapter=null;
EditText name=null;
EditText address=null;
EditText notes=null;
RadioGroup types=null;
RestaurantHelper helper=null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
helper=new RestaurantHelper(this);
name=(EditText)findViewById(R.id.name);
address=(EditText)findViewById(R.id.addr);
notes=(EditText)findViewById(R.id.notes);
types=(RadioGroup)findViewById(R.id.types);
address.setVisibility(View.GONE);
notes.setVisibility(View.GONE);
Button save=(Button)findViewById(R.id.save);
save.setOnClickListener(onSave);
ListView list=(ListView)findViewById(R.id.restaurants);
model=helper.getAll();
startManagingCursor(model);
adapter=new RestaurantAdapter(model);
list.setAdapter(adapter);
TabHost.TabSpec spec=getTabHost().newTabSpec("tag1");
spec.setContent(R.id.restaurants);
spec.setIndicator("My Reasons", getResources()
.getDrawable(R.drawable.list));
getTabHost().addTab(spec);
spec=getTabHost().newTabSpec("tag2");
spec.setContent(R.id.details);
spec.setIndicator("Add Reason", getResources()
.getDrawable(R.drawable.restaurant));
getTabHost().addTab(spec);
getTabHost().setCurrentTab(0);
list.setOnItemClickListener(onListClick);
}
#Override
public void onDestroy() {
super.onDestroy();
helper.close();
}
private View.OnClickListener onSave=new View.OnClickListener() {
public void onClick(View v) {
String type=null;
switch (types.getCheckedRadioButtonId()) {
case R.id.sit_down:
type="sit_down";
break;
case R.id.take_out:
type="take_out";
break;
case R.id.delivery:
type="delivery";
break;
}
helper.insert(name.getText().toString(),
address.getText().toString(), type,
notes.getText().toString());
model.requery();
}
};
private AdapterView.OnItemClickListener onListClick=new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent,
View view, int position,
long id) {
model.moveToPosition(position);
name.setText(helper.getName(model));
address.setText(helper.getAddress(model));
notes.setText(helper.getNotes(model));
if (helper.getType(model).equals("sit_down")) {
types.check(R.id.sit_down);
}
else if (helper.getType(model).equals("take_out")) {
types.check(R.id.take_out);
}
else {
types.check(R.id.delivery);
}
getTabHost().setCurrentTab(1);
}
};
class RestaurantAdapter extends CursorAdapter {
RestaurantAdapter(Cursor c) {
super(LunchList.this, c);
}
#Override
public void bindView(View row, Context ctxt,
Cursor c) {
RestaurantHolder holder=(RestaurantHolder)row.getTag();
holder.populateFrom(c, helper);
}
#Override
public View newView(Context ctxt, Cursor c,
ViewGroup parent) {
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.row, parent, false);
RestaurantHolder holder=new RestaurantHolder(row);
row.setTag(holder);
return(row);
}
}
static class RestaurantHolder {
private TextView name=null;
private TextView address=null;
private ImageView icon=null;
RestaurantHolder(View row) {
name=(TextView)row.findViewById(R.id.title);
address=(TextView)row.findViewById(R.id.address);
icon=(ImageView)row.findViewById(R.id.icon);
}
void populateFrom(Cursor c, RestaurantHelper helper) {
name.setText(helper.getName(c));
address.setText(helper.getAddress(c));
if (helper.getType(c).equals("sit_down")) {
icon.setImageResource(R.drawable.ball_red);
}
else if (helper.getType(c).equals("take_out")) {
icon.setImageResource(R.drawable.ball_yellow);
}
else {
icon.setImageResource(R.drawable.ball_green);
}
}
}
}
Add a new Button (btnDelete) to your layout-xml
mount it in your code using Button btnDel =(Button)findViewById(R.id.btnDelete);
Add a clickListener on it using:
btnDel.setOnClickListener)new OnClickListener()
{
#Override
public void onClick(View v)
{
//add SQL deletion code here
}
});
And final execute the SQL deletion statement in the onClickListener ;)
If you can check a matching ID, this could work
db.execSQL("DELETE FROM restaurants WHERE id = '+" idToDelete "+' ;");
I am fairly certain that you need to carry on with the tutorials. Having watched Commons_Ware (the book's author and extremely active member here) on the site I doubt he will leave you hanging. I am quite certain he teaches the complete CRUD model one step at a time.
As a side note, if you haven't purchased a subscription to his books, I highly recomend it. They are updated frequently to include the latest info.
Rather than using execSQL() for deletion, use following :
To delete entire table:
db.delete(DATABASE_TABLE, null, null);
To delete particular records in a table:
db.delete(DATABASE_TABLE, whereCondition, null);
for eg:
db.delete(restaurants, "id = '"+ IdToBeDeleted +"'", null);
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
I am trying to add data to the SQLite database but when I add the data it gives me null pointer exception.
This is the error in the logcat
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getDatabasePath(java.lang.String)' on a null object reference
enter code here
package com.llmago.autism;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Objects;
public class StartFragment extends Fragment {
private EditText edtName, edtAge, edtScore;
private Button save, load;
Db db = new Db(getActivity());
public StartFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_start, container, false);
initUI(view);
// Inflate the layout for this fragment
return view;
}
public void initUI(View view) {
edtName = view.findViewById(R.id.name);
edtAge = view.findViewById(R.id.age);
edtScore = view.findViewById(R.id.result);
save = view.findViewById(R.id.save);
save.setOnClickListener(v -> btnSaveAction(view));
}
public void btnSaveAction(View view) {
String name = edtName.getText().toString();
String age = edtAge.getText().toString();
String score = edtScore.getText().toString();
boolean result = db.insertData(name, age, score);
if (result == true) {
Toast.makeText(getActivity(), "Done", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(), "Error", Toast.LENGTH_LONG).show();
}
}
}
package com.llmago.autism;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
public class Db extends SQLiteOpenHelper {
public static final String databaseName = "autism.db";
public Db(#Nullable Context context) {
super(context, databaseName, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table autism(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age TEXT, score TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS autiusm");
onCreate(db);
}
public boolean insertData(String name, String age, String score){
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("name", name);
contentValues.put("age", age);
contentValues.put("score", score);
long result = sqLiteDatabase.insert("autism", null, contentValues);
if (result == -1)
return false;
else
return true;
}
}
Declare the mContext inside FragmentClass
Context mContext;
Change constructor from
public StartFragment(Context context) {
mContext = context;
db = new Db(mContext);
}
Also replace the db() constructor
public Db(#Nullable Context context) {
super(context, databaseName, null, 1);
this.getWritableDatabase();
}
Note: When you creating fragment instance you have to pass Activity Reference
I am trying to write a Race database where you would enter a race name and a race date, then click on that race name, and edit/delete it or the date. I am having trouble input the date. below is my LogCat error.
What am I doing wrong ?
//LOGCAT
12-08 20:15:35.710: I/Database(1648): sqlite returned: error code = 1, msg = near "FROM": syntax error
12-08 20:15:35.710: E/ERROR(1648): ERROR IN CODE: android.database.sqlite.SQLiteException: near "FROM": syntax error: , while compiling: SELECT _id, note FROM Races, date FROM Races
12-08 20:15:35.721: W/System.err(1648): android.database.sqlite.SQLiteException: near "FROM": syntax error: , while compiling: SELECT _id, note FROM Races, date FROM Races
12-08 20:15:35.730: W/System.err(1648): at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
//View races java code
package com.CIS2818.tritracker;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
public class View_races extends Activity {
NoteAdapter adapter=null;
RaceHelper helper2=null;
Cursor dataset_cursor=null;
EditText editNote2=null;
EditText editNote3=null;
String noteId2=null;
String TAG = "INFORMATION";
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try
{
setContentView(R.layout.activity_view_races);
ListView list2=(ListView)findViewById(R.id.list2);
editNote2 = (EditText)findViewById(R.id.myEditText2);
editNote3 = (EditText)findViewById(R.id.myEditText3);
helper2=new RaceHelper(this);
dataset_cursor=helper2.getAll();
startManagingCursor(dataset_cursor);
adapter=new NoteAdapter(dataset_cursor);
list2.setAdapter(adapter);
Button btnSimple2 = (Button) findViewById(R.id.btnSimple2);
btnSimple2.setOnClickListener(onSave);
Button btnDelete2 = (Button) findViewById(R.id.btnDelete2);
btnDelete2.setOnClickListener(onDelete);
list2.setOnItemClickListener(onListClick);
}
catch (Exception e)
{
Log.e("ERROR", "ERROR IN CODE: " + e.toString());
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
helper2.close();
}
private View.OnClickListener onSave=new View.OnClickListener() {
#SuppressWarnings("deprecation")
public void onClick(View v) {
Log.i(TAG,"You passed through the save method");
if (noteId2==null) {
helper2.insert(editNote2.getText().toString(),editNote3.getText().toString());
}
else{
helper2.update(noteId2, editNote2.getText().toString(),editNote3.getText().toString());
noteId2=null;
}
dataset_cursor.requery();
editNote2.setText("");
}
};
private View.OnClickListener onDelete=new View.OnClickListener() {
#SuppressWarnings("deprecation")
public void onClick(View v) {
if (noteId2==null) {
return;
}
else{
helper2.delete(noteId2);
noteId2=null;
}
dataset_cursor.requery();
editNote2.setText("");
}
};
private AdapterView.OnItemClickListener onListClick=new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent,
View view, int position,
long id2)
{
noteId2 =String.valueOf(id2);
Cursor c=helper2.getById(noteId2);
c.moveToFirst();
editNote2.setText(helper2.getNote(c));
}
};
class NoteAdapter extends CursorAdapter {
#SuppressWarnings("deprecation")
NoteAdapter(Cursor c) {
super(View_races.this, c);
}
#Override
public void bindView(View row, Context ctxt,Cursor c) {
NoteHolder2 holder=(NoteHolder2)row.getTag();
holder.populateFrom(c, helper2);
}
#Override
public View newView(Context ctxt, Cursor c,ViewGroup parent) {
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.row2, parent, false);
NoteHolder2 holder=new NoteHolder2(row);
row.setTag(holder);
return(row);
}
}
static class NoteHolder2 {
private TextView noteText2=null;
NoteHolder2(View row) {
noteText2=(TextView)row.findViewById(R.id.note2);
}
void populateFrom(Cursor c, RaceHelper helper) {
noteText2.setText(helper.getNote(c));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_view_races, menu);
return true;}
//Button Method to return to the main Menu
public void Menu(View v){
Intent intent = new Intent(this, MainMenuActivity.class);
startActivity(intent);
}
//Button Method to go to the Race Activity
public void Races(View v){
Intent intent = new Intent(this, UpComingRaceActivity.class);
startActivity(intent);
}
}
// RaceHelper java code
package com.CIS2818.tritracker;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
class RaceHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME="Races.db";
private static final int SCHEMA_VERSION=2;
String TAG = "INFORMATION";
public RaceHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE Races (_id INTEGER PRIMARY KEY AUTOINCREMENT, note TEXT, date TEXT);");
Log.i(TAG, "You are in the creation of db");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void insert(String note, String date) {
ContentValues cv=new ContentValues();
cv.put("note", note);
getWritableDatabase().insert("Races", "note", cv);
Log.i(TAG, "You have succesfully inserted into the db");
}
public void update(String id, String note, String date) {
ContentValues cv=new ContentValues();
String[] args={id};
cv.put("note", note);
getWritableDatabase().update("Races", cv, "_id=?", args);
}
public void delete(String id) {
getWritableDatabase().delete("Races", "_id=?", new String[] {id});
}
public Cursor getAll() {
return(getReadableDatabase()
.rawQuery("SELECT _id, note FROM Races, date FROM Races",
null));
}
public String getNote(Cursor c) {
return(c.getString(1));
}
public Cursor getById(String id) {
String[] args={id};
return(getReadableDatabase()
.rawQuery("SELECT _id, note FROM Races WHERE _id=?",
args));
}
Change below line
getReadableDatabase().rawQuery("SELECT _id, note FROM Races, date FROM Races",
null)
to
getReadableDatabase().rawQuery("SELECT _id, note, data FROM Races",
null)
I am trying to write a Race database where you would enter a race name, then click on that race name, and edit/delete it.
So I am getting an error in my logcat (error code=1). It tells me there is no table created so I think I am not calling my variables correctly.
//LogCat
12-08 12:46:21.019: I/INFORMATION(650): You entered the insert method
12-08 12:46:21.019: I/Database(650): sqlite returned: error code = 1, msg = no such table: Note
12-08 12:46:21.062: E/Database(650): Error inserting note=ft
12-08 12:46:21.062: E/Database(650): android.database.sqlite.SQLiteException: no such table: Note: , while compiling: INSERT INTO Note(note) VALUES(?);
12-08 12:46:21.062: E/Database(650): at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
12-08 12:46:21.062: E/Database(650): at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:92)
12-08 12:46:21.062: E/Database(650): at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:65)
//View races java code
package com.CIS2818.tritracker;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
public class View_races extends Activity {
NoteAdapter adapter=null;
RaceHelper helper2=null;
Cursor dataset_cursor=null;
EditText editNote2=null;
String noteId2=null;
String TAG = "INFORMATION";
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try
{
setContentView(R.layout.activity_view_races);
ListView list2=(ListView)findViewById(R.id.list2);
editNote2 = (EditText)findViewById(R.id.myEditText2);
helper2=new RaceHelper(this);
dataset_cursor=helper2.getAll();
startManagingCursor(dataset_cursor);
adapter=new NoteAdapter(dataset_cursor);
list2.setAdapter(adapter);
Button btnSimple2 = (Button) findViewById(R.id.btnSimple2);
btnSimple2.setOnClickListener(onSave);
Button btnDelete2 = (Button) findViewById(R.id.btnDelete2);
btnDelete2.setOnClickListener(onDelete);
list2.setOnItemClickListener(onListClick);
}
catch (Exception e)
{
Log.e("ERROR", "ERROR IN CODE: " + e.toString());
e.printStackTrace();
}
}
#Override
public void onDestroy() {
super.onDestroy();
helper2.close();
}
private View.OnClickListener onSave=new View.OnClickListener() {
#SuppressWarnings("deprecation")
public void onClick(View v) {
Log.i(TAG,"You passed through the save method");
if (noteId2==null) {
helper2.insert(editNote2.getText().toString());
}
else{
helper2.update(noteId2, editNote2.getText().toString());
noteId2=null;
}
dataset_cursor.requery();
editNote2.setText("");
}
};
private View.OnClickListener onDelete=new View.OnClickListener() {
#SuppressWarnings("deprecation")
public void onClick(View v) {
if (noteId2==null) {
return;
}
else{
helper2.delete(noteId2);
noteId2=null;
}
dataset_cursor.requery();
editNote2.setText("");
}
};
private AdapterView.OnItemClickListener onListClick=new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent,
View view, int position,
long id2)
{
noteId2 =String.valueOf(id2);
Cursor c=helper2.getById(noteId2);
c.moveToFirst();
editNote2.setText(helper2.getNote(c));
}
};
class NoteAdapter extends CursorAdapter {
#SuppressWarnings("deprecation")
NoteAdapter(Cursor c) {
super(View_races.this, c);
}
#Override
public void bindView(View row, Context ctxt,Cursor c) {
NoteHolder2 holder=(NoteHolder2)row.getTag();
holder.populateFrom(c, helper2);
}
#Override
public View newView(Context ctxt, Cursor c,ViewGroup parent) {
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.row2, parent, false);
NoteHolder2 holder=new NoteHolder2(row);
row.setTag(holder);
return(row);
}
}
static class NoteHolder2 {
private TextView noteText2=null;
NoteHolder2(View row) {
noteText2=(TextView)row.findViewById(R.id.note2);
}
void populateFrom(Cursor c, RaceHelper helper) {
noteText2.setText(helper.getNote(c));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_view_races, menu);
return true;
}
//Button Method to return to the main Menu
public void Menu(View v){
Intent intent = new Intent(this, MainMenuActivity.class);
startActivity(intent);
}
//Button Method to go to the Race Activity
public void Races(View v){
Intent intent = new Intent(this, UpComingRaceActivity.class);
startActivity(intent);
}}
//RaceHelper java code
package com.CIS2818.tritracker;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
class RaceHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME="note2.db";
private static final int SCHEMA_VERSION=1;
String TAG ="INFORMATION";
public RaceHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE Note (_id INTEGER PRIMARY KEY AUTOINCREMENT, note TEXT);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void insert(String note2) {
Log.i(TAG,"You entered the insert method");
ContentValues cv2=new ContentValues();
cv2.put("note", note2);
getWritableDatabase().insert("Note", "note", cv2);
}
public void update(String id, String note2) {
ContentValues cv2=new ContentValues();
String[] args={id};
cv2.put("note", note2);
getWritableDatabase().update("Note", cv2, "_id=?", args);
}
public void delete(String id2) {
getWritableDatabase().delete("Note", "_id=?", new String[] {id2});
}
public Cursor getAll() {
return(getReadableDatabase()
.rawQuery("SELECT _id, note FROM Notes",
null));
}
public String getNote(Cursor c2) {
return(c2.getString(1));
}
public Cursor getById(String id2) {
String[] args={id2};
return(getReadableDatabase()
.rawQuery("SELECT _id, note FROM Note WHERE _id=?",
args));
}
}
It appears you have changed your SQL schema in your Java code but haven't informed SQLite. In order for your SQLiteOpenHelper class to use the new schema you provided in onCreate(), you need to upgrade your database. This is the most basic approach.
First add some functionality to onUpgrade():
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS Note");
onCreate(db);
}
Now increment SCHEMA_VERSION to trigger an upgrade:
private static final int SCHEMA_VERSION=2;
Understand that SQLiteOpenHelper does not check the code inside onCreate() for you, you must tell SQLite there is a change by incrementing SCHEMA_VERSION.
In your insert method make the second value null. For example getWritableDatabase().insert("Note",null,cv2);
I have the same question as yours.I solved it.At first I rename the table that I create but do nothing with the CREATE_DATABASE order.Then I notice it. Although I corrected the order it does not works.So I add the onUpgrade method, and increment DATABASE_VERSION to a higher number,it works!!!Hope it works also for you.
I have the following two files:
podatkovna_baza.java
package com.example.ultimate.basketball.stats;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class podatkovna_baza extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "baza5";
public podatkovna_baza(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase baza5) {
/*
* Create the employee table and populate it with sample data.
* In step 6, we will move these hardcoded statements to an XML document.
*/
String sql = "CREATE TABLE IF NOT EXISTS ekipe4 (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"ime_ekipe TEXT, " +
"kratko_ime TEXT, " +
"kraj TEXT, " +
"slika TEXT )";
baza5.execSQL(sql);
ContentValues values = new ContentValues();
values.put("ime_ekipe", "Drustvo partizan");
values.put("kratko_ime", "DRP");
values.put("kraj", "Mirna");
values.put("slika", "jajaja");
baza5.insert("ekipe4", null, values);
}
#Override
public void onUpgrade(SQLiteDatabase baza5, int oldVersion, int newVersion) {
baza5.execSQL("DROP TABLE IF EXISTS ekipe4");
onCreate(baza5);
}
}
osnovni_meni.java
package com.example.ultimate.basketball.stats;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Vibrator;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class osnovni_meni extends Activity {
protected SQLiteDatabase baza5;
protected Cursor cursor;
protected ListAdapter adapter;
protected ListView ekipe_list;
protected EditText searchtext;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_osnovni_meni);
baza5 = (new podatkovna_baza(this)).getWritableDatabase();
//searchtext = (EditText) findViewById (R.id.searchText);
//searchText = (EditText) findViewById (R.id.searchText);
//employeeList = (ListView) findViewById (R.id.list);
}
public void hello(View view) {
//cursor = baza2.rawQuery("SELECT ime_ekipe, kratko_ime, kraj FROM ekipe2" , null);
ekipe_list = (ListView) findViewById (R.id.lista);
cursor = baza5.query("ekipe4", null, null, null, null, null,
"_id" + " ASC");
adapter = new SimpleCursorAdapter(
this,
R.layout.ekipe_layout,
cursor,
new String[] {"_id","kratko_ime","kraj"},
new int[] {R.id.ime_ekipe,R.id.kratko_ime,R.id.kraj});
ekipe_list.setAdapter(adapter);
String sadas=adapter.toStr
}
public void delete_byID(int id) {
baza5.delete("ekipe4", "_id"+"="+id, null);
}
public void delete_by_ime_ekipe(String ime) {
baza5.delete("ekipe4", "kraj"+"="+ime, null);
}
public int deleteAll() {
return baza5.delete("ekipe4", null, null);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_osnovni_meni, menu);
return true;
}
public void onBackPressed() {
// TODO Auto-generated method stub
//super.onBackPressed();
finish();
}
public void vibriraj()
{
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(30);
}
public void vpisi(View view)
{
ContentValues values1 = new ContentValues();
//values1.put("_id", "1");
values1.put("ime_ekipe", "Chicago Bulls");
values1.put("kratko_ime", "CHI");
values1.put("kraj", "Chicago");
baza5.insert("ekipe4", "kratko_ime", values1);
vibriraj();
}
public void vpisi_ekipo(View view)
{
vibriraj();
EditText novo_ime_ekipe = (EditText) findViewById (R.id.novo_ime_ekipe);
EditText novo_kratko_ime_ekipe = (EditText) findViewById (R.id.novo_kratko_ime_ekipe);
EditText novo_kraj_ekipe = (EditText) findViewById (R.id.novo_kraj_ekipe);
EditText novo_slika_ekipe = (EditText) findViewById (R.id.novo_slika_ekipe);
ContentValues values1 = new ContentValues();
values1.put("ime_ekipe", (novo_ime_ekipe.getText()).toString());
values1.put("kratko_ime", (novo_kratko_ime_ekipe.getText()).toString());
values1.put("kraj", (novo_kraj_ekipe.getText()).toString());
values1.put("slika", (novo_slika_ekipe.getText()).toString());
baza5.insert("ekipe4", "kratko_ime", values1);
vibriraj();
setContentView(R.layout.edit_teams);
}
}
Now I want to for example delete a row I select (get ID from list and corresponding ID from database) or edit a row. How do I do this? It's pretty easy to delete or edit a SQLite entry if you know the id from a database, but I do not.
Sorry for my English, as you can see, it's not my first language.
ekipe_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
// your code here
}
});
Here in "position" you get the id of the item you've clicked.
So you need only to convert the id in ListView to the id in database.
Otherwise you will need to create custom adapter instead of SimpleCursorAdapter, and override the getView() method.
in the select query you have mentioned "SELECT * FROM ANSWER WHERE ID="
But you have to mention as " "SELECT * FROM answer WHERE ID"
Because table name is answer not ANSWER
I am making an app for cooking. I made three SQL databases and I populate a list with a tabview.
This is the database
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class Cook_tab_mains_data extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "mains";
public Cook_tab_mains_data(Context context) {
super(context, DATABASE_NAME, null, 2);
}
#Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE IF NOT EXISTS mains (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, " +
"disc TEXT, " +
"photo TEXT, " +
"prep TEXT, " +
"thumb TEXT, " +
"ingre TEXT, " +
"howto TEXT, " +
"info TEXT, " +
"mainId INTEGER)";
db.execSQL(sql);
ContentValues values = new ContentValues();
values.put("name", "Name 3");
values.put("disc", "here is the description");
values.put("photo", "stub.png");
values.put("ingre", "the ingredients of the mains");
values.put("howto", "how to make this thing");
values.put("info", "basically its this much calorie and such and such");
db.insert("mains", "name", values);
values.put("name", "Name 4");
values.put("disc", "here is the description");
values.put("photo", "stub.png");
values.put("thumb", "ic_launcher.png");
values.put("ingre", "the ingredients of the mains");
values.put("howto", "how to make this thing");
values.put("info", "basically its this much calorie and such and such");
db.insert("mains", "name", values);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS mains");
onCreate(db);
}}
As you can see my database is static.
Now I have a list activity that lists the items and another that details them:
import java.io.IOException;
import java.io.InputStream;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class Cook_tab_mains extends ListActivity {
protected EditText searchText;
protected SQLiteDatabase db;
protected Cursor cursor;
protected ListAdapter adapter;
class CustomSimpleCursor extends SimpleCursorAdapter {
public CustomSimpleCursor(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
ImageView thumb = (ImageView) view.findViewById(R.id.thumb);
try {
InputStream bitmap = getAssets()
.open(cursor.getString(cursor
.getColumnIndexOrThrow("thumb")));
Bitmap bit = BitmapFactory.decodeStream(bitmap);
thumb.setImageBitmap(bit);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cook_tab_general);
db = (new Cook_tab_mains_data(this)).getWritableDatabase();
searchText = (EditText) findViewById (R.id.searchText);
EditText searchTo = (EditText)findViewById(R.id.searchText);
searchTo.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// autoclick
}
});
// || Query SQLite
cursor = db.rawQuery("SELECT _id, name, disc, thumb, prep FROM mains WHERE name LIKE ?",
new String[]{"%" + searchText.getText().toString() + "%"});
adapter = new CustomSimpleCursor(
this,
R.layout.cook_tab_generalist,
cursor,
new String[] {"name", "disc", "prep"},
new int[] {R.id.name, R.id.disc, R.id.prep});
setListAdapter(adapter);}
public void search(View view) {
// ||Query SQLite
cursor = db.rawQuery("SELECT _id, name, disc, thumb, prep FROM mains WHERE name LIKE ?",
new String[]{"%" + searchText.getText().toString() + "%"});
adapter = new CustomSimpleCursor(
this,
R.layout.cook_tab_generalist,
cursor,
new String[] {"name", "disc", "prep"},
new int[] {R.id.name, R.id.disc, R.id.prep});
setListAdapter(adapter);}
public void onListItemClick(ListView parent, View view, int position, long id) {
Intent intent = new Intent(this, Cook_tab_mains_details.class);
Cursor cursor = (Cursor) adapter.getItem(position);
intent.putExtra("MAINS_ID", cursor.getInt(cursor.getColumnIndex("_id")));
startActivity(intent);
}
}
and then when an item is selected it shows details in this activity:
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
public class Cook_tab_mains_details extends Activity {
protected TextView Name;
protected ImageView Photo;
protected TextView Ingredients;
protected TextView HowTo;
protected TextView Information;
protected int mainId;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cook_tab_generaldetails);
mainId = getIntent().getIntExtra("MAINS_ID", 0);
SQLiteDatabase db = (new Cook_tab_mains_data(this)).getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT emp._id, emp.name, emp.photo, emp.ingre, emp.howto, emp.info, emp.mainId, mgr.name mainsname, mgr.disc mainsdiscname FROM mains emp LEFT OUTER JOIN mains mgr ON emp.mainId = mgr._id WHERE emp._id = ?",
new String[]{""+mainId});
if (cursor.getCount() == 1)
{
cursor.moveToFirst();
Name = (TextView) findViewById(R.id.FoodName);
Name.setText(cursor.getString(cursor.getColumnIndex("name")));
Photo = (ImageView) findViewById(R.id.Photo);
try {
InputStream bitmap=getAssets().open(cursor.getString(cursor.getColumnIndexOrThrow("photo")));
Bitmap bit=BitmapFactory.decodeStream(bitmap);
Photo.setImageBitmap(bit);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Ingredients = (TextView) findViewById(R.id.Ingre);
Ingredients.setText(cursor.getString(cursor.getColumnIndex("ingre")));
HowTo = (TextView) findViewById(R.id.HowtoDo);
HowTo.setText(cursor.getString(cursor.getColumnIndex("howto")));
Information = (TextView) findViewById(R.id.Information);
Information.setText(cursor.getString(cursor.getColumnIndex("info")));
} }}
The problem: I can't seem to close() the database. I searched everywhere. I can't find an answer.
Every time I try this command:
public void close()
{
Cook_tab_mains_data.close();
}
it gives me this error and won't compile: Cannot make a static reference to the non-static method close() from the type SQLiteOpenHelper
So now what?
How do I close my database?
At the very end of your onCreate method in activity Cook_tab_mains_details, add cursor.close(); and db.close() to close the cursor and database respectively.
More preferably, you should load the data in onStart method and close the cursor+database in onStop method of your activity. (but thats just a suggestion)
In Android you don't need to close the db explicitly.It is auto-magically closed by android. In short, don't worry about closing db.
the error is you are trying to close the object you created using ClassName.close() which isnt a static method. You can call db.close() where db is the object whenever you need to. Cursors should managed by you though.
You have to call
cursor.close();
when you dont need them anymore.
In Cook_tab_mains add:
#Override
public void onDestroy() {
db.close()
}