0

I am trying create a progress bar in each listview item and be able to set the maxvalue and progress of each one. i am using an sqlite database to store the information of the 2 values but i when i try to retrieve the values from the database an error occurs.

here is the MainActivity.java class

public class MainActivity extends AppCompatActivity {

DBAdapter myDb;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    openDB();
    populateListView();
    listViewItemLongClick();
    listViewItemClick();
}

private void openDB(){
    myDb = new DBAdapter(this);
    myDb.open();
}

public void onClick_AddTast (View v) {
    final AlertDialog.Builder mBuilder = new AlertDialog.Builder(MainActivity.this);
    View mView = getLayoutInflater().inflate(R.layout.creategoaldialog_layout, null);
    final EditText mSetProgbarVal = (EditText)mView.findViewById(R.id.progbarmaxvalue);
    Button mAccept = (Button)mView.findViewById(R.id.accept);
    Button mCancel = (Button)mView.findViewById(R.id.cancel);


    mBuilder.setView(mView);


    final AlertDialog dialog = mBuilder.create();
    dialog.show();

    mAccept.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(!mSetProgbarVal.getText().toString().isEmpty()){
                myDb.insertRow(mSetProgbarVal.getText().toString());
                dialog.dismiss();
            } else {
                Toast.makeText(MainActivity.this,"Please fill in required fields", Toast.LENGTH_SHORT).show();

            }
            populateListView();
        }
    });


    mCancel.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            dialog.dismiss();
        }
    });

}

private void populateListView(){
    Cursor cursor = myDb.getAllRows();
    String[] fromFieldNames = new String[] {DBAdapter.KEY_ROWID,DBAdapter.KEY_AMT};
    int[] toViewIDs = new int[]{R.id.goal_id,R.id.progbarprog};
    SimpleCursorAdapter myCursorAdapter;
    myCursorAdapter = new SimpleCursorAdapter(getBaseContext(),R.layout.item_layout, cursor, fromFieldNames, toViewIDs, 0);
    myCursorAdapter.setViewBinder(new CustomViewBinder());
    ListView myList = (ListView)findViewById(R.id.goalList);
    myList.setAdapter(myCursorAdapter);
}

private class CustomViewBinder implements SimpleCursorAdapter.ViewBinder{
    @Override
    public boolean setViewValue(View view, Cursor cursor, int columnIndex){
        if (view.getId()==R.id.progbar){
            ProgressBar progress = (ProgressBar)view;
            progress.setMax(cursor.getInt(cursor.getColumnIndex(String.valueOf(myDb.getRow(1)))));
            return true;
        }
        return false;
    }
}


private void populateProgView(){
    Cursor cursor = myDb.getAllRows();
    String[] fromFieldNames = new String[] {DBAdapter.KEY_PROG};
    int[] toViewIDs = new int[]{R.id.progbarprog};
    SimpleCursorAdapter myCursorAdapter;
    myCursorAdapter = new SimpleCursorAdapter(this,R.layout.item_layout, cursor, fromFieldNames, toViewIDs, 0);
    myCursorAdapter.setViewBinder(new CustomViewBinder2());
    ListView myList = (ListView)findViewById(R.id.goalList);
    myList.setAdapter(myCursorAdapter);
}
private class CustomViewBinder2 implements SimpleCursorAdapter.ViewBinder{
    @Override
    public boolean setViewValue(View view, Cursor cursor, int columnIndex){
        if (view.getId()==R.id.progbar){
            ProgressBar progress = (ProgressBar)view;
            progress.setProgress(cursor.getInt(cursor.getColumnIndex(String.valueOf(myDb.getRow(2)))));
            return true;
        }
        return false;
    }
}

public void listViewItemClick(){
    final ListView myList = (ListView)findViewById(R.id.goalList);
    myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, final long id) {
            Context context = view.getContext();
            final EditText goalAmt = new EditText(context);
            goalAmt.setInputType(InputType.TYPE_CLASS_NUMBER);
            AlertDialog dialog = new AlertDialog.Builder(MainActivity.this)
                    .setTitle("Set Amount")
                    .setView(goalAmt)
                    .setPositiveButton("Update", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            String goalValue = String.valueOf(goalAmt.getText().toString());
                            myDb.insertProg(goalValue);
                            populateProgView();
                        }
                    })
                    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    })
                    .create();
            dialog.show();
        }
    });
}

public void onClickDeleteAllGoals(View v){
    myDb.deleteAll();
    populateListView();
}

private void listViewItemLongClick(){
    ListView myList = (ListView)findViewById(R.id.goalList);
    myList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            myDb.deleteRow(id);
            populateListView();

            return false;
        }
    });
  }
}

here is the DBAdapter.java class

