jeudi 26 novembre 2015

Android SQLite Database not fully commiting? Changes until Activity ends?

Sorry for the long description, it's hard to describe my problem without giving you some background.

Okay so I have an app that uses one SQLite database and has two tables in it Table 1 and Table 2. I have a main activity with fragment with a button that starts my Log activity with fragment. The Log activity has a tabbed viewpager and in each view of the viewpager is a listview (Tab 1 listview and Tab 2 listview) with data from the corresponding tables (Table 1 and Table 2) in the database.

So when I'm in my Log Activity with Fragment I can click on the Tab 1 and it will populate the Tab 1 listview with the data from the Table 1 in my database. When I click on Tab 2 it'll populate the Tab 2 listview with the data from my Table 2 in my database. Each tab has it's own fragment. Tab 1 fragment and Tab 2 fragment.

So to explain my issue I'll just focus on my Tab 1, because both tabs are doing the same time.

Let me explain first though that if I add Data X into my Tab 1, Table 1, it will populate Listview 1 with Data X and add the Data X into my Table 1 just fine. I can Log.d my Table 1 and see it got entered just fine. If I press back on the phone to go back to my Main Activity with Fragment and then decide to go back into my Log Activity with Fragment it will populate the Listview 1 just fine with Data X and Data X is still in my Table 1, because again I can Log.d my Table 1 and see the data has been entered just fine. If I delete Data X now after having gone to the Main Activity and back into the Log Activity the Data X will delete from my Table 1 just fine and it will be removed from my Listview 1. I can log.d my Table 1 after deleting and see it has been deleted from my Table 1.

So my actual issue is when I add lets say Data X and Data Y into my Tab 1, Table 1 of my database. The Listview 1 will populate with Data X and Data Y and insert Data X and Data Y into the database just fine because I can Log.d the table and see Data X and Data Y have been entered into my table.... But now lets say I decide to instantly delete the Data Y (While have never left the Log Activity this time) it will not delete from the Table 1 but it will delete Data Y from my Listview 1. So now when I Log.d my Table 1 I see that I still have Data X and Data Y in my Table 1, but my Listview 1 shows only Data X. If I now press the back button and go back to my Main Activity, and then again go back into my Log Activity it will populate my Tab 1 Listview 1 with Data X and Data Y because Data Y was not actually removed from my Table 1.

It seems as if I can't Delete or Edit freshly entered Data into my Tables without first leaving my Log Activity and going back into it to "Commit/Finalize" the data entered into the Table 1. My Insert, Update, and Delete functions work just fine after I have left the Logs Activity after adding fresh data and then going back into my Logs Activity. But My Delete and Update functions do not work properly if I add fresh data and then instantly try to alter that data. My Listview is updating and populating correctly though.

I've made sure I have one instance of my SQLiteOpenHelper and my SQLiteDatabase variables.

Here is code for one of my Tab fragments I stripped out a lot of stuff due to size of the file.

public class LogOilTabFragment extends Fragment  implements View.OnClickListener{

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    mContext = getActivity();

    DataSource.getInstance(mContext).open();

    mListView = (ListView) view.findViewById(R.id.oil_list);

    arrayOfLogs = new ArrayList<Log>();

    arrayOfLogs = DataSource.getInstance(mContext).getAllLogs(LogsContract.OilTable.TAG);
    mAdapter = new LogAdapter(getActivity(), arrayOfLogs);
    mListView.setAdapter(mAdapter);
    }

}


@Override
public void onResume() {
    DataSource.getInstance(mContext).open();
    super.onResume();
}

@Override
public void onPause() {
    DataSource.getInstance(mContext).close();
    super.onPause();
}



private void addLog() {
    LayoutInflater factory = LayoutInflater.from(getActivity());
    final View view = factory.inflate(R.layout.add_edit_log, null);

    AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
    alert.setView(view);

    alert.setPositiveButton("ADD LOG", new DialogInterface.OnClickListener(){
        public void onClick(DialogInterface dialog, int whichButton) {
            String date = dateInput.getText().toString();
            String amount = amountInput.getText().toString();
            String miles = milesInput.getText().toString();

            if (error_count == 0) {
                Log log = new Log();
                log.setmDate(date);
                log.setmAmount(amount);
                log.setmMiles(miles);

                DataSource.getInstance(mContext).insert(date, amount, miles, OilTable.TAG);
                mAdapter.add(log);
                mAdapter.notifyDataSetChanged();

                mListView.smoothScrollToPosition(mPosition);
            }
        }
    });
    alert.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {

        }
    });
    alert.show();



}

