I'm developing a program using database.
I'm stuck on inserting the data typed from EditText, keep on getting NullPointerException.
Here is my code:
AddBusDataActivity.java
public class AddBusDataActivity extends ActionBarActivity {
SQLiteDatabase mBusDatabse;
BusDatabaseHelper mBusDatabaseHelper;
EditText mNumber;
EditText mDestination;
EditText mArrivalTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
mBusDatabaseHelper = new BusDatabaseHelper(AddBusDataActivity.this, Constants.DATABASE_NAME, null, Constants.VERSION);
mNumber = (EditText)findViewById(R.id.number_text);
mDestination = (EditText)findViewById(R.id.destination_text);
mArrivalTime = (EditText)findViewById(R.id.arrival_time);
}
public void addBusActivityButton(View view) {
mBusDatabse = mBusDatabaseHelper.getWritableDatabase();
BusData bus = new BusData(mNumber.getText().toString(), mDestination.getText().toString(), Integer.valueOf(mArrivalTime.getText().toString()));
mBusDatabaseHelper.addBusData(bus); // error here
mBusDatabaseHelper.close();
Toast.makeText(AddBusDataActivity.this, "Bus data successfully added", Toast.LENGTH_SHORT).show();
this.finish();
}
}
BusDatabaseHelper.java
public class BusDatabaseHelper extends SQLiteOpenHelper {
SQLiteDatabase mBusDatabase;
public BusDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table "+ Constants.TABLE_NAME + " (" + Constants.KEY_ID + " integer primary key autoincrement, " +
Constants.NUMBER + " text not null, " + Constants.DESTINATION + " text not null, " + Constants.ARRIVAL_TIME + " integer not null);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table " + Constants.TABLE_NAME + ";");
onCreate(db);
}
public void addBusData(BusData busData) {
ContentValues busValues = new ContentValues();
busValues.put(Constants.NUMBER, busData.getmNumber());
busValues.put(Constants.DESTINATION, busData.getmDestination());
busValues.put(Constants.ARRIVAL_TIME, busData.getmArrivalTime());
mBusDatabase.insert(Constants.TABLE_NAME, null, busValues); // error here
}
}
Error message
Caused by: java.lang.NullPointerException
at com.id11201478.exercise6.BusDatabaseHelper.addBusData(BusDatabaseHelper.java:36)
at com.id11201478.exercise6.AddBusDataActivity.addBusActivityButton(AddBusDataActivity.java:36)
I have separate Constants.java class for storing thoses values.
Thanks in advance!
It looks like mBusDatabase in BusDatabaseHelper is never initialised and therefore is null. Dereferencing it on line 36 causes your NPE.
You don't actually need it if you modify addBusData to grab it each time:
public void addBusData(BusData busData) {
ContentValues busValues = new ContentValues();
busValues.put(Constants.NUMBER, busData.getmNumber());
busValues.put(Constants.DESTINATION, busData.getmDestination());
busValues.put(Constants.ARRIVAL_TIME, busData.getmArrivalTime());
getWritableDatabase().insert(Constants.TABLE_NAME, null, busValues);
}
The variable
BusDatabaseHelper.mBusDatabase
is null. You need to initialize it!
Otherwise how does the system knows what mBusDatabase is
try to add this before insert
mBusDatabase= this.getWritableDatabase();
Related
I am a student and started working on android studio recently. I don't know about it much. I am working on an application where I save the item name and its amount in the database and display toast message if data we entered is saved or not. problem is whenever I click on the save button my application crashes.
following is my DatabaseHelper class:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "Items.db";
public static final String TABLE_NAME = "item_table";
public static final String COL_1 = "ID";
public static final String COL_2 = "ITEM";
public static final String COL_3 = "AMOUNT";
public DatabaseHelper(#Nullable 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," + "ITEM TEXT, AMOUNT TEXT)";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP IF TABLE EXISTS" + TABLE_NAME);
onCreate(db);
}
public boolean addData(String item, String amount){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_2,item);
contentValues.put(COL_3,item);
long result = db.insert(TABLE_NAME,null, contentValues);
if(result == -1){
return false;
}else {
return true;
}
}
}
following is my MainActivity class:
public class MainActivity extends AppCompatActivity {
DatabaseHelper myDb;
EditText editItem, editAmount;
Button buttonSave;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myDb = new DatabaseHelper(this);
editItem = (EditText)findViewById(R.id.item_field);
editAmount = (EditText)findViewById(R.id.amount_field);
buttonSave = (Button)findViewById(R.id.button_save);
AddData();
}
public void AddData(){
buttonSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String item = editItem.getText().toString();
String amount = editAmount.getText().toString();
boolean insertData = myDb.addData(item, amount);
if(insertData == true){
Toast.makeText(MainActivity.this,"Amount is saved with Item detail", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(MainActivity.this, "Error occurred : Detailed are not saved", Toast.LENGTH_LONG).show();
}
}
});
}
}
I will appreciate your help.
Thank you
It might be crashing because it's not creating the table:
String createTable = "CREATE TABLE" + TABLE_NAME + "(ID INTEGER PRIMARY KEY AUTOINCREMENT," + "ITEM TEXT, AMOUNT TEXT)";
A space is missing between table and its name:
String createTable = "CREATE TABLE " + TABLE_NAME + "(ID INTEGER PRIMARY KEY AUTOINCREMENT, ITEM TEXT, AMOUNT TEXT)";
You should also close the database after you get the data in db.insert but this only creates a warning:
long result = db.insert(TABLE_NAME,null, contentValues);
db.close();
#After insert a row Database is creating again .how can i solve this problem and i can check database is android device monitor
#After insert a row Database is creating again .how can i solve this problem and i can check database is android device monitor
#After insert a row Database is creating again .how can i solve this problem and i can check database is android device monitor
public class DatabaseOperations extends SQLiteOpenHelper {
public static final int Database_version = 2;
public static final String Tag = DatabaseOperations.class.getSimpleName();
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + TableData.TableInfo.TABLE_NAME + " (" +
TableData.TableInfo.USER_ID + " INTEGER PRIMARY KEY," +
TableData.TableInfo.USER_PASS +" TEXT "+ "," +
TableData.TableInfo.USER_EMAIL +" TEXT "+ ");";
public DatabaseOperations(Context context) {
super(context, TableData.TableInfo.DATABASE_NAME, null,Database_version);
Log.d("Tag", "Database created");
}
#Override
public void onCreate(SQLiteDatabase sdb) {
sdb.execSQL(SQL_CREATE_ENTRIES);
Log.d("Tag", "Table created");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void putInformation(DatabaseOperations drop, String name, String pass, String email) {
SQLiteDatabase SQ = drop.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(TableData.TableInfo.USER_ID, name);
cv.put(TableData.TableInfo.USER_PASS, pass);
cv.put(TableData.TableInfo.USER_EMAIL, email);
long k = SQ.insert(TableData.TableInfo.TABLE_NAME, null, cv);
Log.d("Tag", "inert a row");
}
public Cursor getInformation(DatabaseOperations dop) {
SQLiteDatabase SQ = dop.getReadableDatabase();
String[] coloumns = {TableData.TableInfo.USER_ID, TableData.TableInfo.USER_PASS, TableData.TableInfo.USER_EMAIL};
Cursor CR = SQ.query(TableData.TableInfo.TABLE_NAME, coloumns, null, null, null, null, null);
return CR;
}
}
RegisterActivity
public class RegisterActivity extends AppCompatActivity {
EditText USER_NAME, USER_PASS, CON_PASS, USER_EMAIL;
String user_name, user_pass, con_pass, user_email;
Button REG;
Context ctx = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
USER_NAME = (EditText) findViewById(R.id.reg_user);
USER_PASS = (EditText) findViewById(R.id.reg_pass);
CON_PASS = (EditText) findViewById(R.id.con_pass);
USER_EMAIL = (EditText) findViewById(R.id.reg_email);
REG = (Button) findViewById(R.id.user_reg);
REG.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
user_name = USER_NAME.getText().toString();
user_pass = USER_PASS.getText().toString();
con_pass = CON_PASS.getText().toString();
user_email = USER_EMAIL.getText().toString();
if (!(user_pass.equals(con_pass))) {
Toast.makeText(getBaseContext(), "Password are not matching", Toast.LENGTH_LONG).show();
USER_NAME.setText("");
USER_PASS.setText("");
CON_PASS.setText("");
USER_EMAIL.setText("");
} else {
DatabaseOperations DB = new DatabaseOperations(ctx);
DB.putInformation(DB, user_name, user_pass, user_email);
Toast.makeText(getBaseContext(), "Registration is suessful", Toast.LENGTH_LONG).show();
finish();
}
}
});
}
}
It is because you are creating table each time you insert a row. To solve this problem you need to change the create table query "CREATE TABLE 'TABLE_NAME' IF NOT EXISTS". The "IF NOT EXISTS" will restrict the system to create the database again if it is created once.
You are calling creating a new Table every time, you create an instance of DatabaseOperations - as your SQL statement 'CREATES'
Modify SQL_CREATE_ENTRIES to something like below
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE IF NOT EXISTS " + TableData.TableInfo.TABLE_NAME + " (" +
TableData.TableInfo.USER_ID + + " integer primary key autoincrement, "+
TableData.TableInfo.USER_PASS +" TEXT "+ "," +
TableData.TableInfo.USER_EMAIL +" TEXT "+ ");";
Edit
1) I've update query to include auto-increment your primary key
2) In your onUpgrade method add the line
db.execSQL("DROP TABLE IF EXISTS " + TableData.TableInfo.TABLE_NAME);
This will delete the table when you change the version of DB.
Next, update the version of by 1, to 3.
Re-run app, it will be rebuild the DB table.
There is a problem with insetion in database. I don't know what to do.
It writes error inserting.
public class MainActivity extends Activity implements OnClickListener {
BaseOpener bo;
private static final String ML = "ML";
Button read, write;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
read = (Button) findViewById(R.id.read);
read.setOnClickListener(this);
write = (Button) findViewById(R.id.write);
write.setOnClickListener(this);
bo = new BaseOpener(this);
Log.i("Ml", "good start");
}
#Override
public void onClick(View v) {
SQLiteDatabase db = bo.getWritableDatabase();
switch (v.getId()) {
case R.id.write:
{
ContentValues cv = new ContentValues();
Log.i("ML", "write");
cv.put("id", 1);
cv.put("name", "Petr");
cv.put("phone", "911");
cv.clear();
db.insert("table1", null, cv);
}
break;
case R.id.read:
{`enter code here`
Log.i("ML", "read");
Cursor c = db.query("table1",null,null,null,null,null,null);
if(c.moveToFirst()){
int idColIndex = c.getColumnIndex("id");
int nameColIndex = c.getColumnIndex("name");
int emailColIndex = c.getColumnIndex("phone");
Log.i("ML",
"ID = " + c.getInt(idColIndex) +
", name = " + c.getString(nameColIndex) +
", phone = " + c.getString(emailColIndex));
}
}
break;
}
db.close();
Log.i("ML", "the base is closed");
}
}
public class BaseOpener extends SQLiteOpenHelper {
public BaseOpener(Context context) {
super(context, "contacts", null, 1);
Log.i("ML", "the base is ready");
}`enter code here`
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table table1 (" + "id integer primary key,"
+ "name String," + "phone String" + ");");
Log.i("ML", "table1 is ready");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
clear()
Removes all values. Read more on ContentValues here
Your table lists id as primary key so you can't insert it twice. I would just comment out the cv.put("id",1) line and let sqlite handle it.
//cv.put("id", 1);
db.execSQL("create table table1 (" + "id integer primary key,"
+ "name String," + "phone String" + ");");
Log.i("ML", "table1 is ready");
Also from your next app on consider naming your id column _id. This will make the table more compatible with cursor adapters and such.
Look at these links they all use _id
cursorAdapter ContentProvider ListView
I am making this sample app that will insert, update, delete and retrieve data from database. now the problem I am facing is how to update the record. I know I have to pass Id but how.
MainActivity.java :
public class MainActivity extends Activity {
Button btnSubmit, btnUpdate, btnDelete;
EditText UserName, FirstName, LastName, txtPassword;
RunDatabase db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new RunDatabase(this);
UserName = (EditText) findViewById(R.id.User_Name);
FirstName = (EditText) findViewById(R.id.First_Name);
LastName = (EditText) findViewById(R.id.Last_Name);
txtPassword = (EditText) findViewById(R.id.Password);
btnSubmit = (Button) findViewById(R.id.btn_Submit);
btnSubmit.setOnClickListener (new View.OnClickListener() {
#Override
public void onClick(View v) {
addRow();
}
});
btnUpdate = (Button) findViewById(R.id.btn_Update);
btnUpdate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
updateRow();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void addRow()
{
try
{
db.addRow
(
UserName.getText().toString(),
FirstName.getText().toString(),
LastName.getText().toString(),
txtPassword.getText().toString()
);
// remove all user input from the Activity
emptyFormFields();
}
catch (Exception e)
{
Log.e("Add Error", e.toString());
e.printStackTrace();
}
}
private void updateRow()
{
try
{
db.updateRow
(
UserName.getText().toString(),
FirstName.getText().toString(),
LastName.getText().toString(),
txtPassword.getText().toString()
);
emptyFormFields();
}
catch (Exception e)
{
Log.e("Update Error", e.toString());
e.printStackTrace();
}
}
private void emptyFormFields()
{
User_Id.setText("");
FirstName.setText("");
LastName.setText("");
UserName.setText("");
txtPassword.setText("");
}
}
RunDatabase.java:
public class RunDatabase {
Context context;
private SQLiteDatabase db; // a reference to the database manager class.
private final String DB_NAME = "Records"; // the name of our database
private final int DB_VERSION = 1; // the version of the database
// the names for our database columns
private final String TABLE_NAME = "tblRecords";
private final String TABLE_ROW_ID = "id";
private final String TABLE_ROW_ONE = "UserName";
private final String TABLE_ROW_TWO = "FirstName";
private final String TABLE_ROW_THREE = "LastName";
private final String TABLE_ROW_FOUR = "Password";
// the beginnings our SQLiteOpenHelper class
public void onCreate(SQLiteDatabase db)
{
String newTableQueryString =
"create table " +
TABLE_NAME +
" (" +
TABLE_ROW_ID + " integer primary key autoincrement not null, " +
TABLE_ROW_ONE + " text, " +
TABLE_ROW_TWO + " text, " +
TABLE_ROW_THREE + " text, " +
TABLE_ROW_FOUR + " text" +
");";
System.out.println(newTableQueryString);
// execute the query string to the database.
db.execSQL(newTableQueryString);
}
public RunDatabase(Context context)
{
this.context = context;
// create or open the database
CustomSQLiteOpenHelper helper = new CustomSQLiteOpenHelper(context);
this.db = helper.getWritableDatabase();
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void addRow(String rowStringOne, String rowStringTwo, String rowStringThree, String rowStringFour)
{
// this is a key value pair holder used by android's SQLite functions
ContentValues values = new ContentValues();
values.put(TABLE_ROW_ONE, rowStringOne);
values.put(TABLE_ROW_TWO, rowStringTwo);
values.put(TABLE_ROW_THREE, rowStringThree);
values.put(TABLE_ROW_FOUR, rowStringFour);
try
{
db.insert(TABLE_NAME, null, values);
}
catch(Exception e)
{
Log.e("DB ERROR", e.toString());
e.printStackTrace(); // prints the stack trace to the log
}
}
public void updateRow(long rowID, String rowStringOne, String rowStringTwo, String rowStringThree, String rowStringFour)
{
ContentValues values = new ContentValues();
values.put(TABLE_ROW_ONE, rowStringOne);
values.put(TABLE_ROW_TWO, rowStringTwo);
values.put(TABLE_ROW_THREE, rowStringThree);
values.put(TABLE_ROW_FOUR, rowStringFour);
try {db.update(TABLE_NAME, values, TABLE_ROW_ID + "=" + rowID, null);}
catch (Exception e)
{
Log.e("DB Error", e.toString());
e.printStackTrace();
}
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// NOTHING TO DO HERE. THIS IS THE ORIGINAL DATABASE VERSION.
// OTHERWISE, YOU WOULD SPECIFIY HOW TO UPGRADE THE DATABASE.
}
}
}
1. In your create table String,
String newTableQueryString =
"create table " +
TABLE_NAME +
" (" +
TABLE_ROW_ID + " integer primary key autoincrement not null, " +
TABLE_ROW_ONE + " text, " +
TABLE_ROW_TWO + " text, " +
TABLE_ROW_THREE + " text, " +
TABLE_ROW_FOUR + " text" +
");";
The ROW_ID is an integer, so in your function updateRow(), the data type for parameter of rowID should be integer, which is passed in the "where" clause. So should change
-> public void updateRow(long rowID, String rowStringOne,...
2. To identify the row you have added, you need to have a primary key which you will be able to identify on the basis of the entry.
Auto increment integer is good for ensuring that the database will have a new row each time,
but the primary key you need should be something you will know to differentiate entries.
Can try a derived key which would be another column in your db, to insert the same with adding rows would be like:
String customPrimaryKey="UserName.getText().toString()+FirstName.getText().toString()+txtPassword.getText().toString()";
db.updateRow
(
UserName.getText().toString(),
FirstName.getText().toString(),
LastName.getText().toString(),
txtPassword.getText().toString(),
// add one more value for a particular entry-a primary key for You to identify that row
customPrimaryKey
);
So you have a way to identify which row to update then, and pass the same in the updateRow() parameters for the where clause
You could try like this-
db.update(TABLE_NAME, values, TABLE_ROW_ID + "=?", String[]{rowID});
I'm trying to insert a row in a sqlite database's table, but when I call the insertOrThrow() method (Class Sqlitedatabase) i get this exception:
"Application did not close the cursor or database object that was opened here"
I don't understand why:
here's the code for the main class:
........
ContentValues values = new ContentValues();
values.put("nome", info.getString("nome"));
values.put("ingredienti", info.getJSONObject("ingredienti").toString());
values.put("descrizione", info.getString("descrizione"));
values.put("persone", info.getString("persone"));
values.put("tempo", info.getString("tempo"));
values.put("facilita", info.getString("facilita"));
if(info.getString("url_foto")!="/images/ricettapredefinita.jpg")
values.put("foto", true);
else
values.put("foto", false);
values.put("categoria", info.getString("categoria"));
values.put("zona", info.getString("regione"));
values.put("ethnos", info.getString("etnica"));
values.put("voto", info.getString("voto"));
// Open database
DbAdapter mDbHelper = new DbAdapter(Main.this);
mDbHelper.open_w();
long ritorno=mDbHelper.createRecipe(values);
These are the main methods for DbAdapter Class:
private static final String DATABASE_CREATE =
"CREATE TABLE recipes (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT," +
"nome VARCHAR(255) NOT NULL," +
"ingredienti TEXT NOT NULL," +
"descrizione TEXT " +
"persone SMALLINT," +
"tempo TINYINT(3)," +
"facilita SMALLINT," +
"foto BOOL," +
"voto TINYINT(3)," +
"categoria VARCHAR(255)," +
"zona VARCHAR(255)," +
"ethnos VARCHAR(255));";
public long createRecipe(ContentValues info) {
return mDb.insertOrThrow(DATABASE_TABLE, null, info);
}
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS notes");
onCreate(db);
}
}
public DbAdapter open_w() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
Anyone has an idea for what the problem could be?
You should add mDbHelper.close() at end.
you have to add a mDbHelper.close(); when you are sure that I do not need more a mDbHelper.
I have solved same issue by doing this. I hope is working for u.