I was trying to add the data i receive from some specific messages to SQLite database..
But when i run my application i am getting error which says ... Fatal Exception : Main caused by Java Null Pointer exception at the InsertTitle Function in my DBAdapter.java
This is my DBAdapter Class
package com.lalsoft.janko;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter
{
public static final String KEY_ROWID = "_id";
public static final String KEY_GQTY = "gqty";
public static final String KEY_NQTY = "nqty";
public static final String KEY_DATE = "ddate";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "lalaqua";
private static final String DATABASE_TABLE = "nsales";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE =
"create table titles (_id integer primary key autoincrement, "
+ "gqty text not null, nqty text not null, "
+ "ddate text not null);";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
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 titles");
onCreate(db);
}
}
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
//---insert a title into the database---
public long insertTitle(String gqty, String nqty, String ddate)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_GQTY, gqty);
initialValues.put(KEY_NQTY, nqty);
initialValues.put(KEY_DATE, ddate);
return db.insert(DATABASE_TABLE, null, initialValues);
}
//---deletes a particular title---
public boolean deleteTitle(long rowId)
{
return db.delete(DATABASE_TABLE, KEY_ROWID +
"=" + rowId, null) > 0;
}
//---retrieves all the titles---
public Cursor getAllTitles()
{
return db.query(DATABASE_TABLE, new String[] {
KEY_ROWID,
KEY_GQTY,
KEY_NQTY,
KEY_DATE},
null,
null,
null,
null,
null);
}
//---retrieves a particular title---
public Cursor getTitle(long rowId) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {
KEY_ROWID,
KEY_GQTY,
KEY_NQTY,
KEY_DATE
},
KEY_ROWID + "=" + rowId,
null,
null,
null,
null,
null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
//---updates a title---
public boolean updateTitle(long rowId, String gqtr,
String nqty, String ddate)
{
ContentValues args = new ContentValues();
args.put(KEY_GQTY, gqtr);
args.put(KEY_NQTY, nqty);
args.put(KEY_DATE, ddate);
return db.update(DATABASE_TABLE, args,
KEY_ROWID + "=" + rowId, null) > 0;
}
}
This is the class which extends from BroadcastReceiver, which is calling the inserttitle function..
package com.lalsoft.janko;
import java.util.Calendar;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.gsm.SmsManager;
import android.telephony.gsm.SmsMessage;
import android.util.Log;
public class SMSReceiver extends BroadcastReceiver
{
public String SendMsgBody;
private static final String LOG_TAG = "JankoSMS";
public DBAdapter db;
public Integer isDone=0;
public Double GrossQty,NetQty;
#Override
public void onReceive(Context context, Intent intent)
{
db = new DBAdapter(context);
//---get the SMS message passed in---
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = "";
String PhNo;
String MsgBody;
if (bundle != null)
{
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
str += "SMS from " + msgs[i].getOriginatingAddress();
PhNo=msgs[i].getOriginatingAddress();
str += " :";
str += msgs[i].getMessageBody().toString();
MsgBody=msgs[i].getMessageBody().toString();
str += "\n";
// EncodeSMS(MsgBody);
String GQtyS,NQtyS,sDate;
GQtyS="Ok";
NQtyS="Done";
sDate=getDate();
Log.i(LOG_TAG, "Date" +" "+ sDate +" "+ GQtyS +" "+ NQtyS);
long id;
id = db.insertTitle(GQtyS ,NQtyS,sDate);
}
}
}
public static String getDate()
{
Calendar c = Calendar.getInstance();
String sDate = c.get(Calendar.DAY_OF_MONTH) + "-"
+ c.get(Calendar.MONTH)
+ "-" + c.get(Calendar.YEAR);
//+ " at " + c.get(Calendar.HOUR_OF_DAY)
//+ ":" + c.get(Calendar.MINUTE);
return sDate;
}
}
Also i have checked the database is not getting created..
So what should be the possible cause of this issue and how can i solve this?? Please help me out of this trouble.
The problem is in line db.insert() of insertTitle() method. You have to assign the value of db before using so use open the database before using by calling open() as first statement inside insertTitle() method
Your code will be something like the below
public long insertTitle(String gqty, String nqty, String ddate)
{
open();
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_GQTY, gqty);
initialValues.put(KEY_NQTY, nqty);
initialValues.put(KEY_DATE, ddate);
return db.insert(DATABASE_TABLE, null, initialValues);
}
I guess you haven't called db.open(); that is this method
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
Follow the above 2 suggestions given by sunil & lalit
include the below one also i.e place db.execSQL(DATABASE_CREATE); in try catch block
public void onCreate(SQLiteDatabase db) {
System.out.println("table created....");
try{
db.execSQL(DATABASE_CREATE);
}catch (Exception e) {
// TODO: handle exception
}
}
Related
i try to save current date values when button get clicked....i use DBAdapter for save parameters to sqlite and it was fine when used for 2 fields like example of DBAdapter but when i edited DBAdapter for 6 fields this doesnt work.where is my problem?
DBAdapter.java
import java.io.StringReader;
import java.util.ArrayList;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
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;
public class DBAdapter {
private static final String TAG = "DBAdapter"; //used for logging database version changes
// Field Names:
public static final String KEY_ROWID = "_id";
public static final String KEY_YEAR = "year";
public static final String KEY_MONTH = "month";
public static final String KEY_DAY = "day";
public static final String KEY_HOUR = "hour";
public static final String KEY_MINUTE = "minute";
public static final String KEY_SECOND = "second";
public static final String[] ALL_KEYS = new String[] { KEY_ROWID, KEY_YEAR, KEY_MONTH, KEY_DAY, KEY_HOUR, KEY_MINUTE, KEY_SECOND};
// Column Numbers for each Field Name:
public static final int COL_ROWID = 0;
public static final int COL_TASK = 1;
public static final int COL_DATE = 2;
// DataBase info:
public static final String DATABASE_NAME = "dbToDo12";
public static final String DATABASE_TABLE = "mainToDo12";
public static final int DATABASE_VERSION = 2; // The version number must be incremented each time a change to DB structure occurs.
//SQL statement to create database
private static final String DATABASE_CREATE_SQL =
"CREATE TABLE " + DATABASE_TABLE
+ " (" + KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ KEY_YEAR + " TEXT NOT NULL, "
+ KEY_MONTH + " TEXT"
+ KEY_DAY + " TEXT"
+ KEY_HOUR + " TEXT"
+ KEY_MINUTE + " TEXT"
+ KEY_SECOND + " TEXT"
+ ");";
private final Context context;
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx) {
this.context = ctx;
myDBHelper = new DatabaseHelper(context);
}
// Open the database connection.
public DBAdapter open() {
db = myDBHelper.getWritableDatabase();
return this;
}
// Close the database connection.
public void close() {
myDBHelper.close();
}
// Add a new set of values to be inserted into the database.
public long insertRow(String year, String month,String day, String hour,String minute,String second) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_YEAR, year);
initialValues.put(KEY_MONTH, month);
initialValues.put(KEY_DAY, day);
initialValues.put(KEY_HOUR, hour);
initialValues.put(KEY_MINUTE, minute);
initialValues.put(KEY_SECOND, second);
// Insert the data into the database.
return db.insert(DATABASE_TABLE, null, initialValues);
}
// Delete a row from the database, by rowId (primary key)
public boolean deleteRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
return db.delete(DATABASE_TABLE, where, null) != 0;
}
public void deleteAll() {
Cursor c = getAllRows();
long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
if (c.moveToFirst()) {
do {
deleteRow(c.getLong((int) rowId));
} while (c.moveToNext());
}
c.close();
}
// Return all data in the database.
public Cursor getAllRows() {
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS, where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
// Get a specific row (by rowId)
public Cursor getRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
// Change an existing row to be equal to new data.
public boolean updateRow(long rowId, String year, String month,long day, String hour, String minute,long second) {
String where = KEY_ROWID + "=" + rowId;
ContentValues newValues = new ContentValues();
newValues.put(KEY_YEAR, year);
newValues.put(KEY_MONTH, month);
newValues.put(KEY_DAY, day);
newValues.put(KEY_HOUR, hour);
newValues.put(KEY_YEAR, year);
newValues.put(KEY_MINUTE, minute);
newValues.put(KEY_SECOND, second);
// Insert it into the database.
return db.update(DATABASE_TABLE, newValues, where, null) != 0;
}
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_SQL);
}
#Override
public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading application's database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data!");
// Destroy old database:
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
// Recreate new database:
onCreate(_db);
}
}
}
MainActivity.java
import android.content.Context;
import android.database.Cursor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.view.View;
import java.util.Calendar;
public class MainActivity extends AppCompatActivity {
Button plus;
int second,minute,houre,day,mounth,year;
DBAdapter mDb = new DBAdapter(this);
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
ViewGroup.LayoutParams superparams =
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.MATCH_PARENT);
LinearLayout table = new LinearLayout(this);
plus = new Button(this);
plus.setText("+");
table.addView(plus);
setContentView(table);
plus.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Calendar c = Calendar.getInstance();
second = c.get(Calendar.SECOND);
minute = c.get(Calendar.MINUTE);
houre = c.get(Calendar.HOUR);
day = c.get(Calendar.DAY_OF_MONTH);
mounth = c.get(Calendar.MONTH);
year = c.get(Calendar.YEAR);
mDb.open();
mDb.insertRow(Integer.toString(year), Integer.toString (mounth),Integer.toString(day), Integer.toString(houre),Integer.toString(minute), Integer.toString(second));
mDb.close();
mDb.open();
Cursor g=mDb.getRow(2);
DisplayContact(g);
mDb.close();
}
});
}
public void DisplayContact(Cursor c)
{
Toast.makeText(this,"id: "+c.getString(0)+"\n"+
"year: "+c.getString(1)+"\n"+
"month: "+c.getString(2),
Toast.LENGTH_LONG).show();
}
}
You're missing commas , between your column specifications here:
+ KEY_MONTH + " TEXT"
+ KEY_DAY + " TEXT"
+ KEY_HOUR + " TEXT"
+ KEY_MINUTE + " TEXT"
After adding the missing commas, either uninstall your app or increment the schema version to get the table recreated.
I have already checked the other XML files for errors, however this is the file that the error message is saying the error is in. There is also a message that pops up whenever I try to run the app that says, "Files under the build folder are generated and should not be edited".
package com.example.drive.drivercorder;
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;
public class DBAdapter {
private static final String TAG = "DBAdapter";
public static final String KEY_ROWID = "_id";
public static final int COL_ROWID = 0;
public static final String KEY_DRIVETIME = "Drive Time";
public static final String KEY_NIGHTORDAY = "Time of Day";
public static final int COL_DRIVETIME = 1;
public static final int COL_NIGHTORDAY = 2;
public static final String[] ALL_KEYS = new String[] {KEY_ROWID, KEY_DRIVETIME, KEY_NIGHTORDAY, };
public static final String DATABASE_NAME = "MyDb";
public static final String DATABASE_TABLE = "mainTable";
public static final int DATABASE_VERSION = 2;
private static final String DATABASE_CREATE_SQL =
"create table " + DATABASE_TABLE
+ " (" + KEY_ROWID + " integer primary key autoincrement, "
+ KEY_DRIVETIME + " integer not null, "
+ KEY_NIGHTORDAY + " text not null "
+ ");";
private final Context context;
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx) {
this.context = ctx;
myDBHelper = new DatabaseHelper(context);
}
public DBAdapter open() {
db = myDBHelper.getWritableDatabase();
return this;
}
public void close() {
myDBHelper.close();
}
public long insertRow(int drivetime, String nightorday) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_DRIVETIME, Drive Time);
initialValues.put(KEY_NIGHTORDAY, Time of Day);
return db.insert(DATABASE_TABLE, null, initialValues);
}
public boolean deleteRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
return db.delete(DATABASE_TABLE, where, null) != 0;
}
public void deleteAll() {
Cursor c = getAllRows();
long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
if (c.moveToFirst()) {
do {
deleteRow(c.getLong((int) rowId));
} while (c.moveToNext());
}
c.close();
}
public Cursor getAllRows() {
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
public Cursor getRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
public boolean updateRow(long rowId, String drivetime, String nightorday) {
String where = KEY_ROWID + "=" + rowId;
ContentValues newValues = new ContentValues();
newValues.put(KEY_DRIVETIME, Drive Time);
newValues.put(KEY_NIGHTORDAY, Time of Day);
return db.update(DATABASE_TABLE, newValues, where, null) != 0;
}
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_SQL);
}
#Override
public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading application's database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data!");
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(_db);
}
}
}
There is also a message that pops up whenever I try to run the app that says, "Files under the build folder are generated and should not be edited".
I think you are changing the .class file in debug/DDMS mode or something like that. Please check and make sure to edit your .java file instead.
Posting your relevant logcat messages and also the XML file in question might help understand the problem.
Heyhey :)
I looked at several Questions to the same topic, but I found no solution to my problem.
A NullPointerException at this.getReadableDatabase(); appears...
Here's my Code:
public class DatabaseHandler extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "TODO_APP";
/*--------------------------- TABLE ITEMS START ---------------------------*/
private static final String TABLE_ITEMS = "items";
private static String KEY_ID_ITEMS = "id_items";
private static final String KEY_CATEGORY_ITEMS = "category";
private static final String KEY_DATETIME_ITEMS = "datetime";
private static String KEY_NAME_ITEMS = "name";
private static final String KEY_DESCRIPTION_ITEMS = "description";
private static final String KEY_ALARM_ITEMS = "alarm";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// create table ITEMS
String CREATE_ITEMS_TABLE = "CREATE TABLE " + TABLE_ITEMS + "("
+ KEY_ID_ITEMS + " INTEGER PRIMARY KEY," + KEY_CATEGORY_ITEMS
+ " INTEGER," + KEY_DATETIME_ITEMS
+ " TIMESTAMP DEFAULT CURRENT_TIMESTAMP," + KEY_NAME_ITEMS
+ " TEXT," + KEY_DESCRIPTION_ITEMS + " TEXT," + KEY_ALARM_ITEMS
+ " INTEGER" + ");";
db.execSQL(CREATE_ITEMS_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_ITEMS);
// Create tables again
this.onCreate(db);
}
public void addItem(DB_Item item) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_CATEGORY_ITEMS, item.getCategory());
values.put(KEY_NAME_ITEMS, item.getName());
values.put(KEY_DESCRIPTION_ITEMS, item.getDescription());
values.put(KEY_ALARM_ITEMS, item.getAlarm());
// Inserting Row
db.insert(TABLE_ITEMS, null, values);
db.close(); // Closing database connection
}
public DB_Item getItem(String name) {
//!!!!! Here is one problem !!!!!
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_ITEMS, new String[] { KEY_ID_ITEMS,
KEY_CATEGORY_ITEMS, KEY_DATETIME_ITEMS, KEY_NAME_ITEMS,
KEY_DESCRIPTION_ITEMS, KEY_ALARM_ITEMS },
KEY_NAME_ITEMS = " = ?", new String[] { String.valueOf(name) },
null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
// DB_Item (int category, String name, String description, int
// alarm)
DB_Item item = new DB_Item(cursor.getInt(1), cursor.getString(3),
cursor.getString(4), cursor.getInt(5));
return item;
}
public List<DB_Item> getAllItems() {
List<DB_Item> itemList = new ArrayList<DB_Item>();
// SELECT ALL
String selectQuery = "SELECT * FROM " + TABLE_ITEMS;
//!!!!!!!!!! here is the other Problem
SQLiteDatabase database = this.getWritableDatabase();
Cursor cursor = database.rawQuery(selectQuery, null);
// go through all rows and then adding to list
if (cursor.moveToFirst()) {
do {
DB_Item item = new DB_Item();
item.setCategory(Integer.parseInt(cursor.getString(0)));
// TODO
// adding to list
itemList.add(item);
} while (cursor.moveToNext());
}
return itemList;
}
[and so on, didn't copy the whole code]
Hope you can help me...
The error appears definitely at SQLiteDatabase db = this.getReadableDatabase();
Output:
09-03 08:34:17.863: E/AndroidRuntime(7074): java.lang.RuntimeException: Unable to start activity ComponentInfo{todo.todo_list/todo.view.StartApp}: java.lang.NullPointerException
09-03 08:34:17.863: E/AndroidRuntime(7074): at todo.database.DatabaseHandler.getAllItems(DatabaseHandler.java:144)
09-03 08:34:17.863: E/AndroidRuntime(7074): at todo.helper.SortItems.sortItemsCategory(SortItems.java:16)
09-03 08:34:17.863: E/AndroidRuntime(7074): at todo.view.StartApp.onCreate(StartApp.java:36)
chnage you class to something like this:
package com.mhp.example;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
/*--------------------------- TABLE ITEMS START ---------------------------*/
private static final String TABLE_ITEMS = "items";
private static String KEY_ID_ITEMS = "id_items";
private static final String KEY_CATEGORY_ITEMS = "category";
private static final String KEY_DATETIME_ITEMS = "datetime";
private static String KEY_NAME_ITEMS = "name";
private static final String KEY_DESCRIPTION_ITEMS = "description";
private static final String KEY_ALARM_ITEMS = "alarm";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "dbname";
private static final int DATABASE_VERSION = 1;
tring CREATE_ITEMS_TABLE = "CREATE TABLE " + TABLE_ITEMS + "("
+ KEY_ID_ITEMS + " INTEGER PRIMARY KEY," + KEY_CATEGORY_ITEMS
+ " INTEGER," + KEY_DATETIME_ITEMS
+ " TIMESTAMP DEFAULT CURRENT_TIMESTAMP," + KEY_NAME_ITEMS
+ " TEXT," + KEY_DESCRIPTION_ITEMS + " TEXT," + KEY_ALARM_ITEMS
+ " INTEGER" + ");";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
try {
db.execSQL(CREATE_ITEMS_TABLE);
} catch (SQLException e) {
e.printStackTrace();
}
}
#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 contacts");
onCreate(db);
}
}
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
public void addItem(DB_Item item) {
ContentValues values = new ContentValues();
values.put(KEY_CATEGORY_ITEMS, item.getCategory());
values.put(KEY_NAME_ITEMS, item.getName());
values.put(KEY_DESCRIPTION_ITEMS, item.getDescription());
values.put(KEY_ALARM_ITEMS, item.getAlarm());
// Inserting Row
db.insert(TABLE_ITEMS, null, values);
}
public DB_Item getItem(String name) {
Cursor cursor = db.query(TABLE_ITEMS, new String[] { KEY_ID_ITEMS,
KEY_CATEGORY_ITEMS, KEY_DATETIME_ITEMS, KEY_NAME_ITEMS,
KEY_DESCRIPTION_ITEMS, KEY_ALARM_ITEMS },
KEY_NAME_ITEMS = " = ?", new String[] { String.valueOf(name) },
null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
}
// DB_Item (int category, String name, String description, int
// alarm)
DB_Item item = new DB_Item(cursor.getInt(1), cursor.getString(3),
cursor.getString(4), cursor.getInt(5));
return item;
}
public List<DB_Item> getAllItems() {
List<DB_Item> itemList = new ArrayList<DB_Item>();
// SELECT ALL
String selectQuery = "SELECT * FROM " + TABLE_ITEMS;
Cursor cursor = db.rawQuery(selectQuery, null);
// go through all rows and then adding to list
if (cursor.moveToFirst()) {
do {
DB_Item item = new DB_Item();
item.setCategory(Integer.parseInt(cursor.getString(0)));
// TODO
// adding to list
itemList.add(item);
} while (cursor.moveToNext());
}
return itemList;
}
}
NOTE: when you create object from DBAdapter,you should open() db and after your work close() it.
DBAdapter db = new DBAdapter(contex);
db.open();
//do you work
db.close();
Just use getReadableDatabase() without this.
I'm developing an app that (so far) pulls data from an API, inserts it to a local SQLite database & displays it on screen.
In order to make my life simpler, I wrote a master database adapter (MyDBAdapter) as well as adapters for each individual table, according to the top anser for this question.
While developing the app, I'm also teaching myself unit testing in JUnit (not sure if this is relevant, but I figured I'd throw it in there).
When trying to refresh the database I somehow dropped all the tables and now I can't get them back. When I increment the DB_VERSION value, onUpgrade() doesn't get called, and the app errors out because it's trying to access nonexistent tables.
What circumstances would cause onUpgrade() to not get called? I'm at my wits' end trying to figure this out.
MyDbAdapter:
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class MyDbAdapter {
public static final String TAG = "MyDbAdapter";
protected static final String DB_NAME = "mydb.db";
protected static final int DB_VERSION = 21;
private final Context context;
private DbHelper helper;
private SQLiteDatabase db;
private static final String CREATE_TABLE_CRUISE_LINES = "create table " + CruiseLineAdapter.TABLE + " (" + CruiseLineAdapter.C_ID + " integer primary key autoincrement, "
+ CruiseLineAdapter.C_NAME + " TEXT);";
private static final String CREATE_TABLE_SHIPS = "create table " + ShipAdapter.TABLE + " (" + ShipAdapter.C_ID + " integer primary key autoincrement, "
+ ShipAdapter.C_NAME + " TEXT, "
+ ShipAdapter.C_CRUISE_LINE + " integer);";
private static final String CREATE_TABLE_TABLE_UPDATES = "create table " + UpdateTimestampAdapter.TABLE + " (" + UpdateTimestampAdapter.C_ID + " integer primary key autoincrement, "
+ UpdateTimestampAdapter.C_TABLE_NAME + " TEXT, "
+ UpdateTimestampAdapter.C_LAST_UPDATE + " TEXT);";
private static final String DROP_TABLE = "drop table if exists %s";
private static final String DROP_TABLE_CRUISE_LINES = String.format(DROP_TABLE, CruiseLineAdapter.TABLE);
private static final String DROP_TABLE_SHIPS = String.format(DROP_TABLE, ShipAdapter.TABLE);
private static final String DROP_TABLE_TABLE_UPDATES = String.format(DROP_TABLE, UpdateTimestampAdapter.TABLE);
public MyDbAdapter (Context context) {
this.context = context;
helper = new DbHelper(this.context);
}
private static class DbHelper extends SQLiteOpenHelper {
DbHelper (Context context) {
super(context, DB_NAME, null, DB_VERSION);
Log.i(TAG, "initialized");
}
#Override
public void onCreate(SQLiteDatabase db) {
Log.i(TAG, "Database created: version " + DB_VERSION);
db.execSQL(CREATE_TABLE_CRUISE_LINES);
db.execSQL(CREATE_TABLE_SHIPS);
db.execSQL(CREATE_TABLE_TABLE_UPDATES);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "Database upgraded to " + DB_VERSION);
db.execSQL(DROP_TABLE_CRUISE_LINES);
db.execSQL(DROP_TABLE_SHIPS);
db.execSQL(DROP_TABLE_TABLE_UPDATES);
this.onCreate(db);
}
}
public MyDbAdapter open() throws SQLException {
db = helper.getWritableDatabase();
return this;
}
public void close() {
helper.close();
}
}
ShipAdapter:
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
public class ShipAdapter {
public static final String TAG = "ShipAdapter";
public static final String TABLE = "ships";
public static final String C_ID = BaseColumns._ID;
public static final String C_NAME = "name";
public static final String C_CRUISE_LINE = "cruise_line";
private DbHelper dbHelper;
private SQLiteDatabase db;
private final Context context;
private static class DbHelper extends SQLiteOpenHelper {
DbHelper (Context context) {
super(context, MyDbAdapter.DB_NAME, null, MyDbAdapter.DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
public ShipAdapter(Context context) {
this.context = context;
}
public ShipAdapter open() throws SQLException {
dbHelper = new DbHelper(context);
db = dbHelper.getWritableDatabase();
return this;
}
public void close() {
dbHelper.close();
}
public long createShip(String name, long cruise_line_id) {
ContentValues initialValues = new ContentValues();
initialValues.put(C_NAME, name);
initialValues.put(C_CRUISE_LINE, cruise_line_id);
return db.insert(TABLE, null, initialValues);
}
public long createShip(long id, String name, long cruise_line_id) {
ContentValues initialValues = new ContentValues();
initialValues.put(C_ID, id);
initialValues.put(C_NAME, name);
initialValues.put(C_CRUISE_LINE, cruise_line_id);
return db.insert(TABLE, null, initialValues);
}
public long createShip(ShipModel ship) {
return createShip(ship.getName(), ship.getCruiseLineId());
}
public long insertOrIgnoreShip(long id, String name, long cruise_line_id) {
ContentValues initialValues = new ContentValues();
initialValues.put(C_ID, id);
initialValues.put(C_NAME, name);
initialValues.put(C_CRUISE_LINE, cruise_line_id);
return db.insertWithOnConflict(TABLE, null, initialValues, SQLiteDatabase.CONFLICT_IGNORE);
}
public long insertOrIgnoreShip(ShipModel ship) {
return insertOrIgnoreShip(ship.getId(), ship.getName(), ship.getCruiseLineId());
}
public List<ShipModel> getAllShips() {
List<ShipModel> ships = new ArrayList<ShipModel>();
Cursor cursor = getAllShipsCursor();
if (cursor.getCount() > 0) {
while(!cursor.isAfterLast()) {
ships.add(cursorToShip(cursor));
cursor.moveToNext();
}
}
return ships;
}
public Cursor getAllShipsCursor() {
Cursor cursor = db.query(TABLE, null, null, null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
}
return cursor;
}
public ShipModel getShip(long id) {
Cursor cursor = getShipCursor(id);
if (cursor.getCount() > 0) {
return cursorToShip(cursor);
}
return null;
}
public Cursor getShipCursor(long id) {
Cursor cursor = db.query(TABLE, null, C_ID + " = ?", new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
}
return cursor;
}
public ShipModel getShip(String name) {
Cursor cursor = getShipCursor(name);
if (cursor.getCount() > 0) {
return cursorToShip(cursor);
}
return null;
}
public Cursor getShipCursor(String name) {
Cursor cursor = db.query(TABLE, null, C_NAME + " = ?", new String[] { name }, null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
}
return cursor;
}
public List<ShipModel> getShipsByCruiseLine(long cruise_line_id) {
List<ShipModel> ships = new ArrayList<ShipModel>();
Cursor cursor = getShipsCursorByCruiseLine(cruise_line_id);
if (cursor.getCount() > 0) {
while (!cursor.isAfterLast()) {
ships.add(cursorToShip(cursor));
cursor.moveToNext();
}
}
return ships;
}
public Cursor getShipsCursorByCruiseLine(long cruise_line_id) {
Cursor cursor = db.query(TABLE, null, C_CRUISE_LINE + " = ?", new String[] { String.valueOf(cruise_line_id) }, null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
}
return cursor;
}
public boolean updateShip(long id, String name, long cruise_line_id) {
ContentValues args = new ContentValues();
args.put(C_NAME, name);
args.put(C_CRUISE_LINE, cruise_line_id);
return db.update(TABLE, args, C_ID + " = ?", new String[] { String.valueOf(id) }) > 0;
}
public boolean updateShip(ShipModel ship) {
return updateShip(ship.getId(), ship.getName(), ship.getCruiseLineId());
}
public boolean deleteShip(long id) {
return db.delete(TABLE, C_ID + " = ?", new String[] { String.valueOf(id) }) > 0;
}
public boolean deleteShip(String name) {
return db.delete(TABLE, C_NAME + " = ?", new String[] { name }) > 0;
}
public boolean deleteShip(ShipModel ship) {
return deleteShip(ship.getName());
}
public boolean deleteAll() {
return db.delete(TABLE, null, null) > 0;
}
private ShipModel cursorToShip(Cursor cursor) {
long id = cursor.getLong(cursor.getColumnIndex(C_ID));
String name = cursor.getString(cursor.getColumnIndex(C_NAME));
long cruise_line_id = cursor.getLong(cursor.getColumnIndex(C_CRUISE_LINE));
return new ShipModel(id, name, cruise_line_id);
}
}
Communicator:
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.ConnectivityManager;
import android.util.Log;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NoHttpResponseException;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* Created by mcampo on 5/30/13.
*/
public class Communicator {
private static final String TAG = "Communicator";
private static final int CONNECTION_TIMEOUT = 10000;
protected String base_url = "http://[myapi]/mobileapi/";
protected Context context;
protected CruiseLineAdapter cruise_line_adapter;
protected ShipAdapter ship_adapter;
protected UpdateTimestampAdapter table_update_adapter;
protected String update_timestamps_json;
public Communicator() {
}
public Communicator (Context context) {
this.context = context;
this.cruise_line_adapter = new CruiseLineAdapter(this.context);
this.ship_adapter = new ShipAdapter(this.context);
this.table_update_adapter = new UpdateTimestampAdapter(this.context);
}
// begin defining getters / setters
/**
*
* #param context
*/
public void setContext(Context context) {
this.context = context;
this.cruise_line_adapter = new CruiseLineAdapter(this.context);
this.ship_adapter = new ShipAdapter(this.context);
this.table_update_adapter = new UpdateTimestampAdapter(this.context);
}
public Context getContext() {
return this.context;
}
// end getters / setters
private boolean isNetworkConnected() {
if (context == null) {
return false;
}
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
return cm.getActiveNetworkInfo() != null;
}
private String makeApiCall(String api_extension) throws IOException {
if (!isNetworkConnected()) {
throw new IOException("Your device is not connected to the internet. Please enable your network connection and restart CabinGuru.");
}
Log.d(TAG, "Making HTTP request to " + this.base_url + api_extension);
HttpClient httpClient = new DefaultHttpClient();
HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, CONNECTION_TIMEOUT);
HttpResponse response = httpClient.execute(new HttpGet(this.base_url + api_extension));
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
Log.i(TAG, "HTTP Response: " + out.toString());
return out.toString();
} else {
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
}
private boolean tableIsUpToDate(String table) throws IOException {
try {
String api_timestamp = getApiUpdateTimestamp(table);
String device_timestamp = getDeviceUpdateTimestamp(table);
if (device_timestamp == null || device_timestamp.equals("")) {
throw new NullPointerException("device_timestamp is null");
}
Log.i(TAG, "API Timestamp: " + api_timestamp);
Log.i(TAG, "Device Timestamp: " + device_timestamp);
// compare device_timestamp to api_timestamp. If device_timestamp comes after api_timestamp, table is up-to-date.
DateTime api_datetime = this.strToDateTime(api_timestamp);
DateTime device_datetime = this.strToDateTime(device_timestamp);
return device_datetime.isAfter(api_datetime);
} catch (NullPointerException e) {
e.printStackTrace();
Log.e(TAG, "NullPointerException encountered in tableIsUpToDate(" + table + "): " + e.getMessage() + " " + e.getCause());
return false;
}
}
private String getDeviceUpdateTimestamp(String table) {
String return_string = "";
table_update_adapter.open();
UpdateTimestampModel timestamp = this.table_update_adapter.getUpdateTimestamp(table);
table_update_adapter.close();
try {
return_string = timestamp.getLastUpdate();
return return_string;
} catch (NullPointerException e) {
Log.e(TAG, "NullPointerException encountered in getDeviceUpdateTimestamp(" + table + "): " + e.getMessage());
return "";
}
}
private boolean updateLastUpdateTimestamp(String table) {
// set up current timestamp
DateTime timestamp = new DateTime(System.currentTimeMillis());
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
String now = formatter.print(timestamp);
// fetch ID of row to update
table_update_adapter.open();
table_update_adapter.updateOrCreateTimestamp(table, now);
table_update_adapter.close();
return true;
}
private void getApiUpdateTimestamps() throws IOException {
if (this.update_timestamps_json == null || this.update_timestamps_json.equals(""))
try {
this.update_timestamps_json = this.makeApiCall("get_update_timestamps");
} catch (NoHttpResponseException e) {
Log.e(TAG, "App was unable to connect to the servers.");
}
}
private String getApiUpdateTimestamp(String table) throws IOException {
this.getApiUpdateTimestamps();
try {
if (this.update_timestamps_json == null) {
throw new Exception("Could not fetch update timestamps. Check and make sure you are able to connect to " + this.base_url + ".");
}
JSONObject timestamps = new JSONObject(this.update_timestamps_json);
return timestamps.getString(table);
} catch (JSONException e) {
Log.e(TAG, "An error occurred when extracting update timestamps from the api: " + e.getMessage() + " | " + e.getCause());
return null;
} catch (Exception e) {
Log.e(TAG, e.getMessage());
return null;
}
}
public boolean updateCruiseLines() throws IOException {
// if the cruise lines from the API have been updated since the last update on the device, update the device.
if (!this.tableIsUpToDate(CruiseLineAdapter.TABLE)) {
Log.i(TAG, "Attempting API call for Cruise Lines.");
try {
String cruise_line_json = this.makeApiCall("cruise_lines");
JSONArray cruise_lines = new JSONArray(cruise_line_json);
// loop through cruise_lines, add to database
int array_size = cruise_lines.length();
cruise_line_adapter.open();
for (int i = 0; i < array_size; i++) {
JSONObject cruise_line = cruise_lines.getJSONObject(i);
int cruise_line_id = cruise_line.getInt("CruiseLineID");
String cruise_line_name = cruise_line.getString("Name");
// insert record into database.
this.cruise_line_adapter.insertOrIgnoreCruiseLine(cruise_line_id, cruise_line_name);
}
cruise_line_adapter.close();
this.updateLastUpdateTimestamp(CruiseLineAdapter.TABLE);
} catch (JSONException e) {
Log.e(TAG, "JSONException encountered in updateCruiseLines(): " + e.getMessage());
e.printStackTrace();
return false;
}
} else {
Log.i(TAG, "Cruise Line records exist. No API call necessary.");
}
return true;
}
public boolean updateShips() throws IOException {
// if the ships from the API have been updated since the last update on the device, update the device
if (!this.tableIsUpToDate(ShipAdapter.TABLE)) {
Log.i(TAG, "Attempting API call for Ships.");
try {
String ships_json = this.makeApiCall("ships");
JSONArray ships = new JSONArray(ships_json);
// loop through ships, add to database
int array_size = ships.length();
ship_adapter.open();
for (int i = 0; i < array_size; i++) {
JSONObject ship = ships.getJSONObject(i);
int id = ship.getInt("ShipID");
String name = ship.getString("ShipName");
int cruise_line_id = ship.getInt("CruiseLineID");
this.ship_adapter.insertOrIgnoreShip(id, name, cruise_line_id);
}
ship_adapter.close();
this.updateLastUpdateTimestamp(ShipAdapter.TABLE);
} catch (JSONException e) {
Log.e(TAG, "JSONException encountered in updateShips():" + e.getMessage());
e.printStackTrace();
return false;
}
} else {
Log.i(TAG, "Ship records exist. No API call necessary.");
}
return true;
}
private DateTime strToDateTime(String timestamp) {
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
return formatter.parseDateTime(timestamp);
}
}
Android would not be able to figure out that it needs to run MyDbAdapter on its own.
Create a class that extends Application.
public class MyApplication extends Application {
private static MyDbAdapter dbAdapter;
#Override
public void onCreate() {
super.onCreate();
dbAdapter = new MyDbAdapter(getApplicationContext());
}
}
On your AndroidManifest.xml, you need to set the attribute in the application element like this:
<application
android:name=".MyApplication"
...
/application>
After stepping away from the problem for a few hours I came up with this solution:
Instead of making the *Adapter classes independent of one another, I modified the code to make them children of MyDBAdapter. This way, when open() is called, it calls the open() method of MyDBAdapter, checking the DB version & upgrading when appropriate.
MyDbAdapter:
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class MyDbAdapter {
public static final String TAG = "MyDbAdapter";
protected static final String DB_NAME = "mydb.db";
protected static final int DB_VERSION = 21;
private final Context context;
private DbHelper helper;
private SQLiteDatabase db;
private static final String CREATE_TABLE_CRUISE_LINES = "create table " + CruiseLineAdapter.TABLE + " (" + CruiseLineAdapter.C_ID + " integer primary key autoincrement, "
+ CruiseLineAdapter.C_NAME + " TEXT);";
private static final String CREATE_TABLE_SHIPS = "create table " + ShipAdapter.TABLE + " (" + ShipAdapter.C_ID + " integer primary key autoincrement, "
+ ShipAdapter.C_NAME + " TEXT, "
+ ShipAdapter.C_CRUISE_LINE + " integer);";
private static final String CREATE_TABLE_TABLE_UPDATES = "create table " + UpdateTimestampAdapter.TABLE + " (" + UpdateTimestampAdapter.C_ID + " integer primary key autoincrement, "
+ UpdateTimestampAdapter.C_TABLE_NAME + " TEXT, "
+ UpdateTimestampAdapter.C_LAST_UPDATE + " TEXT);";
private static final String DROP_TABLE = "drop table if exists %s";
private static final String DROP_TABLE_CRUISE_LINES = String.format(DROP_TABLE, CruiseLineAdapter.TABLE);
private static final String DROP_TABLE_SHIPS = String.format(DROP_TABLE, ShipAdapter.TABLE);
private static final String DROP_TABLE_TABLE_UPDATES = String.format(DROP_TABLE, UpdateTimestampAdapter.TABLE);
public MyDbAdapter (Context context) {
this.context = context;
helper = new DbHelper(this.context);
}
private static class DbHelper extends SQLiteOpenHelper {
DbHelper (Context context) {
super(context, DB_NAME, null, DB_VERSION);
Log.i(TAG, "initialized");
}
#Override
public void onCreate(SQLiteDatabase db) {
Log.i(TAG, "Database created: version " + DB_VERSION);
db.execSQL(CREATE_TABLE_CRUISE_LINES);
db.execSQL(CREATE_TABLE_SHIPS);
db.execSQL(CREATE_TABLE_TABLE_UPDATES);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "Database upgraded to " + DB_VERSION);
db.execSQL(DROP_TABLE_CRUISE_LINES);
db.execSQL(DROP_TABLE_SHIPS);
db.execSQL(DROP_TABLE_TABLE_UPDATES);
this.onCreate(db);
}
}
public MyDbAdapter open() throws SQLException {
db = helper.getWritableDatabase();
return this;
}
public void close() {
helper.close();
}
}
ShipAdapter:
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
public class ShipAdapter extends MyDbAdapter {
public static final String TAG = "ShipAdapter";
public static final String TABLE = "ships";
public static final String C_ID = BaseColumns._ID;
public static final String C_NAME = "name";
public static final String C_CRUISE_LINE = "cruise_line";
public ShipAdapter(Context context) {
this.context = context;
}
public long createShip(String name, long cruise_line_id) {
ContentValues initialValues = new ContentValues();
initialValues.put(C_NAME, name);
initialValues.put(C_CRUISE_LINE, cruise_line_id);
return db.insert(TABLE, null, initialValues);
}
public long createShip(long id, String name, long cruise_line_id) {
ContentValues initialValues = new ContentValues();
initialValues.put(C_ID, id);
initialValues.put(C_NAME, name);
initialValues.put(C_CRUISE_LINE, cruise_line_id);
return db.insert(TABLE, null, initialValues);
}
public long createShip(ShipModel ship) {
return createShip(ship.getName(), ship.getCruiseLineId());
}
public long insertOrIgnoreShip(long id, String name, long cruise_line_id) {
ContentValues initialValues = new ContentValues();
initialValues.put(C_ID, id);
initialValues.put(C_NAME, name);
initialValues.put(C_CRUISE_LINE, cruise_line_id);
return db.insertWithOnConflict(TABLE, null, initialValues, SQLiteDatabase.CONFLICT_IGNORE);
}
public long insertOrIgnoreShip(ShipModel ship) {
return insertOrIgnoreShip(ship.getId(), ship.getName(), ship.getCruiseLineId());
}
public List<ShipModel> getAllShips() {
List<ShipModel> ships = new ArrayList<ShipModel>();
Cursor cursor = getAllShipsCursor();
if (cursor.getCount() > 0) {
while(!cursor.isAfterLast()) {
ships.add(cursorToShip(cursor));
cursor.moveToNext();
}
}
return ships;
}
public Cursor getAllShipsCursor() {
Cursor cursor = db.query(TABLE, null, null, null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
}
return cursor;
}
public ShipModel getShip(long id) {
Cursor cursor = getShipCursor(id);
if (cursor.getCount() > 0) {
return cursorToShip(cursor);
}
return null;
}
public Cursor getShipCursor(long id) {
Cursor cursor = db.query(TABLE, null, C_ID + " = ?", new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
}
return cursor;
}
public ShipModel getShip(String name) {
Cursor cursor = getShipCursor(name);
if (cursor.getCount() > 0) {
return cursorToShip(cursor);
}
return null;
}
public Cursor getShipCursor(String name) {
Cursor cursor = db.query(TABLE, null, C_NAME + " = ?", new String[] { name }, null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
}
return cursor;
}
public List<ShipModel> getShipsByCruiseLine(long cruise_line_id) {
List<ShipModel> ships = new ArrayList<ShipModel>();
Cursor cursor = getShipsCursorByCruiseLine(cruise_line_id);
if (cursor.getCount() > 0) {
while (!cursor.isAfterLast()) {
ships.add(cursorToShip(cursor));
cursor.moveToNext();
}
}
return ships;
}
public Cursor getShipsCursorByCruiseLine(long cruise_line_id) {
Cursor cursor = db.query(TABLE, null, C_CRUISE_LINE + " = ?", new String[] { String.valueOf(cruise_line_id) }, null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
}
return cursor;
}
public boolean updateShip(long id, String name, long cruise_line_id) {
ContentValues args = new ContentValues();
args.put(C_NAME, name);
args.put(C_CRUISE_LINE, cruise_line_id);
return db.update(TABLE, args, C_ID + " = ?", new String[] { String.valueOf(id) }) > 0;
}
public boolean updateShip(ShipModel ship) {
return updateShip(ship.getId(), ship.getName(), ship.getCruiseLineId());
}
public boolean deleteShip(long id) {
return db.delete(TABLE, C_ID + " = ?", new String[] { String.valueOf(id) }) > 0;
}
public boolean deleteShip(String name) {
return db.delete(TABLE, C_NAME + " = ?", new String[] { name }) > 0;
}
public boolean deleteShip(ShipModel ship) {
return deleteShip(ship.getName());
}
public boolean deleteAll() {
return db.delete(TABLE, null, null) > 0;
}
private ShipModel cursorToShip(Cursor cursor) {
long id = cursor.getLong(cursor.getColumnIndex(C_ID));
String name = cursor.getString(cursor.getColumnIndex(C_NAME));
long cruise_line_id = cursor.getLong(cursor.getColumnIndex(C_CRUISE_LINE));
return new ShipModel(id, name, cruise_line_id);
}
}
Here is what i am trying to do, i have created a SQL database to hold a giant table of drinks, The table looks like this:
**_ID ALCOHOL TYPE BRAND PRICE**
Ex. 1 Liquor Vodka Smirnoff 14
Here is the code for my database adapter:
package net.learn2develop.Database;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
public static final String KEY_ROWID = "_id";
public static final String KEY_ALCOHOL = "alcohol";
public static final String KEY_TYPE = "type";
public static final String KEY_BRAND = "brand";
public static final String KEY_PRICE = "price";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "booze";
private static final String DATABASE_TABLE = "titles";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE =
"create table titles (_id integer primary key autoincrement, "
+ "alcohol text not null, type text not null, "
+ "brand text not null);" + "price integer not null";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
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 titles");
onCreate(db);
}
}
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
//---insert a title into the database---
public long insertTitle(String alcohol, String type, String brand, int price)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_ALCOHOL, alcohol);
initialValues.put(KEY_TYPE, type);
initialValues.put(KEY_BRAND, brand);
initialValues.put(KEY_PRICE, price);
return db.insert(DATABASE_TABLE, null, initialValues);
}
//---deletes a particular title---
public boolean deleteTitle(long rowId)
{
return db.delete(DATABASE_TABLE, KEY_ROWID +
"=" + rowId, null) > 0;
}
//---retrieves all the titles---
public Cursor getAllTitles()
{
return db.query(DATABASE_TABLE, new String[] {
KEY_ROWID,
KEY_ALCOHOL,
KEY_TYPE,
KEY_BRAND,
KEY_PRICE},
null,
null,
null,
null,
null);
}
//---retrieves a particular title---
public Cursor getTitle(long rowId) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {
KEY_ROWID,
KEY_ALCOHOL,
KEY_TYPE,
KEY_BRAND,
KEY_PRICE
},
KEY_ROWID + "=" + rowId,
null,
null,
null,
null,
null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
//---updates a title---
public boolean updateTitle(long rowId, String alcohol,
String type, String brand, int price)
{
ContentValues args = new ContentValues();
args.put(KEY_ALCOHOL, alcohol);
args.put(KEY_TYPE, type);
args.put(KEY_BRAND, brand);
args.put(KEY_PRICE, price);
return db.update(DATABASE_TABLE, args,
KEY_ROWID + "=" + rowId, null) > 0;
}
}
Now I know I could add them individually in my main activity by calling:
//---add 2 titles---
db.open();
long id;
id = db.insertTitle(
"Liquor",
"Vodka",
"Smirnoff",
"14");
id = db.insertTitle(
"Liquor",
"Rum",
"Captain Morgan",
"20");
db.close();
The problem is i have hundreds to add.... what is the best way to go about adding them all into the DB?
Thanks in advance for anyhelp you guys! I am still learning, i have never used a database before so im lost rite now.
I wouldn't recommend hard coding them in your source, since you will have double the data (and then some) and will suck RAM and storage from your users.
I assume that there is no good reason for you to statically load the list into your DB at runtime. I also assume that you already have the list of drinks.
I would create a CSV file from the list and then use a desktop SQLite editor on my PC to load the list into my table(s), then include the database as a resource in my app.
Google will lead you to plenty of SQLite editors.
I do all of my DB design and initial loading/testing on my PC before moving it to Android. It's a lot easier and faster.
Good luck.
You could do something like this:
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {
for(ContentValues con:conValues){
db.insert(TABLE_COLUMN,null,con);
}
db.setTransactionSuccessful();
}
finally {
db.endTransaction();
}
You can read more about begintransaction and end transaction SQLite Optimization in Android