我需要帮助。我已经研究了一周来解决我的问题,而且找不到解决方案。
我已经放了一些代码,逻辑上它会起作用。
我的问题是我想从数据库(SQLite)获取信息并将其保存到变量中。
当我按下按钮(getLoginInfo)时,它将使应用程序崩溃。这是代码。
DBHandler.java
package project.asyraf.sar;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBHandler extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "kypsarv2.db";
public static final int DATABASE_VERSION = 1;
public DBHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String createTableLoginInfo = "CREATE TABLE loginInfo (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT, password TEXT, accesslevel TEXT, owner TEXT);";
db.execSQL(createTableLoginInfo);
String createTableAdmin = "CREATE TABLE admin (id INTEGER PRIMARY KEY AUTOINCREMENT, adminName TEXT, adminIC);";
db.execSQL(createTableAdmin);
String createTableLect = "CREATE TABLE lecturer (id INTEGER PRIMARY KEY AUTOINCREMENT, lecturerName TEXT, lecturerIC);";
db.execSQL(createTableLect);
String createTableStud = "CREATE TABLE student (id INTEGER PRIMARY KEY AUTOINCREMENT, studentName TEXT, studentIC);";
db.execSQL(createTableStud);
String createTableReminder = "CREATE TABLE reminder (id INTEGER PRIMARY KEY AUTOINCREMENT, subject TEXT, activity TEXT, startDate DATE, endDate DATE, description TEXT, owner TEXT);";
db.execSQL(createTableReminder);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS loginInfo");
db.execSQL("DROP TABLE IF EXISTS admin");
db.execSQL("DROP TABLE IF EXISTS lecturer");
db.execSQL("DROP TABLE IF EXISTS student");
db.execSQL("DROP TABLE IF EXISTS reminder");
onCreate(db);
}
protected String owner, accessLevel;
public void getLoginInfo (String username, String password)
{
Cursor cursor = this.getReadableDatabase().rawQuery("SELECT * FROM loginInfo WHERE username = ? AND password = ?", new String[] {username, password});
cursor.moveToFirst();
accessLevel = cursor.getString(3);
owner = cursor.getString(4);
cursor.close();
}
LoginMenu.java
package project.asyraf.sar;
import android.content.Intent;
import android.database.Cursor;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class LoginMenu extends AppCompatActivity {
DBHandler useDB = new DBHandler(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_menu);
}
public void closeApps (View view){
finish();
}
public void loginTrial (View view) {
final EditText getUsername = (EditText) findViewById(R.id.username);
final EditText getPassword = (EditText) findViewById(R.id.password);
String textUsername, textPassword = "";
textUsername = getUsername.getText().toString();
textPassword = getPassword.getText().toString();
Intent loginSuccessLecturer = new Intent (this, LecturerDashboard.class);
Intent loginSuccessStudent = new Intent (this, StudentDashboard.class);
Intent loginSuccessAdmin = new Intent (this, AdminDashboard.class);
//Cursor getLogin = useDB.getLoginData(textUsername, textPassword);
useDB.getLoginInfo(textUsername, textPassword);
String owner = "";
String accessLevel = "";
owner = useDB.owner;
accessLevel = useDB.accessLevel;
StringBuffer buffer = new StringBuffer();
if (textUsername.equals("") || textPassword.equals(""))
{
Toast.makeText(getApplicationContext(), "Enter Username or Password", Toast.LENGTH_SHORT).show();
}
else if (textUsername.equals("admin") && textPassword.equals("admin"))
{
startActivity(loginSuccessAdmin);
}
else
{
if (owner.equals(""))
{
Toast.makeText(getApplicationContext(), "User do not exist", Toast.LENGTH_SHORT).show();
}
else
{
if (accessLevel.equals("student"))
{
startActivity(loginSuccessStudent);
}
else if (accessLevel.equals("lecturer"))
{
startActivity(loginSuccessLecturer);
}
}
}
/*
if (owner.equals(""))
{
Toast.makeText(getApplicationContext(), "No Data", Toast.LENGTH_SHORT).show();
}
else
{
//showMessage("Data",buffer.toString());
if (!owner.equals("") && accessLevel.equals("student"))
{
startActivity(loginSuccessAdmin);
}
else
Toast.makeText(getApplicationContext(), "Login Error, Please Login Again", Toast.LENGTH_SHORT).show();
if (textUsername.equals(usernameInfo) && textPassword.equals(passwordInfo))
{
if (accessInfo.equals("admin"))
{
//startActivity(loginSuccessAdmin);
}
else if (accessInfo.equals("student"))
{
Toast.makeText(getApplicationContext(), "Login to Student", Toast.LENGTH_SHORT).show();
//startActivity(loginSuccessStudent);
}
else if (accessInfo.equals("lecturer"))
{
//startActivity(loginSuccessLecturer);
}
else
Toast.makeText(getApplicationContext(), "Access Error, Please Login Again", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(), "Login Error, Please Login Again", Toast.LENGTH_SHORT).show();
}
}*/
}
}
错误日志
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
at project.asyraf.sar.DBHandler.getLoginInfo(DBHandler.java:144)
at project.asyraf.sar.LoginMenu.loginTrial(LoginMenu.java:44)
DBHandler.java:144(accessLevel = cursor.getString(3);)
LoginMenu.java:44(useDB.getLoginInfo(textUsername,textPassword);)
答案 0 :(得分:0)
假设其他一切正常,您的数据库有一个空的Context,因此您需要将其初始化移动到onCreate,其中Context不为null。
DBHandler useDB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_menu);
useDB = new DBHandler(this);
}
虽然,问题似乎是Cursor是空的(没有列)
请求索引0,大小为0
在这种情况下,您需要手动卸载应用程序并重新运行以重新创建表格。
要编写不易出错的查询,可以试试这个。
if (cursor != null && cursor.moveToFirst()) {
accessLevel = cursor.getString(cursor.getColumnIndex("accessLevel"));
owner = cursor.getString(cursor.getColumnIndex("owner"));
}
如果在尝试访问这些变量时出现错误或无效,则检查数据库中是否有数据。
旁注:我不确定将这些存储为实例变量是个好主意。你应该真的返回Cursor或User对象。