Issue 1 null Cursor
НИКОГДА считают, что пустой курсор нулевой.
Методы SQLiteDatabase, которые возвращают Курсор, вернут действительный Курсор, не нуль.Курсор, если он пустой, будет иметь счетчик 0 (т. Е. cursor.getCount() == 0
).
Так что если вы просто сделаете это (как в вашем методе showlist )
cursor.moveToFirst();
if (cursor == null) {
do you stuff here
}
Вы получите ошибку индексации, если курсор будет пустым.Вместо этого вы должны проверить результат cursor.moveToFirst()
, будет ложным, если есть извлеченные строки.Однако проще использовать цикл while (см. Код ниже).
Выпуск 1-2 Закрыть курсоры
Вы также должны закрыть курсор, когда закончите с ним.
Исправлено /лучше showList метод: -
private void showList() {
Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM " + mySQLiteHelper.MYTABLE, null);
userDataList.clear();
//<<<<<<<<<< simpler while loop >>>>>>>>>>
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndex(mySQLiteHelper.KEY_ID));
String user = cursor.getString(cursor.getColumnIndex(mySQLiteHelper.USERNAME));
String pass = cursor.getString(cursor.getColumnIndex(mySQLiteHelper.PASSWORD));
String email = cursor.getString(cursor.getColumnIndex(mySQLiteHelper.EMAIL));
userDataList.add(id + " " + user + " " + pass + " " + email);
adapter.notifyDataSetChanged();
Log.d(TAG, "onClick: ******rows: " + mySQLiteHelper.KEY_ID + ":" + id + " user: " + user + " pass: " + pass + " email: " + email);
Toast.makeText(MainActivity.this,
"id: " + id + " user: " + user + " pass: " + pass + " email: " + email, Toast.LENGTH_SHORT)
.show();
}
cursor.close();
}
Проблема 2 - Сохранить, когда данные не были введены.
Если вы нажмете кнопку Сохранить и данные не будут введены вполе, затем будет добавлена новая строка.Это приведет к тому, что при нажатии элемента в ListView произойдет сбой из-за ошибок индексации в массивах, поскольку split не будет извлекать 4 элемента (гарантируется только id ).
Следующее исправит это (посмотрите на комменеты): -
btSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//<<<<<<<<<< Start of Extra Code >>>>>>>>>>
if (
etUser.getText().toString().length() < 1 ||
etEmail.getText().toString().length() < 1 ||
etPass.getText().toString().length() < 1
) {
Toast.makeText(MainActivity.this,"WHOA ENTER DATA IN ALL FIELDS!!!!!!!!!!",Toast.LENGTH_SHORT).show();
return;
}
//<<<<<<<<<< End of Extra Code >>>>>>>>>>
//content values to put the data in the database
//same order as table creation fields order
ContentValues contentValues = new ContentValues();
String user = etUser.getText().toString();
String pass = etPass.getText().toString();
String email = etEmail.getText().toString();
contentValues.put(mySQLiteHelper.USERNAME, user);
contentValues.put(mySQLiteHelper.PASSWORD, pass);
contentValues.put(mySQLiteHelper.EMAIL, email);
sqLiteDatabase.insert(mySQLiteHelper.MYTABLE, null, contentValues);
hideKeyboard();
showList();
etUser.setText("");
etPass.setText("");
etEmail.setText("");
}
});
Проблема 3 - метод updateData всегда возвращает true
SQliteDatabase update метод возвращает количество затронутых строк, поэтому, если ни одна строка не обновлена (при изменении строки на те же значения, что и при обновлении), будет возвращено 0.Вы updateData метод не проверяет результат, поэтому всегда возвращает true.
Возможно, измените его на: -
public boolean updateData(String id, String user, String pass, String email) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(USERNAME, user);
cv.put(PASSWORD, pass);
cv.put(EMAIL, email);
if (db.update(MYTABLE, cv, "_id = ?", new String[] {id}) > 0) {
return true;
}
return false;
}
Чтобы обеспечить более точную обратную связь (ивыделите основную проблему) можно добавить следующий метод для получения данных в соответствии с идентификатором: -
public Cursor getDataById(String id) {
SQLiteDatabase db = this.getWritableDatabase();
String whereclause = KEY_ID + "=?";
String[] whereargs = new String[]{String.valueOf(id)};
return db.query(MYTABLE,null,whereclause,whereargs,null,null,null);
}
- Обратите внимание, использование этого включено в основной выпуск ниже.
Основная проблема
Основная проблема, которая приводит к отсутствию обновлений, заключается в том, что вы передаете в обновление старые значения, а не значения в соответствии с EditTexts.
Следующий код изменяет кнопку UPDATE onClickListener , чтобы решить эту проблему, а также обеспечивает лучшую обратную связь через выпускаемые тосты: -
btUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {//
//boolean isUpdate = mySQLiteHelper.updateData(userId, username, password, email);
boolean isUpdate = mySQLiteHelper.updateData(
userId,
etUser.getText().toString(),
etPass.getText().toString(),
etEmail.getText().toString()
);
Cursor csr = mySQLiteHelper.getDataById(userId);
String newUser = "not found";
String newEmail = "not found";
String newPass = "not found";
if (csr.moveToFirst()) {
newUser = csr.getString(csr.getColumnIndex(MySQLiteHelper.USERNAME));
newEmail = csr.getString(csr.getColumnIndex(MySQLiteHelper.EMAIL));
newPass = csr.getString(csr.getColumnIndex(MySQLiteHelper.PASSWORD));
}
csr.close();
if(isUpdate==true)
Toast.makeText(getContext(),
"Data Updated - User now " + newUser +
" Email now " + newEmail +
" Password now " + newPass,
Toast.LENGTH_LONG
).show();
else
Toast.makeText(getContext(),"Data not Updated - User is " + newUser +
" Email is " + newEmail +
" Password is " + newPass,
Toast.LENGTH_LONG
).show();
}
});
btUpdate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//boolean isUpdate = mySQLiteHelper.updateData(userId, username, password, email); //<<<<<<<<<< Commented out (old)
//<<<<<<<<<< NEW (gets values from the edit texts)
boolean isUpdate = mySQLiteHelper.updateData(
userId,
etUser.getText().toString(),
etPass.getText().toString(),
etEmail.getText().toString()
);
//<<<<<<<<<< ADDED to get current stored data for Toast
Cursor csr = mySQLiteHelper.getDataById(userId);
String newUser = "not found";
String newEmail = "not found";
String newPass = "not found";
if (csr.moveToFirst()) {
newUser = csr.getString(csr.getColumnIndex(MySQLiteHelper.USERNAME));
newEmail = csr.getString(csr.getColumnIndex(MySQLiteHelper.EMAIL));
newPass = csr.getString(csr.getColumnIndex(MySQLiteHelper.PASSWORD));
}
csr.close();
//<<<<<<<<< CHANGES so more info is provided by Toasts
if(isUpdate==true)
Toast.makeText(getContext(),
"Data Updated - User now " + newUser +
" Email now " + newEmail +
" Password now " + newPass,
Toast.LENGTH_LONG
).show();
else
Toast.makeText(getContext(),"Data not Updated - User is " + newUser +
" Email is " + newEmail +
" Password is " + newPass,
Toast.LENGTH_LONG
).show();
}
});