I get the following error when running my app using android studio.
Error
==============================================
java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
My database is SQLite. My app allows a user to register and login. Sports app.
From here they can add "Players" to their team. I have two tables set up in my db one for users and one for players with the "user_id" field from users table being used as the foreign key to link both dbs. Basically only the logged in users who add a certain player can see that players information and not all others that other users created.
Originally the app was saving the players to the correct table. However the foreign key was not getting filled. I then re wrote the code to correct this. However this is when i encountered this new problem.
Any help or advice at all is much appreciated.
1) DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "MyDB1.db";
private static final String TABLE_USER = "User";
private static final String COLUMN_USER_NAME = "User_name";
private static final String COLUMN_USER_ID = "User_id";
private static final String COLUMN_USER_EMAIL = "User_email";
private static final String COLUMN_USER_PASSWORD = "User_password";
private static final String TABLE_PLAYERS = "Player";
private static final String COLUMN_PLAYER_NAME = "Player_name";
private static final String COLUMN_PLAYER_AGE = "Player_age";
private static final String COLUMN_PLAYER_WEIGHT = "Player_weight";
private static final String COLUMN_PLAYER_HEIGHT = "Player_height";
private static final String COLUMN_PLAYER_ID = "Player_id";
private static final String FOREIGN_PLAYER_ID = COLUMN_USER_ID;
// private static final Image COLUMN_PLAYER_IMAGE ;
// Table 1 : Login/Register
private String CREATE_USER_TABLE = "CREATE TABLE " + TABLE_USER + "(" + COLUMN_USER_NAME + " TEXT,"
+ COLUMN_USER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_USER_EMAIL + " TEXT," + COLUMN_USER_PASSWORD + " TEXT" + ")";
// Table 2 : Adding players
private String CREATE_PLAYER_TABLE = "CREATE TABLE " + TABLE_PLAYERS + "(" + COLUMN_PLAYER_NAME + " TEXT,"
+ COLUMN_PLAYER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_PLAYER_AGE + " INTEGER," + COLUMN_PLAYER_WEIGHT + " INTEGER," + COLUMN_PLAYER_HEIGHT + " INTEGER, " + FOREIGN_PLAYER_ID + " INTEGER," + "FOREIGN KEY(" + FOREIGN_PLAYER_ID + ") REFERENCES " + TABLE_USER + "(User_id) " + ")";
// Drop tables
private String DROP_USER_TABLE = "DROP TABLE IF EXISTS " + TABLE_USER ;
private String DROP_PLAYER_TABLE = "DROP TABLE IF EXISTS " + TABLE_PLAYERS ;
public DatabaseHelper(Context context){
//String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
if (!db.isReadOnly()) {
// Enable foreign key constraints
db.execSQL("PRAGMA foreign_keys=ON;");
}
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_USER_TABLE);
db.execSQL(CREATE_PLAYER_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(DROP_USER_TABLE);
db.execSQL(DROP_PLAYER_TABLE);
onCreate(db);
}
// Adding a user to Users table
public void addUser(User user){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_USER_NAME, user.getName());
values.put(COLUMN_USER_EMAIL, user.getEmail());
values.put(COLUMN_USER_PASSWORD, user.getPassword());
values.put(FOREIGN_PLAYER_ID, user.getForeignID());
db.insert(TABLE_USER, null, values);
db.close();
}
// Adding a player to players table
public void addPlayer(Player player) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
// Table 2 : Add players info
values.put(COLUMN_PLAYER_NAME, player.getPlayerName());
values.put(COLUMN_PLAYER_AGE, player.getPlayerAge());
values.put(COLUMN_PLAYER_HEIGHT, player.getPlayerHeight());
values.put(COLUMN_PLAYER_WEIGHT, player.getPlayerWeight());
values.put(FOREIGN_PLAYER_ID, player.getForeignKey());
db.insert(TABLE_PLAYERS, null, values);
db.close();
}
// Checking the users email
public boolean checkUser(String email){
String[] columns = {
COLUMN_USER_ID
};
SQLiteDatabase db = this.getWritableDatabase();
String selection = COLUMN_USER_EMAIL + " = ?";
String[] selectionArgs = { email };
Cursor cursor = db.query(TABLE_USER,
columns,
selection,
selectionArgs,
null,
null,
null);
int cursorCount = cursor.getCount();
cursor.close();
db.close();
if (cursorCount > 0){
return true;
}
return false;
}
//
public String getColumnUserName(String email){
String user = "";
String[] columns = {
COLUMN_USER_ID
};
SQLiteDatabase db = this.getWritableDatabase();
String selection = COLUMN_USER_EMAIL + " = ?";
String[] selectionArgs = { email };
Cursor cursor = db.query(TABLE_USER,
columns,
selection,
selectionArgs,
null,
null,
null);
int cursorCount = cursor.getCount();
if (cursor.moveToFirst()) // data?{
user = cursor.getString(cursor.getColumnIndex("EMAIL"));
cursor.close(); // that's important too, otherwise you're gonna leak cursors
db.close();
if (cursorCount > 0){
return user;
}
return user;
}
// Checking the users email and password
public boolean checkUser(String email, String password){
String[] columns = {
COLUMN_USER_ID
};
SQLiteDatabase db = this.getWritableDatabase();
String selection = COLUMN_USER_EMAIL + " = ?" + " AND " + COLUMN_USER_PASSWORD + " =?";
String[] selectionArgs = { email, password };
Cursor cursor = db.query(TABLE_USER,
columns,
selection,
selectionArgs,
null,
null,
null);
int cursorCount = cursor.getCount();
cursor.close();
db.close();
if (cursorCount > 0){
return true;
}
return false;
}
}
2) Players.java
public class Players extends AppCompatActivity {
private Button insert;
private static final int PICK_IMAGE=100;
private String nameFromIntent = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_players);
//Open add players section
insert = (Button) findViewById(R.id.addPlayer);
insert.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick (View v)
{
openaAddPlayersActivity();
}
});
nameFromIntent = getIntent().getStringExtra("EMAIL");
}
private void openaAddPlayersActivity() {
Intent intent = new Intent(this, addPlayers.class );
String nameFromIntent = getIntent().getStringExtra("EMAIL");
intent.putExtra(("EMAIL") ,nameFroenter code heremIntent);
startActivity(intent);
}
}
3)addPlayers.java
public class addPlayers extends AppCompatActivity implements View.OnClickListener{
private Button insert;
private static final int PICK_IMAGE=100;
private final AppCompatActivity activity = addPlayers.this;
private EditText editTextPlayerName;
private EditText editTextPlayerAge;
private EditText editTextPlayerWeight;
private EditText editTextPlayerHeight;
private TextInputEditText textInputEditTextEmail;
private Inputvalidation inputvalidation;
private DatabaseHelper databaseHelper;
private Player player;
private Button appCompatButtonRegister;
private User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_players);
// insert = (Button) findViewById(R.id.profilePicture);
// insert.setOnClickListener(new View.OnClickListener()
getSupportActionBar().hide();
initViews();
initListeners();
initObjects();
}
private void initViews() {
editTextPlayerName = (EditText) findViewById(R.id.playerName);
editTextPlayerAge = (EditText) findViewById(R.id.playerAge);
editTextPlayerHeight = (EditText) findViewById(R.id.playerHeight);
editTextPlayerWeight = (EditText) findViewById(R.id.playerWeight);
textInputEditTextEmail = (TextInputEditText) findViewById(R.id.enterEmail);
appCompatButtonRegister = (Button) findViewById(R.id.savePlayer);
}
private void initListeners() {
appCompatButtonRegister.setOnClickListener(this);
}
private void initObjects() {
inputvalidation = new Inputvalidation(activity);
databaseHelper = new DatabaseHelper(activity);
player = new Player ();
}
// Table 2 : Add players info
@Override
public void onClick(View v) {
// Intent intent = new Intent(Intent.ACTION_PICK, Uri.parse("content://media/internal/images/media"));
//startActivityForResult(intent, PICK_IMAGE);
switch (v.getId()){
case R.id.savePlayer:
postDataToSQLite();
break;
}
}
private void postDataToSQLite() {
if(!databaseHelper.checkUser(editTextPlayerName.getText().toString().trim()))
//textInputEditTextPassword.getText().toString().trim()))
{
Bundle email= getIntent().getExtras();
String a = databaseHelper.getColumnUserName(email.getString("EMAIL"));
player.setPlayerName(editTextPlayerName.getText().toString().trim());
player.setPlayerAge(Integer.parseInt(editTextPlayerAge.getText().toString().trim()));
player.setPlayerHeight(Integer.parseInt(editTextPlayerHeight.getText().toString().trim()));
player.setPlayerWeight(Integer.parseInt(editTextPlayerWeight.getText().toString().trim()));
player.setForeignKey(Integer.parseInt(a));
//Integer.parseInt(databaseHelper.getColumnUserName(ContactsContract.CommonDataKinds.Email.getString("EMAIL"))));
databaseHelper.addPlayer(player);
Snackbar.make(findViewById(R.id.addPlayer), R.string.success_player_message,Snackbar.LENGTH_LONG).show();
// emptyEditText();
Intent accountIntent = new Intent(activity, Players.class);
accountIntent.putExtra("EMAIL", textInputEditTextEmail.getText().toString().trim());
//emptyInputEditText();
startActivity(accountIntent);
}
//else {
// Snack Bar to show error message that record already exists
// Snackbar.make(findViewById(R.id.Register), getString(R.string.error_email_exists), Snackbar.LENGTH_LONG).show();
// }
}
/*protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==RESULT_OK && requestCode==PICK_IMAGE){
Uri uri = data.getData();
String x = getPath(uri);
Toast.makeText(getApplicationContext(), x, Toast.LENGTH_LONG).show();
}
}
private String getPath(Uri uri) {
if(uri==null)return null;
String [] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery(uri, projection, null, null, null);
if(cursor!=null){
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
return uri.getPath();
}
*/
}
4) Login.java
public class LoginActivity extends AppCompatActivity implements View.OnClickListener {
private final AppCompatActivity activity = LoginActivity.this;
private NestedScrollView nestedScrollView;
private TextInputLayout textInputLayoutEmail;
private TextInputLayout textInputLayoutPassword;
private TextInputEditText textInputEditTextEmail;
private TextInputEditText textInputEditTextPassword;
private AppCompatButton appCompatButtonLogin;
private AppCompatTextView textViewLinkRegister;
private Inputvalidation inputvalidation;
private DatabaseHelper databaseHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
getSupportActionBar().hide();
initViews();
initListeners();
initObjects();
}
private void initViews() {
textInputLayoutEmail = findViewById(R.id.textInputLayoutEmail);
textInputLayoutPassword = findViewById(R.id.textInputLayoutPassword);
textInputEditTextEmail = findViewById(R.id.enterEmail);
textInputEditTextPassword = findViewById(R.id.enterPassword);
appCompatButtonLogin = findViewById(R.id.Login);
textViewLinkRegister = findViewById(R.id.textViewLinkRegister);
}
private void initListeners() {
appCompatButtonLogin.setOnClickListener(this);
textViewLinkRegister.setOnClickListener(this);
}
private void initObjects() {
databaseHelper = new DatabaseHelper(activity);
inputvalidation = new Inputvalidation(activity);
}
@Override
public void onClick(View v){
switch (v.getId()){
case R.id.Login:
verifyFromSQLite();
break;
case R.id.textViewLinkRegister:
Intent intentRegister = new Intent(getApplicationContext(), Register.class);
startActivity(intentRegister);
break;
}
}
private void verifyFromSQLite() {
if (!inputvalidation.isInputEditTextFilled(textInputEditTextEmail, textInputLayoutEmail, getString(R.string.error_message_email))){
return;
}
if (!inputvalidation.isInputEditTextEmail(textInputEditTextEmail, textInputLayoutEmail, getString(R.string.error_message_email))){
return;
}
if (!inputvalidation.isInputEditTextFilled(textInputEditTextPassword, textInputLayoutPassword, getString(R.string.error_message_password))){
return;
}
if(databaseHelper.checkUser(textInputEditTextEmail.getText().toString().trim(), textInputEditTextPassword.getText().toString().trim()))
{
Intent accountIntent = new Intent(activity, LoggedIn.class);
accountIntent.putExtra("EMAIL", textInputEditTextEmail.getText().toString().trim());
emptyInputEditText();
startActivity(accountIntent);
}else {
Snackbar.make(findViewById(R.id.Login), R.string.error_valid_email_password,Snackbar.LENGTH_LONG).show();
//nestedScrollView, getString(R.string.error_valid_email_password), Snackbar.LENGTH_LONG).show();
}
}
private void emptyInputEditText() {
textInputEditTextEmail.setText(null);
textInputEditTextPassword.setText(null);
}
}