我正在开发一个应用程序,输入登录详细信息后,该应用程序崩溃了。我认为该错误是由于数据库链接和获取的问题所致,并且尝试了一些在线发布的解决方案,但没有任何效果。 我该怎么解决?
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;
}
}
答案 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对象可以使用哪些构造函数。