public class DBAdapter {

private static final String TAG = "DBAdapter"; //used for logging database version

//Field Names
public static final String KEY_ROWID = "_id";
public static final String KEY_AMT = "amt";
public static final String KEY_PROG = "prog";

public static final String[] ALL_KEYS = new String[]{KEY_ROWID, KEY_AMT};

//Column Numbers for each field name;
public static final int COL_ROWID = 0;
public static final int COL_AMT = 1;
public static final int COL_PROG = 2;

//Database Info
public static final String DATABASE_NAME = "dbGoals";
public static final String DATABASE_TABLE = "tblGoals";
public static final int DATABASE_VERSION = 1; //The Version number must be incremented

//SQL Statement to create database
private static final String DATABASE_CREATE_SQL = "CREATE TABLE " + DATABASE_TABLE + " (" +
        KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
        KEY_AMT + " INTEGER, " +
        KEY_PROG + " INTEGER " +");";

private final Context context;
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;


public DBAdapter(Context ctx){
    this.context = ctx;
    myDBHelper = new DatabaseHelper(context);
}


//Open the database connection
public DBAdapter open(){
    db = myDBHelper.getWritableDatabase();
    return this;
}

//Close the database connection
public void close(){
    myDBHelper.close();
}

//Add a new set of values to be inserted into the database.
public long insertRow(String amt){
    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_AMT, amt);

    //Insert the data into the database
    return db.insert(DATABASE_TABLE, null, initialValues);
}

public long insertProg(String prog){
    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_PROG, prog);

    //Insert the data into the database
    return db.insert(DATABASE_TABLE, null, initialValues);
}


//Delete a row from the database by rowId (primary key)
public boolean deleteRow(long rowId){
    String where = KEY_ROWID + "=" + rowId;
    return db.delete(DATABASE_TABLE, where, null) != 0;
}

public void deleteAll(){
    Cursor c = getAllRows();
    long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
    if (c.moveToFirst()){
        do {
            deleteRow(c.getLong((int) rowId));
        } while (c.moveToNext());
    }
    c.close();
}

//Return all data to database
public Cursor getAllRows(){
    String where = null;
    Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS, where,
            null, null, null, null, null);
    if (c != null){
        c.moveToFirst();
    }
    return c;
}

//Get a specific row (by rowId)
public  Cursor getRow(long rowId){
    String where = KEY_ROWID + "=" + rowId;
    Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS, where,
            null, null, null, null, null);
    if (c != null){
        c.moveToFirst();
    }
    return c;
}

private static class DatabaseHelper extends SQLiteOpenHelper {

    DatabaseHelper(Context context){
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void  onCreate(SQLiteDatabase _db){
        _db.execSQL(DATABASE_CREATE_SQL);
    }

    @Override
    public void  onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion){
        Log.w(TAG, "Upgrading application's database from new version " + oldVersion + " to " + newVersion +
                ", which will destroy all old data!");

        //Destroy old database:
        _db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);

        //Recreate new database;
        onCreate(_db);
    }
  }
}

then here is the logcat error message

2-16 18:50:05.562 7084-7084/com.example.eugene.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
                                                                            Process: com.example.eugene.myapplication, PID: 7084
                                                                            java.lang.IllegalArgumentException: column 'prog' does not exist
                                                                                at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:303)
                                                                                at android.widget.SimpleCursorAdapter.findColumns(SimpleCursorAdapter.java:333)
                                                                                at android.widget.SimpleCursorAdapter.<init>(SimpleCursorAdapter.java:107)
                                                                                at com.example.eugene.myapplication.MainActivity.populateProgView(MainActivity.java:114)
                                                                                at com.example.eugene.myapplication.MainActivity.access$300(MainActivity.java:25)
                                                                                at com.example.eugene.myapplication.MainActivity$3$2.onClick(MainActivity.java:147)
                                                                                at android.support.v7.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:5221)
                                                                                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:899)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

i am very new to android studio and most of these code i got from tutorials and other questions in this site.

EDIT! Turns out there were some parts in the database that weren't typed correctly resulting in the error message, the issue has been fixed!

Waffles
  • 1
  • 2

1 Answers1

0

The likely cause of the exception, (column prog not found), is a very common misconception that the onCreate method is invoked every time the DatabaseHelper (subclass of SQLiteOpenHelper) is instantiated. This is not the case, the onCreate method is invoked only once when the database is created.

As such the code in the onCreate method, typically the creation of the table(s) in the database is only run once. As such any subsequent changes to the table(s) will not be applied unless the database is deleted or if the onCreate method is invoked otherwise.

So assuming that the table structure has been changed to include the prog column. There are 2 or 3 simple ways to circumvent the issue assuming that loss of existing data is not an issue. They are :-

  • Uninstall the App.
  • Delete the App's data.
  • If the onUpgrade method has been written accordingly i.e. to DROP the changed table(s) and to then call the onCreate method, to increase the database version number.

As you code does DROP the table and call onCreate you can use any of the 3 options and then rerun the App.

MikeT
  • 51,415
  • 16
  • 49
  • 68
  • I have tried, uninstalling, deleting the app's data and updating the database ver, but the problem still persists – Waffles Feb 16 '18 at 11:49