Android Application did not close cursor or database - android

Im running into an issue inserting items into my database. It really odd that the program will run through 4 rows and insert them fine, but on the 5th row it crashes and I got three reports of Application did not close cursor or database. In my code I am closing and reopening both the cursor and the database so I am really confused on how this is happening. Here is the code.
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case REQUEST_CODE_NEW:
if (resultCode == -1) {
Integer chapterId = data.getIntExtra("chapterId", -1);
Toast toast = Toast.makeText(this, "Selected Chapter: " + chapterId.toString(), Toast.LENGTH_LONG);
if (chapterId != -1) {
DbHelper db = new DbHelper(this);
for (int i = 0; i < questions.getTitle().size(); i++) {
db.insertQuestion(chapterId.toString(), questions.getTitle().get(i), questions.getAnswer().get(i), questions.getAr().get(i));
}
}
toast.show();
}
break;
}
}
Thats calling the database to be created through a dbhelper class. Here is the database helper
public void insertQuestion(String cat_id, String title, String answer, String article) {
db.execSQL("INSERT INTO " + QUESTION_TABLE_NAME + " (title,answer,article,picture) VALUES ('" + title + "','" + answer + "','" + article + "','none')");
String id = getQuestionId(title);
db.execSQL("INSERT INTO " + REL_TABLE_NAME + " (question_id, cat_id) VALUES (" + id + "," + cat_id + ")");
}
public String getQuestionId(String title) {
String id;
cursor = this.db.rawQuery("SELECT question_id FROM " + QUESTION_TABLE_NAME + " WHERE title = '" + title + "' LIMIT 1", null);
cursor.moveToFirst();
id = cursor.getString(0);
cursor.close();
db.close();
return id;
}
I put the cursor at the class level so I can try to manage it better, but still to no avail. Its still crashing after 4 queries.

Try this "fix":
DbHelper db = new DbHelper(this);
try{
for (int i = 0; i < questions.getTitle().size(); i++) {
db.insertQuestion(chapterId.toString(), questions.getTitle().get(i), questions.getAnswer().get(i), questions.getAr().get(i));
}
}catch(Exception e1){
android.util.Log.v("DbHelper Error","Crash: "+e1.getMessage(), e1);
}finally{
db.close();
}

Related

How can I repeat a ListView item a certain number of times using Android and SQLite data and changing one column each iteration?

I am trying to repeat certain data from a table in a ListView with one row changing each iteration of the item. I want to have a user input an int of the times to repeat and press a button to update the list.
I am working with dates as the updating item. So if a user inputs '3', I want 3 rows added to the list, and inserted into the table, adding 1 month to the date for the 3 months.
Main Activity
planAheadButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (planAheadMonths.getText().toString().trim().isEmpty()) {
Toast.makeText(getBaseContext(), "Add months to plan by", Toast.LENGTH_SHORT).show();
} else {
int plan = Integer.parseInt(planAheadMonths.getText().toString());
mDBHelper.updateCheckingPlanner(plan, mChecking.getCheckingId());
planAheadMonths.setText("");
mDBHelper.getTransRepeater(plan, mChecking.getCheckingId());
}
}
});
DBHelper
public void getTransactionRepeater(int repeat, int id) {
SQLiteDatabase db = this.getWritableDatabase();
String whereclause = TRANSACTION_DATE + " BETWEEN " + getCurrentMonth() + " AND " + getFutureMonth() + " AND " +
TRANSACTION_CHECKING_ID + " = " + id + " AND " + TRANSACTION_REPEAT + " != 'NONE' ";
String[] whereargs = new String[1];
Cursor res = db.query(TABLE_TRANSACTIONS, null, whereclause, null, null, null, TRANSACTION_DATE + " ASC, " + TRANSACTION_ID);
db.beginTransaction();
while (res.moveToNext()) {
if (res.getString(res.getColumnIndex(TRANSACTION_REPEAT)).equals("MONTH")) {
for (int i = 0; i < repeat; i++) {
+ i);
ContentValues cv = new ContentValues();
cv.put(TRANSACTION_NAME, res.getString(res.getColumnIndex(TRANSACTION_NAME)));
cv.put(TRANSACTION_TYPE, res.getString(res.getColumnIndex(TRANSACTION_TYPE)));
cv.put(TRANSACTION_DATE, sdf.format(cFuture.getTime()) + res.getString(res.getColumnIndex(TRANSACTION_NAME)) + i);
cv.put(TRANSACTION_AMOUNT, res.getInt(res.getColumnIndex(TRANSACTION_AMOUNT)));
cv.put(TRANSACTION_NOTES, res.getString(res.getColumnIndex(TRANSACTION_NOTES)));
cv.put(TRANSACTION_REPEAT, res.getString(res.getColumnIndex(TRANSACTION_REPEAT)));
cv.put(TRANSACTION_CHECKING_ID, res.getInt(res.getColumnIndex(TRANSACTION_CHECKING_ID)));
cv.put(TRANSACTION_NEW_BALANCE, res.getInt(res.getColumnIndex(TRANSACTION_NEW_BALANCE)));
cv.put(TRANSACTION_CREDIT_ID, res.getString(res.getColumnIndex(TRANSACTION_CREDIT_ID)));
whereargs[0] = res.getString(res.getColumnIndex(TRANSACTION_DATE));
db.insert(TABLE_TRANSACTIONS, null, cv);
}
}
}
res.close();
db.setTransactionSuccessful();
db.endTransaction();
}