private void editLog() {
    LayoutInflater factory = LayoutInflater.from(getActivity());
    final View view = factory.inflate(R.layout.add_edit_log, null);

    AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());

    alert.setView(view);

    Log log = null;
    //Pre fill in the edit text views with the data already in the database
    if (mAdapter.getCount() > 0 && mPosition >= 0) {
        log = (Log) mAdapter.getItem(mPosition);
        dateInput.setText(log.getmDate());
        amountInput.setText(log.getmAmount());
        milesInput.setText(log.getmMiles());
    }

    alert.setPositiveButton("EDIT LOG", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            String date = dateInput.getText().toString();
            String amount = amountInput.getText().toString();
            String miles = milesInput.getText().toString();

            if (error_count == 0) {

                Log log = (Log) mAdapter.getItem(mPosition);
                                  DataSource.getInstance(mContext).edit(log.getmId(), date, amount, miles, OilTable.TAG);
                mAdapter.clear();
                arrayOfLogs = new ArrayList<Log>();

                arrayOfLogs = DataSource.getInstance(mContext).getAllLogs(OilTable.TAG);
                mAdapter.addAll(arrayOfLogs);
                mAdapter.notifyDataSetChanged();

            }
        }
    });
    alert.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            //Do Nothing
        }
    });

    alert.show();
}

private void deleteLog() {
    LayoutInflater factory = LayoutInflater.from(getActivity());
    final View view = factory.inflate(R.layout.delete_log, null);

    AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());

    alert.setView(view);

    alert.setPositiveButton("DELETE LOG", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            Log log = null;

            if (mAdapter.getCount() > 0) {
                log = (Log) mAdapter.getItem(mPosition);
                                        DataSource.getInstance(mContext).delete(log, OilTable.TAG);

                mAdapter.remove(log);
                mAdapter.notifyDataSetChanged();
            }

        }
    });
    alert.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int whichButton) {
            //Do Nothing
        }
    });

    alert.show();

}

Here is my class that has my Insert, Update, and Delete code from my DataSource

public class DataSource {

public static DataSource dataSource;

private SQLiteDatabase mSQLiteDatabase;
private LogsDBHelper mLogsDBHelper; //LogsDBHelper Extends SQLiteOpenHelper
}

//String of column names for the oil sqlite database.
private String[] mAllOilColumns = {
        OilTable.COLUMN_ID,
        OilTable.COLUMN_DATE,
        OilTable.COLUMN_AMOUNT,
        OilTable.COLUMN_MILES};

//String of column names for the coolant sqlite database.
private String[] mAllCoolantColumns = {
        OilTable.COLUMN_ID,
        OilTable.COLUMN_DATE,
        OilTable.COLUMN_AMOUNT,
        OilTable.COLUMN_MILES};

    public static synchronized DataSource getInstance(Context context) {

    if (dataSource == null) {
        dataSource = new DataSource(context.getApplicationContext());
    }
    return dataSource;
}

private DataSource(Context context) {
    mLogsDBHelper = new LogsDBHelper(context); //LogsDBHelper Extends SQLiteOpenHelper
}

public void open() throws SQLiteException {
    mSQLiteDatabase = mLogsDBHelper.getWritableDatabase();
}

public void close() {
    mLogsDBHelper.close();
   // mSQLiteDatabase.close();
}



//Method takes a string and depending on the string creates a query from the correct
//database table and returns the amount of items in the table
public int getLength(String tag){
    Cursor cursor;

    switch (tag) {
        case OilTable.TAG:
            cursor = mSQLiteDatabase.query(OilTable.TABLE_NAME,
                    mAllOilColumns, null, null, null, null, null);
            return cursor.getCount();
        case CoolantTable.TAG:
            cursor = mSQLiteDatabase.query(CoolantTable.TABLE_NAME,
                    mAllCoolantColumns, null, null, null, null, null);
            return cursor.getCount();
    }
    return 0;
}

//Inserts a log into the correct sqlite table with the passed values
public void insert(String date, String amount, String miles, String tag) {
    ContentValues values = new ContentValues();

    switch (tag) {
        case OilTable.TAG:
            values.put(OilTable.COLUMN_DATE, date);
            values.put(OilTable.COLUMN_AMOUNT, amount);
            values.put(OilTable.COLUMN_MILES, miles);
            mSQLiteDatabase.insert(OilTable.TABLE_NAME, null, values);
            break;
        case CoolantTable.TAG:
            values.put(CoolantTable.COLUMN_DATE, date);
            values.put(CoolantTable.COLUMN_AMOUNT, amount);
            values.put(CoolantTable.COLUMN_MILES, miles);
            mSQLiteDatabase.insert(CoolantTable.TABLE_NAME, null, values);
            break;

    }
}

//Edits/Updates a log into the correct sqlite table with the passed values
public void edit(Long id, String date, String amount, String miles, String tag){
    ContentValues values = new ContentValues();

    switch (tag) {
        case OilTable.TAG:
            values.put(OilTable.COLUMN_DATE, date);
            values.put(OilTable.COLUMN_AMOUNT, amount);
            values.put(OilTable.COLUMN_MILES, miles);
            mSQLiteDatabase.update(OilTable.TABLE_NAME, values, "_id=" + id, null);
            break;
        case CoolantTable.TAG:
            values.put(CoolantTable.COLUMN_DATE, date);
            values.put(CoolantTable.COLUMN_AMOUNT, amount);
            values.put(CoolantTable.COLUMN_MILES, miles);
            mSQLiteDatabase.update(CoolantTable.TABLE_NAME, values, "_id=" + id, null);
            break;
    }
}

