Строка обновления Android SQLite не работает и ошибки не отображаются - PullRequest
0 голосов
/ 12 сентября 2018

Я пытаюсь обновить строку через SQLite в Android через фрагмент, но она не обновляет таблицы, и я также не получаю никаких ошибок. Вот мой код .. может быть, я что-то упустил. Спасибо

MySQLiteHelper класс

public class MySQLiteHelper extends SQLiteOpenHelper {

    public static final String MYDATABASE = "myDataBase";
    public static final String MYTABLE = "myTable";
    public static final String USERNAME = "myUser";
    public static final String PASSWORD = "myPass";
    public static final String EMAIL = "myEmail";
    public static final int VERSION = 1;
    public static final String KEY_ID = "_id";


    public MySQLiteHelper(Context context) {
        super(context, MYDATABASE, null, VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_TABLE = "CREATE TABLE " + MYTABLE + "("
                + KEY_ID + " INTEGER PRIMARY KEY," + USERNAME + " TEXT," + PASSWORD + " TEXT,"
                + EMAIL + " TEXT" + ")";

        db.execSQL(CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //any upgrade can update the version and if newV > oldV then upgrade will be exected
        db.execSQL("DROP TABLE IF EXISTS " + MYTABLE);
        onCreate(db);
    }


    public Integer deleteData(String id) {
        SQLiteDatabase db = this.getWritableDatabase();
        return db.delete(MYTABLE, "_id = ?", new String[] {id});
    }

    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);
        db.update(MYTABLE, cv, "_id = ?", new String[] {id});
        return true;
    }


}

Основной класс занятий

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    EditText etUser, etPass, etEmail;
    Button btSave, btShow;
    MySQLiteHelper mySQLiteHelper;
    SQLiteDatabase sqLiteDatabase;
    ListView lvRecords;
    ArrayList<String> userDataList;
    ArrayAdapter<String> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "onCreate: started");

        etUser = findViewById(R.id.etUser);
        etPass = findViewById(R.id.etPass);
        etEmail = findViewById(R.id.etEmail);
        btSave = findViewById(R.id.btSave);
        btShow = findViewById(R.id.btShow);
        lvRecords = findViewById(R.id.lvRecords);

        userDataList = new ArrayList<String>();

        mySQLiteHelper = new MySQLiteHelper(this);
        sqLiteDatabase = mySQLiteHelper.getWritableDatabase(); //write and read

        adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, userDataList);
        lvRecords.setAdapter(adapter);
        showList();

        lvRecords.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

                String selectedData = userDataList.get(position);
                String rowId = selectedData.substring(0,1);
                Log.d(TAG, "onItemLongClick: *******id " + rowId);
                Integer deleteRow = mySQLiteHelper.deleteData(rowId);
                adapter.remove(adapter.getItem(position));
                adapter.notifyDataSetChanged();



                Toast.makeText(MainActivity.this, "Position: " + rowId, Toast.LENGTH_SHORT).show();

                return false;
            }
        });

        lvRecords.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                UpdateFragment updateFragment = new UpdateFragment();
                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.add(R.id.fragment_container, updateFragment).addToBackStack(null).commit();

                String selectedData = userDataList.get(position);
                String[] userData = selectedData.split("\\s+");
                String userId = userData[0];
                String userName = userData[1];
                String userPass = userData[2];
                String userEmail = userData[3];

                Bundle b = new Bundle();
                b.putInt("position", position);
                b.putString("id", userId);
                b.putString("user", userName);
                b.putString("pass", userPass);
                b.putString("email", userEmail);
                updateFragment.setArguments(b);


                Toast.makeText(MainActivity.this, "id", Toast.LENGTH_SHORT).show();

            }
        });


        btShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showList();
            }

        });

        btSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //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("");
            }
        });


    }



    public void hideKeyboard() {
        InputMethodManager imm = (InputMethodManager) getSystemService(
                Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
    }

    private void showList() {
        Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM " + mySQLiteHelper.MYTABLE, null);

            cursor.moveToFirst();
            userDataList.clear();


            //to read the first iteration use a do while
            do {
                if(cursor != null) {

                    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();
                }
            } while(cursor.moveToNext());


    }



}

UpdateFragment.class

public class UpdateFragment extends Fragment {

    private static final String TAG = "UpdateFragment";

    Button btUpdate, btClose;
    EditText etUser, etPass, etEmail;
    Fragment me = this;
    MySQLiteHelper mySQLiteHelper;
    SQLiteDatabase sqLiteDatabase;

    String userId, username, password, email;
    int position, e;

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

        View v = inflater.inflate(R.layout.fragment_update, container, false);

        etUser = v.findViewById(R.id.etUserFrag);
        etPass = v.findViewById(R.id.etPassFrag);
        etEmail = v.findViewById(R.id.etEmailFrag);
        btUpdate = v.findViewById(R.id.btUpdateFrag);
        btClose = v.findViewById(R.id.btCloseFrag);

        Bundle b = getArguments();
        position = b.getInt("position");
        position = position -1;
        userId =  b.getString("id");
        e = Integer.parseInt(userId);
        //e = e - 1;
        //userId = userId -1 ;
        Log.d(TAG, "onCreateView: **********userID: " + userId);
        username = b.getString("user");
        password = b.getString("pass");
        email = b.getString("email");

        etUser.setText(username);
        etPass.setText(password);
        etEmail.setText(email);

        mySQLiteHelper = new MySQLiteHelper(getContext());
        sqLiteDatabase = mySQLiteHelper.getWritableDatabase(); //write and read

        btClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                closeFragment();
            }
        });

        btUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {//
                boolean isUpdate = mySQLiteHelper.updateData(userId, username, password, email);
                if(isUpdate==true)
                    Toast.makeText(getContext(),"Data Update",Toast.LENGTH_LONG).show();
                else
                    Toast.makeText(getContext(),"Data not Updated",Toast.LENGTH_LONG).show();



            }
        });








        return v;
    }

    private void closeFragment() {
        getActivity().getSupportFragmentManager().beginTransaction().remove(me).commit();
    }
}

1 Ответ

0 голосов
/ 12 сентября 2018

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();
        }
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...