I keep on getting this error saying that the table in my database doesn't exist but the table was declared.
So, I have this class to create appointments into a database, which is:
package com.example.calendar;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CalendarView;
import android.widget.EditText;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.example.calendar.Appointment;
import static com.example.calendar.Constants.KEY_DATE;
import static com.example.calendar.Constants.KEY_DETAILS;
import static com.example.calendar.Constants.KEY_ID;
import static com.example.calendar.Constants.KEY_TIME;
import static com.example.calendar.Constants.KEY_TITLE;
import static com.example.calendar.Constants.TABLE_APP;
public class CreateAppointment extends Activity implements OnClickListener{
EditText titleTextBox, timeTextBox, detailsTextBox;
int[] dateSelected = new int[3];
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.create);
titleTextBox = (EditText) findViewById(R.id.apptTitle);
timeTextBox = (EditText) findViewById(R.id.apptTime);
detailsTextBox = (EditText) findViewById(R.id.apptDetails);
View createButton = (Button) findViewById(R.id.apptSave);
String dateToPass = null;
Bundle getExtraFromMain = getIntent().getExtras();
if(getExtraFromMain != null){
dateSelected = getExtraFromMain.getIntArray(dateToPass);
}
createButton.setOnClickListener(this);
}
private Cursor cursor(){
DBHandler appointment = new DBHandler(this);
SQLiteDatabase db = appointment.getReadableDatabase();
String[] getValueFrom = {KEY_DATE, KEY_TITLE, KEY_TIME, KEY_DETAILS};
Cursor cursor = db.query(TABLE_APP, getValueFrom, null, null, null, null, KEY_DATE + " ASC");
return cursor;
}
private void save(){
String getTime = timeTextBox.getText().toString();
String getTitle = titleTextBox.getText().toString();
String getDetails = detailsTextBox.getText().toString();
DBHandler appointment = new DBHandler(this);
SQLiteDatabase db = appointment.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TITLE, getTitle);
values.put(KEY_TIME, getTime);
values.put(KEY_DETAILS, getDetails);
values.put(KEY_DATE, dateSelected[0] + "/" + dateSelected[1] + "/" + dateSelected[2]);
db.insertOrThrow(TABLE_APP, null, values);
appointment.close();
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.apptSave:
save();
finish();
break;
}
}
}
And, of course, my handler:
package com.example.calendar;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import static com.example.calendar.Constants.KEY_DATE;
import static com.example.calendar.Constants.KEY_DETAILS;
import static com.example.calendar.Constants.KEY_ID;
import static com.example.calendar.Constants.KEY_TIME;
import static com.example.calendar.Constants.KEY_TITLE;
import static com.example.calendar.Constants.TABLE_APP;
public class DBHandler extends SQLiteOpenHelper {
//Variables needed
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "appts.db";// database name
public DBHandler(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override//create table
public void onCreate(SQLiteDatabase db){
String CREATE_APPOINTMENTS_TABLE = "CREATE TABLE " + TABLE_APP + " ("
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_DATE + " TEXT NOT NULL,"
+ KEY_TITLE + " TEXT NOT NULL, " + KEY_TIME + " TEXT NOT NULL, " + KEY_DETAILS + " TEXT NOT NULL" + ");";
db.execSQL(CREATE_APPOINTMENTS_TABLE);
}
#Override//when upgraded, trigger
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("DROP TABLE IF EXISTS " + TABLE_APP);//delete table from older version
onCreate(db);//create new table
}
}
And additionally, the interface where the table name was declared:
package com.example.calendar;
import android.provider.BaseColumns;
public interface Constants extends BaseColumns{
public static final String TABLE_APP = "appointments";// table name
public static final String KEY_ID = "id";
public static final String KEY_DATE = "date";
public static final String KEY_TITLE = "title";
public static final String KEY_TIME = "time";
public static final String KEY_DETAILS = "details";
}
When I hit the button on the Activity, Logcat gives me this:
03-24 02:18:28.134: E/AndroidRuntime(800): android.database.sqlite.SQLiteException: no such table: appointments: , while compiling: INSERT INTO appointments(time,title,date,details) VALUES (?,?,?,?)
03-24 02:18:28.134: E/AndroidRuntime(800): at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
03-24 02:18:28.134: E/AndroidRuntime(800): at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
03-24 02:18:28.134: E/AndroidRuntime(800): at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:112)
03-24 02:18:28.134: E/AndroidRuntime(800): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1718)
03-24 02:18:28.134: E/AndroidRuntime(800): at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1617)
03-24 02:18:28.134: E/AndroidRuntime(800): at com.example.calendar.CreateAppointment.save(CreateAppointment.java:69)
03-24 02:18:28.134: E/AndroidRuntime(800): at com.example.calendar.CreateAppointment.onClick(CreateAppointment.java:80)
Note: lines 69 and 80 are:
69:
db.insertOrThrow(TABLE_APP, null, values);
80:
save();//from switch statement
Can someone please help me??
Your code look fine, so changing the DATABASE_VERSION = 1 to DATABASE_VERSION = 2 may do the trick.
The reason because the onCreate() and onUpgrade() run only once! Therefore if you did any change within them after calling them, the change will not take affect. So changing the VERSION of the database or clearing your application data in your device/emulator could trigger to run the onCreate() and onUpgrade() again.
So whenever you change anything within the onCreate() and onUpgrade() increase the Database version.
Related
Alright, So. I've been trying for the last couple of hours to display a database on a list view widget in android studio. I used this exact code in another project and it worked find, but now that I am trying to integrate it into this one, the app continuously crashes when ever I try to pull from the database. this includes the getLight Method and the getAllLight Method. I am at a complete lost here. Again, this code worked, idk why i am getting an error now. is there something wrong with my methods? is there something I can try?
package com.studios.primitive.safealwayz.ui.main.Light;
import com.studios.primitive.safealwayz.ui.main.Account.AccountModel;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class LightDatabaseHelper extends SQLiteOpenHelper {
public static final String LIGHTS = "LIGHTS";
public static final String COLUMN_LIGHTID = "LIGHTID";
public static final String COLUMN_USERNAME = "USERNAME";
public static final String COLUMN_LOCATION = "LOCATION";
public static final String COLUMN_STATUS = "STATUS";
public LightDatabaseHelper(#Nullable Context context) {
super(context, "lights.db", null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTableStatement = "CREATE TABLE " + LIGHTS + " (" + COLUMN_LIGHTID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_USERNAME + " TEXT, " + COLUMN_LOCATION + " TEXT, " + COLUMN_STATUS + " BOOL)";
db.execSQL(createTableStatement);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public boolean addLight(LightModel light, AccountModel accountModel) {
SQLiteDatabase db = getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COLUMN_USERNAME, accountModel.getUserName());
cv.put(COLUMN_LOCATION, light.getLocation());
cv.put(COLUMN_STATUS, light.isActive());
long insert = db.insert(LIGHTS, null, cv);
return insert != -1;
}
public void changeLightStatus(LightModel light){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COLUMN_LIGHTID, light.getLightID());
cv.put(COLUMN_LOCATION,light.getLocation());
cv.put(COLUMN_USERNAME, light.getUsername());
cv.put(COLUMN_STATUS, light.isActive());
db.update(LIGHTS, cv, COLUMN_LIGHTID + " = ?", new String[] { String.valueOf(light.getLightID())});
}
public List<LightModel> getAllLights(AccountModel account){
List<LightModel> rtnList = new ArrayList<>();
String queryCommand = "SELECT * FROM " + LIGHTS +" WHERE " + COLUMN_USERNAME + " = " + "'"+account.getUserName()+"'";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(queryCommand,null);
if(cursor.moveToFirst()){
do{
int LightID = cursor.getInt(0);
String username = cursor.getString(1);
String lightLocation = cursor.getString(2);
boolean lightStatus = cursor.getInt(3) == 1;
LightModel newLight = new LightModel(lightLocation, account);
newLight.setActive(lightStatus);
newLight.setLightID(LightID);
rtnList.add(newLight);
}while(cursor.moveToNext());
}else{
//returns an empty list
}
cursor.close();
db.close();
return rtnList;
}
public LightModel getLight(String id, String user){
LightModel light = new LightModel(user);
SQLiteDatabase db = this.getReadableDatabase();
String queryCommand = "SELECT * FROM " + LIGHTS + " WHERE "+ COLUMN_LIGHTID + " = "+ "'" + id +"'";
Cursor cursor = db.rawQuery(queryCommand,null);
if(cursor.moveToFirst()){
do{
int LightID = cursor.getInt(0);
String username = cursor.getString(1);
String location = cursor.getString(2);
boolean status = cursor.getInt(3) == 1? true: false;
light.setLightID(LightID);
light.setUsername(username);
light.setLocation(location);
light.setActive(status);
}while(cursor.moveToNext());
}else{
//returns an empty list
}
cursor.close();
db.close();
return light;
}
}
Here is the Activity Class
package com.studios.primitive.safealwayz;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import com.studios.primitive.safealwayz.ui.main.Account.AccountModel;
import com.studios.primitive.safealwayz.ui.main.Light.LightDatabaseHelper;
import com.studios.primitive.safealwayz.ui.main.Light.LightModel;
import java.util.List;
public class AccountLightActivity extends AppCompatActivity {
Button turn;
ListView listV;
EditText lightID;
ArrayAdapter<LightModel> lightArrayAdapter;
LightDatabaseHelper lightDatabaseHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_account_light);
final AccountModel model = (AccountModel) getIntent().getSerializableExtra("obj");
turn = (Button) findViewById(R.id.turn_light);
listV = (ListView) findViewById(R.id.list_view);
lightID = (EditText) findViewById(R.id.light_id_input);
/*
lightArrayAdapter = new ArrayAdapter<LightModel>(AccountLightActivity.this, android.R.layout.simple_list_item_1,lightDatabaseHelper.getAllLights(model));
listV.setAdapter(lightArrayAdapter);
*/
turn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String lightInput = lightID.getText().toString();
Toast.makeText(AccountLightActivity.this, model.getUserName(), Toast.LENGTH_SHORT).show();
LightModel li = lightDatabaseHelper.getLight(lightInput, model.getUserName());
Toast.makeText(AccountLightActivity.this, li.toString(), Toast.LENGTH_SHORT).show();
/*
if (lightInput.isEmpty()) {
Toast.makeText(AccountLightActivity.this, "Please Choose a LightID", Toast.LENGTH_SHORT).show();
}else{
LightModel li = lightDatabaseHelper.getLight(lightInput, model.getUserName());
if(li.isActive()){
li.setActive(false);
}else{
li.setActive(true);
}
lightDatabaseHelper.changeLightStatus(li);
Toast.makeText(AccountLightActivity.this, li.toString() , Toast.LENGTH_SHORT).show();
lightArrayAdapter = new ArrayAdapter<LightModel>(AccountLightActivity.this, android.R.layout.simple_list_item_1,lightDatabaseHelper.getAllLights(model));
listV.setAdapter(lightArrayAdapter);
}
*/
}
});
}
}
and finally, here is the error I've been getting.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.studios.primitive.safealwayz, PID: 2269
java.lang.NullPointerException
at com.studios.primitive.safealwayz.AccountLightActivity$1.onClick(AccountLightActivity.java:53)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
I'm building an application for a barber shop and im on a part now where I am creating an appointment and saving the data from that appointment, however when I go to click add to create the appointment, the application crashes and I left with this error;
E/CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 2 rows, 3 columns.
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: ie.app.barbershop, PID: 31270
java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetString(Native Method)
at android.database.CursorWindow.getString(CursorWindow.java:438)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
at ie.app.barbershop.TableControllerAppointments.read(TableControllerAppointments.java:46)
at ie.app.barbershop.Landing.readRecords(Landing.java:47)
at ie.app.barbershop.OnClickListenerCreateAppointment$1.onClick(OnClickListenerCreateAppointment.java:38)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:162)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
I/Process: Sending signal. PID: 31270 SIG: 9
Application terminated.
Here is my class for TableControllerAppointments.java
package ie.app.barbershop;
import android.content.Context;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.ArrayList;
import java.util.List;
public class TableControllerAppointments extends DatabaseHandler {
public TableControllerAppointments(Context context) {
super(context);
}
public boolean create(ObjectAppointment objectAppointments) {
ContentValues values = new ContentValues();
values.put("fullname", objectAppointments.fullName);
values.put("contactno", objectAppointments.contactNumber);
SQLiteDatabase db = this.getWritableDatabase();
boolean createSuccessful = db.insert("appointments", null, values) > 0;
db.close();
return createSuccessful;
}
public List<ObjectAppointment> read() {
List<ObjectAppointment> recordsList = new ArrayList<>();
String sql = "SELECT * FROM Appointments ORDER BY id DESC";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(sql, null);
if (cursor.moveToFirst()) {
do {
String fullName = cursor.getString(cursor.getColumnIndex("firstname"));
int contactNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex("contactno")));
ObjectAppointment objectAppointment = new ObjectAppointment();
objectAppointment.fullName = fullName;
objectAppointment.contactNumber = contactNumber;
recordsList.add(objectAppointment);
} while (cursor.moveToNext());
}
cursor.close();
db.close();
return recordsList;
}
public int count() {
SQLiteDatabase db = this.getWritableDatabase();
String sql = "SELECT * FROM appointments";
int recordCount = db.rawQuery(sql, null).getCount();
db.close();
return recordCount;
}
}
And here is my class for OnClickListenerCreateAppointment.java
package ie.app.barbershop;
import android.view.View;
import android.content.Context;
import android.view.LayoutInflater;
import android.widget.EditText;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.widget.Toast;
public class OnClickListenerCreateAppointment implements View.OnClickListener {
public ObjectAppointment objectAppointment;
#Override
public void onClick(View view){
final Context context = view.getRootView().getContext();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View formElementsView = inflater.inflate(R.layout.appointment_input_form, null, false);
final EditText editTextFullName = formElementsView.findViewById(R.id.editTextFullName);
final EditText editTextContactNumber = formElementsView.findViewById(R.id.editTextContactNumber);
ObjectAppointment objectAppointment = new ObjectAppointment();
new AlertDialog.Builder(context)
.setView(formElementsView)
.setTitle("Create Appointment")
.setPositiveButton("Add",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
String fullname = editTextFullName.getText().toString();
String contactno = editTextContactNumber.getText().toString();
((Landing) context).countRecords();
((Landing) context).readRecords();
dialog.cancel();
}
}).show();
boolean createSuccessful = new TableControllerAppointments(context).create(objectAppointment);
if(createSuccessful){
Toast.makeText(context, "Appointment Information was saved.", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context, "Unable to save appointment information", Toast.LENGTH_SHORT).show();
}
}
}
and this is my Landing.java class
package ie.app.barbershop;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import java.util.List;
public class Landing extends AppCompatActivity{
public Button buttonProducts;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_landing);
countRecords();
buttonProducts = findViewById(R.id.buttonProducts);
Button buttonCreateAppointment = findViewById(R.id.buttonCreateAppointment);
buttonCreateAppointment.setOnClickListener(new OnClickListenerCreateAppointment());
buttonProducts.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(Landing.this, Products.class));
}
});
}
public void readRecords() {
LinearLayout linearLayoutRecords = findViewById(R.id.linearLayoutRecords);
linearLayoutRecords.removeAllViews();
List<ObjectAppointment> appointments = new TableControllerAppointments(this).read();
if (appointments.size() > 0) {
for (ObjectAppointment obj : appointments) {
String fullName = obj.fullName;
int contactNumber = obj.contactNumber;
String textViewContents = fullName + " - " + contactNumber;
TextView textViewAppointmentItem= new TextView(this);
textViewAppointmentItem.setPadding(0, 10, 0, 10);
textViewAppointmentItem.setText(textViewContents);
textViewAppointmentItem.setTag(Integer.toString(contactNumber));
linearLayoutRecords.addView(textViewAppointmentItem);
}
}
else {
TextView locationItem = new TextView(this);
locationItem.setPadding(8, 8, 8, 8);
locationItem.setText("No records yet.");
linearLayoutRecords.addView(locationItem);
}
}
public void countRecords(){
int recordCount = new TableControllerAppointments(this).count();
TextView textViewRecordCount = findViewById(R.id.textViewRecordCount);
textViewRecordCount.setText(recordCount + " records found.");
}
}
Database Handler Class
package ie.app.barbershop;
import android.database.sqlite.SQLiteOpenHelper;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
public class DatabaseHandler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
protected static final String DATABASE_NAME = "AppointmentDatabase";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE appointments " +
"( id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"fullname TEXT, " +
"contactno NUMBER ) ";
db.execSQL(sql);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String sql = "DROP TABLE IF EXISTS students";
db.execSQL(sql);
onCreate(db);
}
}
The -1 is being returned from getColumnIndex meaning that the column firstname
doesn't exist in the cursor in the following line.
String fullName = cursor.getString(cursor.getColumnIndex("firstname"));
You create the table using :-
String sql = "CREATE TABLE appointments " +
"( id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"fullname TEXT, " +
"contactno NUMBER ) ";
Where the columns are id fullname and contactno.
--
Fix
To fix this change to use :-
String fullName = cursor.getString(cursor.getColumnIndex("fullname"));
Additional
Better still define column and tables names as constants and always refer to them.
e.g.
public class DatabaseHandler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
protected static final String DATABASE_NAME = "AppointmentDatabase";
public static final String TABLE_NAME = "appointments";
public static final String COL_ID = "id";
public static final String COl_FULLNAME = "fullname";
public static final String COL_CONTACTNO = "contactno";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE " + TABLE_NAME +
"( " + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COL_FULLNAME + " TEXT, " +
COL_CONTACTNO + " NUMBER ) ";
db.execSQL(sql);
}
.... and so on
and later as one example :-
String fullName = cursor.getString(cursor.getColumnIndex(DatabaseHandler.COL_FULLNAME));
Error is popping up for me where its telling me a column of mine does not exist. This column exists within my Contract class for my database but for some reason isn't recognized by the cursor.
LOGCAT
03-16 16:37:29.029 8240-8240/com.compscitutorials.basigarcia.ramfernoscout E/SQLiteLog: (1) no such column: TEAM_NUMBER
03-16 16:37:29.030 8240-8240/com.compscitutorials.basigarcia.ramfernoscout D/AndroidRuntime: Shutting down VM
03-16 16:37:29.030 8240-8240/com.compscitutorials.basigarcia.ramfernoscout E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.compscitutorials.basigarcia.ramfernoscout, PID: 8240
android.database.sqlite.SQLiteException: no such column: TEAM_NUMBER (code 1): , while compiling: SELECT TEAM_NUMBER, PORTCULLIS, CHEVAL_DE_FRISE, MOAT, RAMPARTS, DRAWBRIDGE, SALLY_PORT, ROCK_WALL, ROCK_TERRAIN, LOW_BAR FROM scout_table
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:887)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:498)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1316)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1163)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1034)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1202)
at com.compscitutorials.basigarcia.ramfernoscout.DatabaseHelper.getInformation(DatabaseHelper.java:63)
at com.compscitutorials.basigarcia.ramfernoscout.ScoutFragment.onCreateView(ScoutFragment.java:40)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
DatabaseHelper.java
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 DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "Scout.db";
private static final int DATABASE_VERSION = 1;
private static final String CREATE_QUERY = "CREATE TABLE " + DatabaseContract.NewDataInfo.TABLE_NAME + "(" + DatabaseContract.NewDataInfo.COL_NUMBER +
" INTEGER," + DatabaseContract.NewDataInfo.COL_PORTCULLIS + " TEXT," + DatabaseContract.NewDataInfo.COL_CHEVAL_FRISE + " TEXT," +
DatabaseContract.NewDataInfo.COL_MOAT + " TEXT," + DatabaseContract.NewDataInfo.COL_RAMPARTS + " TEXT," + DatabaseContract.NewDataInfo.COL_DRAWBRIDGE +
" TEXT," + DatabaseContract.NewDataInfo.COL_SALLY_PORT + " TEXT," + DatabaseContract.NewDataInfo.COL_ROCK_WALL + " TEXT," +
DatabaseContract.NewDataInfo.COL_ROCK_TERRAIN + " TEXT," + DatabaseContract.NewDataInfo.COL_LOW_BAR + " TEXT);";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Log.e("DATABASE OPERATIONS", "Database created / opened ...");
} //End of DatabaseHelper
#Override
public void onCreate(SQLiteDatabase db) {
//Create Query
db.execSQL(CREATE_QUERY);
//Display Log message
Log.e("DATABASE OPERATIONS", "Table created...");
} //End of onCreate
public void addInformation(String eNumber, String ePoticullis, String eChevalFrise, String eMoat, String eRamparts, String eDrawbridge, String eSallyPort,
String eRockWall, String eRockTerrain, String eLowBar, SQLiteDatabase db) {
//Instantiate contentValues
ContentValues contentValues = new ContentValues();
//Insert all content values
contentValues.put(DatabaseContract.NewDataInfo.COL_NUMBER, eNumber);
contentValues.put(DatabaseContract.NewDataInfo.COL_PORTCULLIS, ePoticullis);
contentValues.put(DatabaseContract.NewDataInfo.COL_CHEVAL_FRISE, eChevalFrise);
contentValues.put(DatabaseContract.NewDataInfo.COL_MOAT, eMoat);
contentValues.put(DatabaseContract.NewDataInfo.COL_RAMPARTS, eRamparts);
contentValues.put(DatabaseContract.NewDataInfo.COL_DRAWBRIDGE, eDrawbridge);
contentValues.put(DatabaseContract.NewDataInfo.COL_SALLY_PORT, eSallyPort);
contentValues.put(DatabaseContract.NewDataInfo.COL_ROCK_WALL, eRockWall);
contentValues.put(DatabaseContract.NewDataInfo.COL_ROCK_TERRAIN, eRockTerrain);
contentValues.put(DatabaseContract.NewDataInfo.COL_LOW_BAR, eLowBar);
//Insert content values into table
db.insert(DatabaseContract.NewDataInfo.TABLE_NAME, null, contentValues);
//Display log message
Log.e("DATABASE OPERATIONS", "One row inserted...");
} //End of addInformation
public Cursor getInformation(SQLiteDatabase db){
Cursor cursor;
String[] projections = {DatabaseContract.NewDataInfo.COL_NUMBER, DatabaseContract.NewDataInfo.COL_PORTCULLIS,
DatabaseContract.NewDataInfo.COL_CHEVAL_FRISE, DatabaseContract.NewDataInfo.COL_MOAT,DatabaseContract.NewDataInfo.COL_RAMPARTS,
DatabaseContract.NewDataInfo.COL_DRAWBRIDGE, DatabaseContract.NewDataInfo.COL_SALLY_PORT, DatabaseContract.NewDataInfo.COL_ROCK_WALL,
DatabaseContract.NewDataInfo.COL_ROCK_TERRAIN, DatabaseContract.NewDataInfo.COL_LOW_BAR};
cursor = db.query(DatabaseContract.NewDataInfo.TABLE_NAME, projections, null, null, null, null, null);
return cursor;
} //End of getInformation
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
} //End of onUpgrade
} //End of class
ScoutFragment.java
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
/**
* A simple {#link Fragment} subclass.
*/
public class ScoutFragment extends Fragment {
FloatingActionButton addDataScout;
ListView eListScoutInfo;
SQLiteDatabase sqLiteDatabase;
DatabaseHelper databaseHelper;
Cursor cursor;
ListScoutInfoAdapter listScoutInfoAdapter;
public ScoutFragment() {
// Required empty public constructor
} //End of ScoutFragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_scout, null, false);
view.setBackgroundColor(Color.WHITE);
eListScoutInfo = (ListView) view.findViewById(R.id.listScoutInfo);
listScoutInfoAdapter = new ListScoutInfoAdapter(getActivity().getApplicationContext(), R.layout.row_layout);
eListScoutInfo.setAdapter(listScoutInfoAdapter);
databaseHelper = new DatabaseHelper(getActivity().getApplicationContext());
sqLiteDatabase = databaseHelper.getReadableDatabase();
cursor = databaseHelper.getInformation(sqLiteDatabase);
//Checks if information is available in cursor
if(cursor.moveToFirst()){
do {
//Delcare all strings
String teamNumber, portcullis, chevalFrise, moat, ramparts, drawbridge, sallyPort, rockWall, rockTerrain, lowBar;
//Get strings from cursor
teamNumber = cursor.getString(0);
portcullis = cursor.getString(1);
chevalFrise = cursor.getString(2);
moat = cursor.getString(3);
ramparts = cursor.getString(4);
drawbridge = cursor.getString(5);
sallyPort = cursor.getString(6);
rockWall = cursor.getString(7);
rockTerrain = cursor.getString(8);
lowBar = cursor.getString(9);
//Get methods from DatabaseProvider
DatabaseProvider databaseProvider = new DatabaseProvider(teamNumber, portcullis, chevalFrise, moat, ramparts,
drawbridge, sallyPort, rockWall, rockTerrain, lowBar);
//Pass objects to add method
listScoutInfoAdapter.add(databaseProvider);
} while (cursor.moveToNext());
} //End of if statement
//Setups Floating Action Button
addDataScout = (FloatingActionButton) view.findViewById(R.id.fab);
addDataScout.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
AddScoutDataFragment fragment = new AddScoutDataFragment();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.commit();
} //End of onClick
}); //End of setOnClickListener
return view;
} //End of onCreateView
} //End of class
DatabaseContract.java
public class DatabaseContract {
public static abstract class NewDataInfo {
public static final String TABLE_NAME = "scout_table";
public static final String COL_NUMBER = "TEAM_NUMBER";
public static final String COL_PORTCULLIS = "PORTCULLIS";
public static final String COL_CHEVAL_FRISE = "CHEVAL_DE_FRISE";
public static final String COL_MOAT = "MOAT";
public static final String COL_RAMPARTS = "RAMPARTS";
public static final String COL_DRAWBRIDGE = "DRAWBRIDGE";
public static final String COL_SALLY_PORT = "SALLY_PORT";
public static final String COL_ROCK_WALL = "ROCK_WALL";
public static final String COL_ROCK_TERRAIN = "ROCK_TERRAIN";
public static final String COL_LOW_BAR = "LOW_BAR";
} //End of NewDataInfo
} //End of class
As discussed you should clear the app data if it still in development as you created the database before without this column, if it in the production phase you should do such upgrades in OnUpgrad method.
The aim is to retrieve the car park names from the car park tables columns 'CPNAME' and put those rows of names in another class' arraylist which a spinner will display.
The problem is apparently with my getCpNames() method, specifically on this line:
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, KEY_CPNAME, null, null, null,
null);
The errors I get on LogCat:
Caused by: java.lang.NullPointerException
at com.example.parkangel.DbHelper.getCpnames(DbHelper.java:93)
at com.example.parkangel.BookTicket.<init>(BookTicket.java:19)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2112)
My database class code:
package com.example.parkangel;
import java.util.ArrayList;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DbHelper extends SQLiteOpenHelper
{
private static DbHelper dbHelper;
private Context ourContext;
private static DbHelper instance;
private static SQLiteDatabase ourDatabase;
private static final String DATABASE_NAME = "CPDB.db";
private static final String DATABASE_TABLE = "CPTable";
private static final int DATABASE_VERSION = 1;
public static final String KEY_ID = "_id";
public static final String KEY_CPNAME = "cpname";
public static final String KEY_COST = "cost";
public DbHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
this.ourContext = context;
}
public static DbHelper getInstance(Context context)
{
if (instance == null)
{
instance = new DbHelper(context);
}
return instance;
}
#Override
public void onCreate(SQLiteDatabase db)
{
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" +
KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_CPNAME + " TEXT NOT NULL, " + KEY_COST + " TEXT NOT NULL);");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values ('1','Learning
Resource Center','2');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values ('2','Park and
Ride','1');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values ('3','de
Havilland Campus','2');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values ('4','Multi
Storey Building','2');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values
('5','Reception','2');");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
public synchronized DbHelper open() throws SQLException
{
System.out.println ("running open");
if(ourDatabase == null || !ourDatabase.isOpen());
this.ourDatabase = getWritableDatabase();
return this;
}
public static String[] getCpnames()
{
String[] columns = new String[] {KEY_ID, KEY_CPNAME, KEY_COST};
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, KEY_CPNAME,
null, null, null, null);
ArrayList<String> list = new ArrayList<String>();
if (c != null)
{
c.moveToFirst();
do
{
list.add(c.getString(0));
}
while (c.moveToNext());
}
if (ourDatabase == null) System.out.println ("is null");
return list.toArray(new String[]{});
}
}
This is the class and arraylist I am calling getCpnames() into:
package com.example.parkangel;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
public class BookTicket extends Activity implements OnClickListener{
Spinner spinner, spinner2;
DbHelper dbhelper = DbHelper.getInstance(this);
String[] carParks = DbHelper.getCpnames();
I am beginner, so apologies for any amateur mistakes. Thank you in advance!
You never called DbHelper.open();
BTW, I also see a potential problem here
public synchronized DbHelper open() throws SQLException
{
System.out.println ("running open");
if(ourDatabase == null || !ourDatabase.isOpen());
this.ourDatabase = getWritableDatabase();
return this;
}
especially on this line
if(ourDatabase == null || !ourDatabase.isOpen());
The semicolon ";" at the end of line makes the if statement ineffective
The most likely explanation is that ourDatabase is null. You failed to call DBHelper.open() to set it.
Kohli.java
package com.kohli;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.content.Context;
public class KohlifActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("KOHLIActivity", "qwert11111111");
setContentView(R.layout.main);
Log.i("KOHILActivity", "qwert22222222222");
DbHelper1 DbHelper=new DbHelper1(this) ;
Log.i("KOHLIfActivity", "qwert3333333333");
}
}
DbHelper1.java
package com.kohli;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.BaseColumns;
import android.util.Log;
public class DbHelper1 extends SQLiteOpenHelper
{
static final String TAG = "DbHelper1";
static final String DB_NAME = "timeline.db";
static final int DB_VERSION = 1;
static final String TABLE = "timeline";
static final String C_ID = BaseColumns._ID;
static final String C_CREATED_AT = "created_at";
static final String C_SOURCE = "source";
static final String C_TEXT = "txt";
static final String C_USER = "user";
Context context;
public DbHelper1(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.context = context;
Log.d(TAG, "constructor111111");
//System.out.println("dbhelper constructor");
}
// Called only once, first time the DB is created
public void onCreate(SQLiteDatabase db) {
String sql = "create table " + TABLE + " (" + C_ID + " int primary key, "
+ C_CREATED_AT + " int, " + C_USER + " text, " + C_TEXT + " text)";
db.execSQL(sql);
Log.d(TAG, "onCreated sql:22222222 ");
//System.out.println("dbhelper oncreate");
}
// Called whenever newVersion != oldVersion
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Typically do ALTER TABLE statements, but...we're just in development,
// so:
db.execSQL("drop table if exists " + TABLE); // drops the old database
Log.d(TAG, "onUpdated 33333333");
//System.out.println("dbhelper onupgrade");
onCreate(db); // run onCreate to get new database
}
}
i wrote the following code to make a database with a table... the output at logcat is :: qwert111111 qwert22222 constructor111111 qwert3333 .. that is the oncreate function is not being called so the database is also not created...
The database isn't actually created until you call getWritableDatabase() on the
dbHelper object.