//Deletes a log into the correct sqlite table based on the log id.
public void delete(Log log, String tag) {
    long id = log.getmId();

    switch(tag) {
        case OilTable.TAG:
            mSQLiteDatabase.delete(OilTable.TABLE_NAME,
                    OilTable.COLUMN_ID + " = " + id, null);
            break;
        case CoolantTable.TAG:
            mSQLiteDatabase.delete(CoolantTable.TABLE_NAME,
                    CoolantTable.COLUMN_ID + " = " + id, null);
            break;
    }
}

//Returns an Arraylist of all of the logs from the table specified from the passed in value.
public ArrayList getAllLogs(String tag){

    ArrayList logs = new ArrayList();
    Cursor cursor;
    Log log;

    switch(tag) {
        case OilTable.TAG:
            cursor = mSQLiteDatabase.query(OilTable.TABLE_NAME,
                mAllOilColumns, null, null, null, null, null);
            cursor.moveToFirst();
            while (!cursor.isAfterLast()) {
                log = cursorToLog(cursor);
                logs.add(log);
                cursor.moveToNext();
            }
            cursor.close();
            break;
        case CoolantTable.TAG:
            cursor = mSQLiteDatabase.query(CoolantTable.TABLE_NAME,
                    mAllCoolantColumns, null, null, null, null, null);
            cursor.moveToFirst();
            while (!cursor.isAfterLast()) {
                log = cursorToLog(cursor);
                logs.add(log);
                cursor.moveToNext();
            }
            cursor.close();
            break;
    }

    return logs;
}

//Used in local method getAllLogs()
private Log cursorToLog(Cursor cursor) {
    Log log = new Log();
    log.setmId(cursor.getLong(0));
    log.setmDate(cursor.getString(1));
    log.setmAmount(cursor.getString(2));
    log.setmMiles(cursor.getString(3));
    return log;
}


//Used to get all of the dates from the specified database in the call.
public String[] getAllDates(String tag){
    Cursor cursor;
    int index;
    String[] dates = new String[0];
    int i = 0;

    switch(tag) {
        case OilTable.TAG:
            cursor = mSQLiteDatabase.query(OilTable.TABLE_NAME, mAllOilColumns, null, null, null, null, null);
            index = cursor.getColumnIndex(OilTable.COLUMN_DATE);
            dates = new String[cursor.getCount()];
            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                dates[i] = cursor.getString(index);
                i++;
                cursor.moveToNext();
            }

            cursor.close();
            break;
        case CoolantTable.TAG:
            cursor = mSQLiteDatabase.query(CoolantTable.TABLE_NAME, mAllCoolantColumns, null, null, null, null, null);
            index = cursor.getColumnIndex(CoolantTable.COLUMN_DATE);
            dates = new String[cursor.getCount()];
            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                dates[i] = cursor.getString(index);
                i++;
                cursor.moveToNext();
            }

            cursor.close();
            break;
    }
    return dates;
}

//Used to get all of the amounts from the specified database in the call.
public String[] getAllAmounts(String tag){
    Cursor cursor;
    int index;
    String[] amounts = new String[0];
    int i = 0;

    switch(tag) {
        case OilTable.TAG:
            cursor = mSQLiteDatabase.query(OilTable.TABLE_NAME, mAllOilColumns, null, null, null, null, null);
            index = cursor.getColumnIndex(OilTable.COLUMN_AMOUNT);
            amounts = new String[cursor.getCount()];
            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                amounts[i] = cursor.getString(index);
                i++;
                cursor.moveToNext();
            }

            cursor.close();
            break;
        case CoolantTable.TAG:
            cursor = mSQLiteDatabase.query(CoolantTable.TABLE_NAME, mAllCoolantColumns, null, null, null, null, null);
            index = cursor.getColumnIndex(CoolantTable.COLUMN_AMOUNT);
            amounts = new String[cursor.getCount()];
            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                amounts[i] = cursor.getString(index);
                i++;
                cursor.moveToNext();
            }

            cursor.close();
            break;
    }

    return amounts;
}

//Used to get all of the miles from the specified database in the call.
public String[] getAllMiles(String tag){
    Cursor cursor;
    int index;
    String[] miles = new String[0];
    int i = 0;

    switch(tag) {
        case OilTable.TAG:
            cursor = mSQLiteDatabase.query(OilTable.TABLE_NAME, mAllOilColumns, null, null, null, null, null);
            index = cursor.getColumnIndex(OilTable.COLUMN_MILES);
            miles = new String[cursor.getCount()];
            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                miles[i] = cursor.getString(index);
                i++;
                cursor.moveToNext();
            }

            cursor.close();
            break;
        case CoolantTable.TAG:
            cursor = mSQLiteDatabase.query(CoolantTable.TABLE_NAME, mAllCoolantColumns, null, null, null, null, null);
            index = cursor.getColumnIndex(CoolantTable.COLUMN_MILES);
            miles = new String[cursor.getCount()];
            cursor.moveToFirst();

            while (!cursor.isAfterLast()) {
                miles[i] = cursor.getString(index);
                i++;
                cursor.moveToNext();
            }

            cursor.close();
            break;
    }

    return miles;
}


}

Aucun commentaire:

Enregistrer un commentaire