不幸的是,Myapp在输入登录详细信息后已停止

时间:2018-06-21 08:15:11

标签: java android crash android-sqlite

我正在开发一个应用程序,输入登录详细信息后,该应用程序崩溃了。我认为该错误是由于数据库链接和获取的问题所致,并且尝试了一些在线发布的解决方案,但没有任何效果。 我该怎么解决?

06-21 13:21:04.590 1913-1913/in.co.arrow E/AndroidRuntime: FATAL EXCEPTION: main
Process: in.co.arrow, PID: 1913
java.lang.IllegalStateException: Couldn't read row 0, col 4 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 in.co.arrow.sql.SqliteHelper.Authenticate(SqliteHelper.java:140)
    at in.co.arrow.LoginActivity$1.onClick(LoginActivity.java:55)
    at android.view.View.performClick(View.java:6367)
    at android.view.View$PerformClick.run(View.java:25032)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6753)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:482)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

这是我的SqliteHelper和LoginActivity类

package in.co.arrow;


public class LoginActivity extends AppCompatActivity {

    EditText editTextEmail;
    EditText editTextPassword;

    TextInputLayout textInputLayoutEmail;
    TextInputLayout textInputLayoutPassword;

    Button buttonLogin;

    SqliteHelper sqliteHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        sqliteHelper = new SqliteHelper(this);
        initCreateAccountTextView();
        initViews();

        buttonLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (validate()) {

                    String Email = editTextEmail.getText().toString();
                    String Password = editTextPassword.getText().toString();

                    User currentUser = sqliteHelper.Authenticate(new User(null,null,null,null,null,Email,Password,null,null,null,null,null,null));


                    if (currentUser != null) {
                        Snackbar.make(buttonLogin, "Successfully Logged in!", Snackbar.LENGTH_LONG).show();

                       /* Intent intent=new Intent(LoginActivity.this,HomeScreenActivity.class);
                        startActivity(intent);
                        finish(); */
                    } else {


                        Snackbar.make(buttonLogin, "Failed to log in , please try again", Snackbar.LENGTH_LONG).show();

                    }
                }
            }
        });


    }

    private void initCreateAccountTextView() {
        TextView textViewCreateAccount = (TextView) findViewById(R.id.textViewCreateAccount);
        textViewCreateAccount.setText(fromHtml("<font color='#ffffff'>I don't have account yet. </font><font color='#0c0099'>create one</font>"));
        textViewCreateAccount.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
                startActivity(intent);
            }
        });
    }

    private void initViews() {
        editTextEmail = (EditText) findViewById(R.id.editTextEmail);
        editTextPassword = (EditText) findViewById(R.id.editTextPassword);
        textInputLayoutEmail = (TextInputLayout) findViewById(R.id.textInputLayoutEmail);
        textInputLayoutPassword = (TextInputLayout) findViewById(R.id.textInputLayoutPassword);
        buttonLogin = (Button) findViewById(R.id.buttonLogin);

    }

    @SuppressWarnings("deprecation")
    public static Spanned fromHtml(String html) {
        Spanned result;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            result = Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY);
        } else {
            result = Html.fromHtml(html);
        }
        return result;
    }

    public boolean validate() {
        boolean valid = false;

        String Email = editTextEmail.getText().toString();
        String Password = editTextPassword.getText().toString();


        if (!android.util.Patterns.EMAIL_ADDRESS.matcher(Email).matches()) {
            valid = false;
            textInputLayoutEmail.setError("Please enter valid email!");
        } else {
            valid = true;
            textInputLayoutEmail.setError(null);
        }


        if (Password.isEmpty()) {
            valid = false;
            textInputLayoutPassword.setError("Please enter valid password!");
        } else {
            if (Password.length() > 5) {
                valid = true;
                textInputLayoutPassword.setError(null);
            } else {
                valid = false;
                textInputLayoutPassword.setError("Password is to short!");
            }
        }

        return valid;
    }


}

SqliteHelper.java

package in.co.arrow.sql;



public class SqliteHelper extends SQLiteOpenHelper {


    public static final String DATABASE_NAME = "arrow";

    public static final int DATABASE_VERSION = 1;

    public static final String TABLE_USERS = "users";

    public static final String KEY_ID = "id";

    public static final String KEY_USER_NAME = "username";

    public static final String KEY_FIRST_NAME="firstname";

    public static final String KEY_LAST_NAME="lastname";

    public static final String KEY_MOBILE_NO="mobileno";

    public static final String KEY_EMAIL = "email";


    public static final String KEY_PASSWORD = "password";

    public static final String KEY_FATHERS_NAME="fathersname";

    public static final String KEY_GENDER="gender";

    public static final String KEY_INST_NAME="instname";

    public static final String KEY_DOB="dob";

    public static final String KEY_BRANCH="branch";

    public static final String KEY_YOP="yop";