Why does my app crash if I don't set in the SQL table not null statement?

I have this code:
{
String SQL_CREATE_BOOKS_TABLE = "CREATE TABLE " + BooksContract.BooksEntry.TABLE_NAME + " ("
+ BooksContract.BooksEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ BooksContract.BooksEntry.COLUMN_BOOKS_PRODUCT + " TEXT NOT NULL, "
+ BooksContract.BooksEntry.COLUMN_BOOKS_PRICE + " DECIMAL NOT NULL DEFAULT 0, "
+ BooksContract.BooksEntry.COLUMN_BOOKS_QUANTITY + " INTEGER NOT NULL, "
+ BooksContract.BooksEntry.COLUMN_BOOKS_SUPPLIER + " TEXT, "
+ BooksContract.BooksEntry.COLUMN_BOOKS_PHONE + " INTEGER );";
db.execSQL(SQL_CREATE_BOOKS_TABLE);
}
Even though I didn't set the supplier to be not null, if I don't type it in my editText when I click the save button my app crashes. Also even though quantity is set to default 0, if I don't type any quantity it still crashes. why?
EditorActivity:
private void insertBooks() {
String productString = productName.getText().toString().trim();
String priceString = price.getText().toString().trim();
int price = Integer.parseInt(priceString);
String quantityString = quantity.getText().toString().trim();
int quantity = Integer.parseInt(quantityString);
String supplierString = supplier.getText().toString().trim();
String phoneString = supplierPhone.getText().toString().trim();
int phone = Integer.parseInt(phoneString);
BooksDbHelper dbHelper = new BooksDbHelper(this);
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(BooksContract.BooksEntry.COLUMN_BOOKS_PRODUCT, productString);
values.put(BooksContract.BooksEntry.COLUMN_BOOKS_PRICE, priceString);
values.put(BooksContract.BooksEntry.COLUMN_BOOKS_QUANTITY, quantityString);
values.put(BooksContract.BooksEntry.COLUMN_BOOKS_SUPPLIER, supplierString);
values.put(BooksContract.BooksEntry.COLUMN_BOOKS_PHONE, phoneString);
long newRowId = db.insert(BooksContract.BooksEntry.TABLE_NAME, null, values);
if (newRowId == -1) {
// If the row ID is -1, then there was an error with insertion.
Toast.makeText(this, "Error with saving book", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Book saved with row id: " + newRowId, Toast.LENGTH_SHORT).show();
}
}
CatalogActivity:
private void insertBooks() {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(BooksContract.BooksEntry.COLUMN_BOOKS_PRODUCT, "Walks with men");
values.put(BooksContract.BooksEntry.COLUMN_BOOKS_PRICE, 10.00);
values.put(BooksContract.BooksEntry.COLUMN_BOOKS_QUANTITY, 2);
values.put(BooksContract.BooksEntry.COLUMN_BOOKS_SUPPLIER, "Amazon");
values.put(BooksContract.BooksEntry.COLUMN_BOOKS_PHONE, 727213658);
long newRowId = db.insert(BooksContract.BooksEntry.TABLE_NAME, null, values);
}
Use this code in your insertBooks() method to avoid NumberFormatException:
String productString = productName.getText().toString().trim();
String priceString = price.getText().toString().trim();
double price = 0.0;
try {
price = Double.parseDouble(priceString);
} catch (NumberFormatException e) {
e.printStackTrace();
}
String quantityString = quantity.getText().toString().trim();
int quantity = 0;
try {
quantity = Integer.parseInt(quantityString);
} catch (NumberFormatException e) {
e.printStackTrace();
}
String supplierString = supplier.getText().toString().trim();
String phoneString = supplierPhone.getText().toString().trim();
Why is phone INTEGER?
Note:
The create table code you posted is probably part of the onCreate() method in your class that extends SQLiteOpenHelper.
The onCreate() method was executed the 1st time you ran the app and created the table. Since then you may have altered the columns either by type or name, or even inserted or deleted columns, but all these changes were made only in your code and not in the table. The onCreate() method has never again been triggered.
So if any of the above applies to you:
Uninstall the app from the emulator/device so that the database is deleted and run again your app to recreate it as it should be.

SQL in android dosent work

I want to update a row in a SQL table in a column (`click'). I can see the row in debug but it isn't recognized.
If click==0 so change to click==1.
Does someone know what is my mistake?
My code is:
public void UpdateClicked2(String name, int table) {
ContentValues values = new ContentValues();
String selectQuery = "SELECT * FROM " + MySQLiteGUESTS.TABLE_NAME
+ " WHERE " + MySQLiteGUESTS.COLUMN_TABLE + "=" + table;
Cursor cursor = database.rawQuery(selectQuery, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
GuestInfo comment = cursorToComment(cursor);
if (comment.getName().toString() != name)
cursor.moveToNext();
else {
if (comment.getClick() == 1) {
values.put(MySQLiteGUESTS.COLUMN_CLICK, 0);
} else
values.put(MySQLiteGUESTS.COLUMN_CLICK, 1);
}
}
String newString = MySQLiteGUESTS.COLUMN_NAME + " = " + name;
database.update(MySQLiteHelper.TABLE_NAME, values, newString, null);
}
if (comment.getName().toString() != name)
Instead of this
Use this:
if (comment.getName().toString().equals(name))
{
}

How to delete a row from sqlite table in recycler view items in Android?

I am trying to delete a row in sqlite database from recyclerview adapter. Based on the position of the adapter, I am deleting my row in sqlite like this :
helper = new DBHelper(v.getContext());
database = helper.getWritableDatabase();
//statement = database.compileStatement("update result set ANS =? where SNO ='" + pos + "'");
// statement = database.compileStatement("delete result where SNO ='" + pos + "'");
//statement.bindString(1, ANS);
// statement.executeInsert();
database.delete("result",
"SNO = ? ",
new String[]{Integer.toString(pos)});
Log.d("pos", "" + pos);
// helper.Delete(pos);
database.close();
but it is not deleting in my table, and I am not getting any error. What am I doing wrong?
db = this.getWritableDatabase();
int l;
l = db.delete("result", SNO = ? " , new String[]{pos+1});
if (l > 0) {
Toast.makeText(context, "Removed "+(pos+1), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
}
db.close();
Here you have pass "pos" so you have not passed right SNO(pos).
Please check SNO is passes on delete query
Try this method ,
public int deleteItem(String id) {
open();
int b = 0;
try {
b = db.delete(DATABASE_TABLE_POST_ITEMS, TAG_PLUS + " = '" + id + "'", null);
} catch (Exception e) {
e.printStackTrace();
}
close();
return b;
}
call this by using this sentence,
holder.img_plus.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
dbhelper.deleteItem((chatMessageList.get((int) v.getTag()).getListid()));
chatMessageList.remove(position);
notifyDataSetChanged();
}
});

Cursor to String

I'm new to android, and I don't know why I am getting CursorIndexOutOfBoundsException: Index 0 requested with a size of 0. I'm trying to display it on another class using listview. Here are my codes:
public void onItemClick(AdapterView<?> arg0, View view, int position,
long id) {
// TODO Auto-generated method stub
position = position + 1;
Cursor a = MainActivity.sqldb
.rawQuery("Select name from " + MainActivity.tblpb
+ " where _pid = " + position + ";", null);
String aa = a.getString(a.getColumnIndex("name"));
Cursor b = MainActivity.sqldb
.rawQuery("Select phone from " + MainActivity.tblpb
+ " where _pid = " + position + ";", null);
String bb = b.getString(b.getColumnIndex("phone"));
Intent next = new Intent (this, ThirdActivity.class);
startActivity(next);
}
I know that there's something really wrong here. And I wonder what it is.
Create Table:
sqldb = this.openOrCreateDatabase(dbpb, MODE_PRIVATE, null);
sqldb.execSQL("CREATE TABLE IF NOT EXISTS "
+ tblpb
+ " (_pid INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, phone INTEGER);");
Insert Table:
sqldb.execSQL("Insert into " + tblpb
+ " (name, phone) Values ('" + x + "' , '"
+ y + "' );");
Try doing this:
public void onItemClick(AdapterView<?> arg0, View view, int position,
long id) {
// TODO Auto-generated method stub
String aa = null;
String bb = null;
// do not alter the position, DB starts the same position as ItemClick for
// adapter view
// position = position + 1;
Cursor a = MainActivity.sqldb
.rawQuery("Select name from " + MainActivity.tblpb
+ " where _pid = " + position + ";", null);
if(a != null){
// Force cursor to position 0
if(a.moveToFirst()){
// make sure the column actually exists
aa = a.getString(a.getColumnIndexOrThrow("name"));
Log.d("Cursor A - Name", "name column val: "+ aa);
}else{
Log.d("Cursor A", "cursor A failed to move to first");
}
}else{
Log.d("Cursor A null", "cannot access cursor A");
}
Cursor b = MainActivity.sqldb.rawQuery("Select phone from " + MainActivity.tblpb + " where _pid = " + position + ";", null);
if(b != null){
// Force cursor to position 0
if(b.moveToFirst()){
// make sure the column actually exists
bb = b.getString(b.getColumnIndexOrThrow("phone"));
Log.d("Cursor B - Phone", "phone column val: "+ bb);
}else{
Log.d("Cursor B", "cursor B failed to move to first");
}
}else{
Log.d("Cursor B null", "cannot access cursor B");
}
Intent next = new Intent (this, ThirdActivity.class);
next.putExtra("NAME", aa);
next.putExtra("PHONE", bb);
startActivity(next);
}
Then in your second Activity do:
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.content_file);
Bundle extras = getIntent().getExtras();
if(extras != null){
String aa = extras.getString("NAME");
String bb = extras.getString("PHONE");
// Since you cannot tell if these are null check them
if(aa != null){
// ... Use on your TextView
}
// Since you cannot tell if these are null check them
if(bb != null){
// ... Use on your TextView
}
}
}
The error indicates that you are trying to access the first element (index 0) of an empty list (size 0) meaning your queries are returning no results. Make sure your queries are correct.
EDIT:
It's also a good idea to call cursor.moveToFirst() and check its result before doing any operations on the data from a query.
http://developer.android.com/reference/android/database/Cursor.html#moveToFirst%28%29

Categories

Resources