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.
Related
I'm having this error when I try to update/edit the Sqlite database java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 can any on helping me.
when I try to delete the existing data from the database it works. But when I try to update or edit the existing data from the database, it does not work and the app crashes.
when I check the database inspector then I find one thing that when I try to edit the table data on the database the Class_table will gone or you can say delete automatically. and I don't find any solution for this problem can anyone help me plz.
Here is the error code:
Process: com.example.attendance, PID: 20112
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.get(ArrayList.java:437)
at com.example.attendance.MainActivity.updateClass(MainActivity.java:135)
at com.example.attendance.MainActivity.lambda$showUpdateDialog$4$MainActivity(MainActivity.java:131)
at com.example.attendance.-$$Lambda$MainActivity$m9twlugKZZaVnr6kCG8LrRCoXMM.onClick(Unknown Source:4)
at com.example.attendance.MyDialog.lambda$getUpdateClassDialog$1$MyDialog(MyDialog.java:94)
at com.example.attendance.-$$Lambda$MyDialog$5v1iqgaO8riJO2phwUfadWXdoyM.onClick(Unknown Source:6)
at android.view.View.performClick(View.java:8160)
at android.widget.TextView.performClick(TextView.java:16222)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:8137)
at android.view.View.access$3700(View.java:888)
at android.view.View$PerformClick.run(View.java:30236)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:246)
at android.app.ActivityThread.main(ActivityThread.java:8512)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
I/Process: Sending signal. PID: 20112 SIG: 9
Here is My Activity:
package com.example.attendance;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toolbar;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
FloatingActionButton floatingActionButton;
RecyclerView recyclerView;
ClassAdapter classAdapter;
RecyclerView.LayoutManager layoutManager;
ArrayList<ClassItem> classItems = new ArrayList<>();
Toolbar toolbar;
DbHelper dbHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new DbHelper(this);
floatingActionButton = findViewById(R.id.fab_main);
floatingActionButton.setOnClickListener(V -> showDialog());
loadData();
recyclerView = findViewById(R.id.att_list);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
classAdapter = new ClassAdapter(this, classItems);
recyclerView.setAdapter(classAdapter);
classAdapter.setOnItemClickListener(position -> gotoItemActivity(position));
setToolbar();
}
private void loadData() {
Cursor cursor = dbHelper.getClassTable();
classItems.clear();
while (cursor.moveToNext()){
int id = cursor.getInt(cursor.getColumnIndex(DbHelper.C_ID));
String department = cursor.getString(cursor.getColumnIndex(DbHelper.CLASS_NAME_KEY));
String subject = cursor.getString(cursor.getColumnIndex(DbHelper.SUBJECT_NAME_KEY));
classItems.add(new ClassItem(id,department,subject));
}
}
private void setToolbar() {
toolbar = findViewById(R.id.toolbar);
TextView title = toolbar.findViewById(R.id.tool_title);
TextView subTitle = toolbar.findViewById(R.id.tool_sub_title);
TextView samiTitle = toolbar.findViewById(R.id.tool_sami_title);
ImageButton back = toolbar.findViewById(R.id.tool_back);
ImageButton save = toolbar.findViewById(R.id.tool_save);
title.setText("Attendance");
subTitle.setVisibility(View.GONE);
samiTitle.setVisibility(View.GONE);
save.setVisibility(View.GONE);
back.setOnClickListener(v -> onBackPressed());
}
private void gotoItemActivity(int position) {
Intent intent = new Intent(this,StudentActivity.class);
intent.putExtra("departmentName",classItems.get(position).getDepartment());
intent.putExtra("subjectName",classItems.get(position).getSubject());
intent.putExtra("position",position);
startActivity(intent);
}
private void showDialog() {
MyDialog dialog = new MyDialog();
dialog.show(getSupportFragmentManager(),MyDialog.CLASS_ADD_DIALOG);
dialog.setListener((department,subject)->addClass(department,subject));
}
private void addClass(String department, String subject) {
long cid = dbHelper.addClass(department,subject);
ClassItem classItem = new ClassItem(cid,department,subject);
classItems.add(classItem);
classAdapter.notifyDataSetChanged();
}
#Override
public boolean onContextItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case 0:
showUpdateDialog(item.getGroupId());
case 1:
deleteClass(item.getGroupId());
}
return super.onContextItemSelected(item);
}
private void showUpdateDialog(int position) {
MyDialog updateDialog = new MyDialog();
updateDialog.show(getSupportFragmentManager(),MyDialog.CLASS_UPDATE_DIALOG);
updateDialog.setListener((department,subject)->updateClass(position,department,subject));
}
// when I try to Update the Data its don't work and the app will crash
private void updateClass(int position, String department, String subject) {
dbHelper.updateClass(classItems.get(position).getCid(),department,subject);
classItems.get(position).setDepartment(department);
classItems.get(position).setSubject(subject);
classAdapter.notifyItemChanged(position);
}
private void deleteClass(int position) {
dbHelper.deleteClass(classItems.get(position).getCid());
classItems.remove(position);
classAdapter.notifyItemRemoved(position);
}
}
Here is my Adepter
package com.example.attendance;
import android.content.Context;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class ClassAdapter extends RecyclerView.Adapter<ClassAdapter.ClassViewHolder> {
private OnItemClickListener onItemClickListener;
public interface OnItemClickListener {
void onClick(int position);
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public ClassAdapter(Context context, ArrayList<ClassItem> classItems) {
this.classItems = classItems;
this.context = context;
}
ArrayList<ClassItem> classItems;
Context context;
public static class ClassViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener {
TextView department, subject;
public ClassViewHolder(#NonNull View itemView,OnItemClickListener onItemClickListener) {
super(itemView);
department = itemView.findViewById(R.id.dep_tv);
subject = itemView.findViewById(R.id.sub_tv);
itemView.setOnClickListener(v -> onItemClickListener.onClick(getAdapterPosition()));
itemView.setOnCreateContextMenuListener(this);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.add(getAdapterPosition(),0,0,"EDIT");
menu.add(getAdapterPosition(),1,0,"DELETE");
}
}
#NonNull
#Override
public ClassViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.class_item, parent, false);
return new ClassViewHolder(itemView, onItemClickListener);
}
#Override
public void onBindViewHolder(#NonNull ClassViewHolder holder, int position) {
holder.department.setText(classItems.get(position).getDepartment());
holder.subject.setText(classItems.get(position).getSubject());
}
#Override
public int getItemCount() {
return classItems.size();
}
}
Here is Database
package com.example.attendance;
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 androidx.annotation.Nullable;
public class DbHelper extends SQLiteOpenHelper {
private static final int VERSION = 1;
//Class table
private static final String CLASS_TABLE_NAME= "CLASS_TABLE";
public static final String C_ID= "_CID";
public static final String CLASS_NAME_KEY= "CLASS_NAME";
public static final String SUBJECT_NAME_KEY= "SUBJECT_NAME";
private static final String CREATE_CLASS_TABLE=
"CREATE TABLE " + CLASS_TABLE_NAME + "(" +
C_ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
CLASS_NAME_KEY + " TEXT NOT NULL, " +
SUBJECT_NAME_KEY + " TEXT NOT NULL, " +
" UNIQUE ( " + CLASS_NAME_KEY + "," + SUBJECT_NAME_KEY + ")" +
");";
private static final String DROP_CLASS_TABLE = "DROP TABLE IF EXISTS "+CLASS_TABLE_NAME;
private static final String SELECT_CLASS_TABLE = "SELECT * FROM "+CLASS_TABLE_NAME;
//Student table
private static final String STUDENT_TABLE_NAME= "STUDENT_TABLE";
private static final String S_ID= "_SID";
private static final String STUDENT_NAME_KEY= "STUDENT_NAME";
private static final String STUDENT_ROLL_KEY= "ROLL";
private static final String CREATE_STUDENT_TABLE=
"CREATE TABLE "+ STUDENT_TABLE_NAME +
"( "+
S_ID+ " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "+
C_ID + " TEXT NOT NULL, "+
STUDENT_NAME_KEY + " TEXT NOT NULL, "+
STUDENT_ROLL_KEY + " INTEGER, "+
" FOREIGN KEY ( "+C_ID+ " ) REFERENCES "+ CLASS_TABLE_NAME + "("+C_ID+")"+
");";
private static final String DROP_STUDENT_TABLE = "DROP TABLE IF EXISTS "+STUDENT_TABLE_NAME;
private static final String SELECT_STUDENT_TABLE = "SELECT * FROM "+STUDENT_TABLE_NAME;
//Status table
private static final String STATUS_TABLE_NAME= "STATUS_TABLE";
private static final String STATUS_ID= "_STATUS_ID";
private static final String DATE_KEY= "STATUS_NAME";
private static final String STATUS_KEY= "STATUS";
private static final String CREATE_STATUS_TABLE=
"CREATE TABLE "+STATUS_TABLE_NAME+
"("+
STATUS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "+
S_ID + " INTEGER NOT NULL, "+
DATE_KEY + " DATE NOT NULL, "+
STATUS_KEY + " TEXT NOT NULL, "+
" UNIQUE ( " + S_ID + "," + DATE_KEY + ")," +
" FOREIGN KEY ( "+ S_ID+ " ) REFERENCES "+ STUDENT_TABLE_NAME + "( "+S_ID+")"+
");";
private static final String DROP_STATUS_TABLE = "DROP TABLE IF EXISTS "+ STATUS_TABLE_NAME;
private static final String SELECT_STATUS_TABLE = "SELECT * FROM "+ STATUS_TABLE_NAME;
public DbHelper(#Nullable Context context) {
super(context, "Attendance.db", null, VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_CLASS_TABLE);
db.execSQL(CREATE_STUDENT_TABLE);
db.execSQL(CREATE_STATUS_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
db.execSQL(DROP_CLASS_TABLE);
db.execSQL(DROP_STUDENT_TABLE);
db.execSQL(DROP_STATUS_TABLE);
} catch (SQLException e) {
e.printStackTrace();
}
}
long addClass(String className,String subjectName){
SQLiteDatabase database = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(CLASS_NAME_KEY,className);
values.put(SUBJECT_NAME_KEY,subjectName);
return database.insert(CLASS_TABLE_NAME,null,values);
}
Cursor getClassTable(){
SQLiteDatabase database = this.getReadableDatabase();
return database.rawQuery(SELECT_CLASS_TABLE,null);
}
int deleteClass(long cid){
SQLiteDatabase database = this.getReadableDatabase();
return database.delete(CLASS_TABLE_NAME,C_ID+"=?",new String[]{String.valueOf(cid)});
}
long updateClass(long cid,String className,String subjectName){
SQLiteDatabase database = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(CLASS_NAME_KEY,className);
values.put(SUBJECT_NAME_KEY,subjectName);
return database.update(CLASS_TABLE_NAME,values,C_ID+"=?",new String[]{String.valueOf(cid)});
}
}
After dropping your tables, you forgot to create them again in your onUpgrade method.
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
db.execSQL(DROP_CLASS_TABLE);
db.execSQL(DROP_STUDENT_TABLE);
db.execSQL(DROP_STATUS_TABLE);
onCreate(db);
} catch (SQLException e) {
e.printStackTrace();
}
}
Also it is a good idea to call .close() method every time you call .getWritableDatabase() or .getReadableDatabase(). Here is an example ...
long addClass(String className, String subjectName){
SQLiteDatabase database = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(CLASS_NAME_KEY,className);
values.put(SUBJECT_NAME_KEY,subjectName);
database.close();
long id = database.insert(CLASS_TABLE_NAME,null,values);
return id;
}
Hope it helps, happy coding!
The issue is in your MainActivity.class and StudentActivity.class.
In your onContextItemSelected(#NonNull MenuItem item) method, you forgot to break; your switch statement.
#Override
public boolean onContextItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case 0:
showUpdateDialog(item.getGroupId());
break;
case 1:
deleteClass(item.getGroupId());
break;
} return true;
}
Also, instead of adding classItems or studentItems to their respective ArrayLists after updating or deleting data in your SQLite Database, just call loadData() method again!
private void deleteClass(int position) {
dbHelper.deleteClass(classItems.get(position).getCid());
loadData();
classAdapter.notifyDataSetChanged();
}
private void updateClass(int position, String department, String subject) {
dbHelper.updateClass(classItems.get(position).getCid(),department,subject);
loadData();
classAdapter.notifyDataSetChanged();
}
The same thing applies to your StudentActivity.class. Happy Coding!
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));
So after editing a method in my MainAcivity, I'm getting a RuntimeException.
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tim.timapp
/com.example.tim.timapp.MainActivity}: java.lang.IllegalStateException:
Activity has been destroyed
I honestly have no idea where this is coming from. Searching online suggests that it's a big with the ChildFragmentManager, but doesn't give me a fix that works for me.
Any idea what I can do to fix this exception?
PS. If you need any more code or info, let me know. My mind is quite flustered by this error, so I might overlooked some stuff here.
Full log:
03-30 21:19:47.910 24785-24785/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.tim.timapp, PID: 24785
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tim.timapp/com.example.tim.timapp.MainActivity}: java.lang.IllegalStateException: Activity has been destroyed
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
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)
Caused by: java.lang.IllegalStateException: Activity has been destroyed
at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1433)
at android.app.BackStackRecord.commitInternal(BackStackRecord.java:687)
at android.app.BackStackRecord.commit(BackStackRecord.java:663)
at com.example.tim.timapp.MainActivity.DrawVariableFragments(MainActivity.java:271)
at com.example.fragments.Settings.GeneralSettingsFragment.onCreateView(GeneralSettingsFragment.java:57)
at android.app.Fragment.performCreateView(Fragment.java:2220)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:973)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1148)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1130)
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1953)
at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:152)
at android.app.Activity.performCreateCommon(Activity.java:6232)
at android.app.Activity.performCreate(Activity.java:6239)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
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)
MainActivity (Sorry about the mess, it's a WIP):
Sorry about this, but I went over the 30.000 characters limit with the entire file.
http://pastebin.com/XZ9k995G
DBHandler (Was giving me grief earlier, so might have something to do with it):
package com.example.tim.timapp;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.util.Log;
import java.util.ArrayList;
public class DBHandler extends SQLiteOpenHelper {
private static String tag = "TEST DBHandler";
private static DBHandler sInstance;
// Database Stuff
private static final int DATABASE_VERSION = 6;
private static final String DATABASE_NAME = "LinkDatabase.db";
// Table Stuff
private static final String TABLE_LinkTable = "LinkTable";
private static final String TABLE_SettingsTable = "SettingsTable";
// LinkTable Stuff
private static final String LT_COLUMN_ID = "_id";
private static final String LT_COLUMN_NAME = "name";
private static final String LT_COLUMN_TAG = "tag";
// SettingsTable Stuff
private static final String ST_COLUMN_ID = "_id";
private static final String ST_COLUMN_NAME = "name";
private static final String ST_COLUMN_IP = "ip";
private static final String ST_COLUMN_PORT = "port";
private static final String ST_COLUMN_USERNAME = "username";
private static final String ST_COLUMN_PASS = "pass";
// Table Create Statements
// LinkTable Create Statement
private static final String CREATE_TABLE_LINKS =
"CREATE TABLE " + TABLE_LinkTable + "(" +
LT_COLUMN_ID + " INTEGER PRIMARY KEY, " +
LT_COLUMN_NAME + " TEXT, " +
LT_COLUMN_TAG + " TEXT" + ");";
// SettingsTable Create Statement
private static final String CREATE_TABLE_SETTINGS =
"CREATE TABLE " + TABLE_SettingsTable + "(" +
ST_COLUMN_ID + " INTEGER PRIMARY KEY, " +
ST_COLUMN_NAME + " TEXT, " +
ST_COLUMN_IP + " TEXT, " +
ST_COLUMN_PORT + " TEXT, " +
ST_COLUMN_USERNAME + " TEXT, " +
ST_COLUMN_PASS + " TEXT" + ");";
// TODO: 28-Mar-16 DON"T FORGET TO UPDATE
// Don't forget to update this when adding a new table.
private static final ArrayList<String> createTablesArray = new ArrayList<String>() {{add(CREATE_TABLE_LINKS); add(CREATE_TABLE_SETTINGS);}};
private static final ArrayList<String> tableNamesArray = new ArrayList<String>() {{add(TABLE_LinkTable); add(TABLE_SettingsTable);}};
public ArrayList<String> tagArray;
public static synchronized DBHandler getInstance(Context context) {
if (sInstance == null) {
Log.d(tag, "sInstance == null");
sInstance = new DBHandler(context.getApplicationContext());
}
return sInstance;
}
private DBHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
for (String s : createTablesArray) {
db.execSQL(s);
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
for (String s : tableNamesArray) {
db.execSQL("DROP TABLE IF EXISTS " + s);
}
onCreate(db);
}
public ArrayList<String> returnArray(String base, String column) {
SQLiteDatabase db;
db = getWritableDatabase();
String TABLENAME;
if (base.equalsIgnoreCase("StuffManager")) {
TABLENAME = TABLE_LinkTable;
} else if (base.equalsIgnoreCase("GeneralSettings")) {
TABLENAME = TABLE_SettingsTable;
} else {
Log.e(tag, "String Base not recognised");
return null;
}
String query = "SELECT * FROM " + TABLENAME + " WHERE 1";
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
ArrayList<String> tempArray = new ArrayList<>();
int i = 0;
while(!c.isAfterLast()){
if(c.getString(c.getColumnIndex(column)) != null){
tempArray.add(i, c.getString(c.getColumnIndex(column)));
} else {
Log.e(tag, "String Column not recognised");
return null;
}
c.moveToNext();
i++;
}
c.close();
if (db != null && db.isOpen()) {
db.close();
}
return tempArray;
}
// *** --------- ***
//
// All methods for the SETTINGS_TABLES
//
// *** --------- ***
public void addSettings(String name, String ip, String port, String username, String pass) {
ContentValues values = new ContentValues();
values.put(ST_COLUMN_NAME, name);
values.put(ST_COLUMN_IP, ip);
values.put(ST_COLUMN_PORT, port);
values.put(ST_COLUMN_USERNAME, username);
values.put(ST_COLUMN_PASS, pass);
SQLiteDatabase db;
db = getWritableDatabase();
db.insert(TABLE_SettingsTable, null, values);
db.close();
}
public void updateSettings(int id, String name, String ip, String port, String username, String pass) {
ContentValues values = new ContentValues();
values.put(ST_COLUMN_NAME, name);
values.put(ST_COLUMN_IP, ip);
values.put(ST_COLUMN_PORT, port);
values.put(ST_COLUMN_USERNAME, username);
values.put(ST_COLUMN_PASS, pass);
SQLiteDatabase db;
db = getWritableDatabase();
db.update(TABLE_SettingsTable, values, "_id=" + id, null);
db.close();
}
public void deleteSettings(String name) {
SQLiteDatabase db;
db = getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_SettingsTable + " WHERE " + ST_COLUMN_NAME + "=\"" + name + "\";");
db.close();
}
public void deleteAllSettings() {
SQLiteDatabase db;
db = getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_SettingsTable + " WHERE 1");
db.close();
}
public float settingsTableSize() {
SQLiteDatabase db;
db = getReadableDatabase();
float amount = DatabaseUtils.queryNumEntries(db, TABLE_SettingsTable);
db.close();
return amount;
}
public ArrayList<String> settingsNameArrayMethod() {
SQLiteDatabase db;
db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_SettingsTable + " WHERE 1";
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
int i = 0;
ArrayList<String> nameArray = new ArrayList<>();
while (!c.isAfterLast()) {
if (c.getString(c.getColumnIndex("name")) != null) {
nameArray.add(i, c.getString(c.getColumnIndex("name")));
}
c.moveToNext();
i++;
}
c.close();
db.close();
return nameArray;
}
// *** --------- ***
//
// All methods for the LINK_TABLES
//
// *** --------- ***
public void addStuffLink(String name, String tag) {
ContentValues values = new ContentValues();
values.put(LT_COLUMN_NAME, name);
values.put(LT_COLUMN_TAG, tag);
SQLiteDatabase db;
db = getWritableDatabase();
db.insert(TABLE_LinkTable, null, values);
db.close();
}
public Bundle updateStuffLink(int id, String name, String tag) {
ContentValues values = new ContentValues();
values.put(LT_COLUMN_NAME, name);
values.put(LT_COLUMN_TAG, tag);
SQLiteDatabase db;
db = getWritableDatabase();
db.update(TABLE_LinkTable, values, "_id=" + id, null);
db.close();
ArrayList<String> nameArray = stuffLinksNameArrayMethod();
ArrayList<String> tagArray = tagArrayMethod();
Bundle bundle = new Bundle();
bundle.putStringArrayList("nameArray", nameArray);
bundle.putStringArrayList("tagArray", tagArray);
return bundle;
}
public void deleteStuffLink(String name) {
SQLiteDatabase db;
db = getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_LinkTable + " WHERE " + LT_COLUMN_NAME + "=\"" + name + "\";");
db.close();
}
public void deleteAllStuffLinks() {
SQLiteDatabase db;
db = getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_LinkTable + " WHERE 1");
db.close();
}
public ArrayList<String> stuffLinksNameArrayMethod(){
SQLiteDatabase db;
db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_LinkTable + " WHERE 1";
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
int i = 0;
ArrayList<String> nameArray = new ArrayList<>();
tagArray = new ArrayList<>();
while(!c.isAfterLast()){
if(c.getString(c.getColumnIndex("name")) != null){
nameArray.add(i, c.getString(c.getColumnIndex("name")));
tagArray.add(i, c.getString(c.getColumnIndex("tag")));
}
c.moveToNext();
i++;
}
c.close();
db.close();
return nameArray;
}
public ArrayList<String> tagArrayMethod() {
stuffLinksNameArrayMethod();
return tagArray;
}
public float stuffTableSize(){
SQLiteDatabase db;
db = getReadableDatabase();
float amount = DatabaseUtils.queryNumEntries(db, TABLE_LinkTable);
db.close();
return amount;
}
}
GeneralSettingsFragment
package com.example.fragments.Settings;
import android.app.AlertDialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import com.example.fragments.MainFragments.DialogFragments.GeneralSettingsInitialInputDialog;
import com.example.fragments.MainFragments.VariableFragments.GeneralSettingsEmptyFragment;
import com.example.fragments.MainFragments.VariableFragments.GeneralSettingsVariableFragment;
import com.example.fragments.MainFragments.VariableFragments.StuffManagerVariableFragment;
import com.example.tim.timapp.DBHandler;
import com.example.tim.timapp.MainActivity;
import com.example.tim.timapp.R;
import java.util.ArrayList;
public class GeneralSettingsFragment extends Fragment {
DBHandler dbHandler;
MainActivity ma = new MainActivity();
private static Menu optionsMenu;
public static boolean hideDeleteAllButton = false;
LinearLayout linearLayout;
View rootView;
#Override
public void onCreate(Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_generalsettings, container, false);
linearLayout = (LinearLayout) rootView.findViewById(R.id.FragmentContainerGeneralSettings);
if (linearLayout == null) {
Log.e("GMF", "Layout is null");
} else if (linearLayout.getChildCount() == 0) {
GeneralSettingsInitialInputDialog GSIID = new GeneralSettingsInitialInputDialog();
GSIID.show(getFragmentManager(), "dialog");
hideDeleteAllButton = true;
} else {
hideDeleteAllButton = false;
}
ma.DrawVariableFragments("GeneralSettings", "draw");
return rootView;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.stuffmanager_actionbuttons, menu);
optionsMenu = menu;
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
optionsMenu.findItem(R.id.removeAllButton).setVisible(!hideDeleteAllButton);
super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.addButton:
GeneralSettingsInitialInputDialog GSIID = new GeneralSettingsInitialInputDialog();
GSIID.show(getFragmentManager(), "dialog");
return true;
case R.id.removeAllButton:
dbHandler = DBHandler.getInstance(getActivity());
final ArrayList<String> nameArray = dbHandler.settingsNameArrayMethod();
final FragmentManager fm = getFragmentManager();
AlertDialog.Builder removeAllDialog = new AlertDialog.Builder(getActivity())
.setTitle("Delete all?")
.setMessage("Are you sure you want to delete all your devices? This is irreversible.")
.setIcon(R.drawable.ic_delete_black)
.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dbHandler.deleteAllSettings();
for (String name : nameArray){
fm.beginTransaction().remove(fm.findFragmentByTag(name)).commit();
}
fm.executePendingTransactions();
// TODO: 30-Mar-16 Add "No devices created" screen like stuffmanager
hideDeleteAllButton = true;
getActivity().invalidateOptionsMenu();
}
})
.setNegativeButton("Cancel", null);
removeAllDialog.show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
MainActivity ma = new MainActivity();
This isn't valid in Android. You can't create an instance of an Activity like this because it isn't actually attached to the Android processes. This instance of MainActivity isn't going to step through any of the lifecycle methods, which is why you're seeing the error that the activity has been stopped. It was never actually started.
Instead, remove this reference to MainActivity, as it's bad practice to keep references like this around in your fragment. Any time you need an instance of MainActivity inside a fragment, use the following example:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// ...
MainActivity ma = (MainActivity) getActivity();
ma.DrawVariableFragments("GeneralSettings", "draw");
// ...
}
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.