    public static final String SQL_TABLE_USERS = " CREATE TABLE " + TABLE_USERS
            + " ( "
            + KEY_ID + " INTEGER PRIMARY KEY, "
            + KEY_USER_NAME + " TEXT, "
            + KEY_FIRST_NAME + " TEXT,"
            + KEY_LAST_NAME + " TEXT,"
            + KEY_MOBILE_NO + " TEXT,"
            + KEY_EMAIL + " TEXT, "
            + KEY_PASSWORD + " TEXT, "
            + KEY_FATHERS_NAME + " TEXT,"
            + KEY_GENDER + " TEXT,"
            + KEY_INST_NAME + " TEXT,"
            + KEY_DOB + " TEXT,"
            + KEY_BRANCH + " TEXT,"
            + KEY_YOP + " TEXT "
            + " ) ";


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

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {

        sqLiteDatabase.execSQL(SQL_TABLE_USERS);

    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

        sqLiteDatabase.execSQL(" DROP TABLE IF EXISTS " + TABLE_USERS);
    }

    public void addUser(User user) {

        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();

        values.put(KEY_USER_NAME, user.userName);

        values.put(KEY_FIRST_NAME, user.firstname);

        values.put(KEY_LAST_NAME, user.lastname);

        values.put(KEY_GENDER, user.gender);

        values.put(KEY_FATHERS_NAME, user.fathersname);

        values.put(KEY_MOBILE_NO, user.mobileno);

        values.put(KEY_EMAIL, user.email);

        values.put(KEY_PASSWORD, user.password);

        values.put(KEY_DOB, user.dob);

        values.put(KEY_INST_NAME,user.instname);

        values.put(KEY_BRANCH, user.branch);

        values.put(KEY_YOP, user.yop);

        long todo_id = db.insert(TABLE_USERS, null, values);
    }

    public User Authenticate(User user) {
        SQLiteDatabase db = this.getReadableDatabase();
        @SuppressLint("Recycle") Cursor cursor = db.query(TABLE_USERS,
                new String[]{KEY_ID, KEY_USER_NAME, KEY_EMAIL, KEY_PASSWORD},
                KEY_EMAIL + "=?",
                new String[]{user.email},
                null, null, null);

        if (cursor != null && cursor.moveToFirst()&& cursor.getCount()>0) {

            User user1;
            user1 = new User(cursor.getString(0), cursor.getString(1), cursor.getString(2), cursor.getString(3),cursor.getString(4), cursor.getString(5), cursor.getString(6),cursor.getString(7),cursor.getString(8),cursor.getString(9),cursor.getString(10),cursor.getString(11),cursor.getString(12));

            if (user.password.equalsIgnoreCase(user1.password)) {
                return user1;
            }
        }

        return null;
    }

    public boolean isEmailExists(String email) {
        SQLiteDatabase db = this.getReadableDatabase();
        @SuppressLint("Recycle") Cursor cursor = db.query(TABLE_USERS,// Selecting Table
                new String[]{KEY_ID, KEY_USER_NAME, KEY_EMAIL, KEY_PASSWORD},
                KEY_EMAIL + "=?",
                new String[]{email},
                null, null, null);

        if (cursor != null && cursor.moveToFirst()&& cursor.getCount()>0) {

            return true;
        }


        return false;
    }
}

2 个答案:

答案 0 :(得分:0)

您的光标只有4列:

new String[]{KEY_ID, KEY_USER_NAME, KEY_EMAIL, KEY_PASSWORD}

,但是您尝试从中读取13列。它在索引4上的第一个不存在的索引上失败。

您可以将正在阅读的所有列添加到投影中。

答案 1 :(得分:0)

您遇到的问题是,您仅指定了要提取到光标中的4列,但是您正尝试从13列中获取数据。

您可以更改:-

Cursor cursor = db.query(TABLE_USERS,
                new String[]{KEY_ID, KEY_USER_NAME, KEY_EMAIL, KEY_PASSWORD},
                KEY_EMAIL + "=?",
                new String[]{user.email},
                null, null, null);

至:-

Cursor cursor = db.query(TABLE_USERS,
                null, // <<<< gets all columns from the table
                KEY_EMAIL + "=?",
                new String[]{user.email},
                null, null, null);

或:-

Cursor cursor = db.query(TABLE_USERS,
                new String[]{KEY_ID, KEY_USER_NAME, KEY_EMAIL, KEY_PASSWORD, KEY_FIRST_NAME, KEY_LAST_NAME, KEY_GENDER, KEY_FATHERS_NAME, KEY_MOBILE_NO, KEY_DOB, KEY_INST_NAME, KEY_BRANCH, KEY_YOP},
                KEY_EMAIL + "=?",
                new String[]{user.email},
                null, null, null);

以上两个假设您要从所有列中获取数据。

或者您可以减少从中检索数据的列数,但这取决于User对象可以使用哪些构造函数。