I'm trying to make a custom search bar for my app and it works fine but I need to include a if/else statement to let my user know that the user he searched for does not exist.I tried implementing a if/else statement but when I try to search a user that's in my database it shows me my else statement of "Username not found" when I know I'm putting in the right Username.
From the code I provided I would like to know what am I doing wrong?
search.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String Username = sbar.getText().toString();
String foundplayer = db.getUsername();
if (Username.equals(foundplayer)) {
ResultFrame.setVisibility(View.VISIBLE);
ResultText.setText(foundplayer);
Toast.makeText(getApplicationContext(), "Player Found", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Username Not Found", Toast.LENGTH_LONG).show();
}
}
});
public String getUsername() {
String[] userName = new String[] { "USERNAME" };
Cursor c = db.query( "NFDB", null, null, null, null, null, null, null);
String result = "";
int iName = c.getColumnIndex("USERNAME");
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
result = c.getString(iName);
}
return result;
}
First make sure that your getUsername() method returning value..
If it returns value then do like this.
String foundplayer = db.getUsername();
this will take sometime to process as it involves getting the data from Database so your compiler will not wait for it to complete because of that compiler will go to if condition before completing getUsername() method. so you will get your foundplayer null
so it will never satisfy the condition.
so call that in a separate thread and let the other statement wait until it completes
String foundplayer = "";
Thread t=new Thread()
{
public void run()
{
foundplayer = db.getUsername();
}
};
t.start();
t.join();
or
equals is case sensitive try equalsIgnoreCase
Your getUsername function actually returns some random user name from the database.
You have to give it the user name to be searched for as a parameter:
public String getUsername(String searchName) {
Cursor c = db.query("NFDB",
new String[] { "USERNAME" },
"USERNAME = ?",
new String[] { searchName },
null, null, null);
if (c.moveToNext())
return c.getString(0);
else
return "";
}
For that matter, it's quite pointless to return the user name from that function, because the caller already knows what name was searched for. You should better return a boolean.
Related
I am working on an app in Android Studio with the following code:
//added this first part to show what c is and what happens with it. I don't use a curser that I know of and it doesn't stop my app from running fine, but I don't like having errors.
#Override
public Iterator<StoredMessage> getAllArrivedMessages(
final String clientHandle) {
return new Iterator<StoredMessage>() {
private Cursor c;
private boolean hasNext;
private final String[] selectionArgs = {
clientHandle,
};
{
db = mqttDb.getWritableDatabase();
// anonymous initialiser to start a suitable query
// and position at the first row, if one exists
if (clientHandle == null) {
c = db.query(ARRIVED_MESSAGE_TABLE_NAME,
null,
null,
null,
null,
null,
"mtimestamp ASC");
} else {
c = db.query(ARRIVED_MESSAGE_TABLE_NAME,
null,
MqttServiceConstants.CLIENT_HANDLE + "=?",
selectionArgs,
null,
null,
"mtimestamp ASC");
}
hasNext = c.moveToFirst();
}
#Override
public boolean hasNext() {
if (!hasNext){
c.close();
}
return hasNext;
}
#Override
public StoredMessage next() {
String messageId = c.getString(c.getColumnIndex(MqttServiceConstants.MESSAGE_ID));
String clientHandle = c.getString(c
.getColumnIndex(MqttServiceConstants.CLIENT_HANDLE));
String topic = c.getString(c
.getColumnIndex(MqttServiceConstants.DESTINATION_NAME));
byte[] payload = c.getBlob(c
.getColumnIndex(MqttServiceConstants.PAYLOAD));
int qos = c.getInt(c.getColumnIndex(MqttServiceConstants.QOS));
boolean retained = Boolean.parseBoolean(c.getString(c
.getColumnIndex(MqttServiceConstants.RETAINED)));
boolean dup = Boolean.parseBoolean(c.getString(c
.getColumnIndex(MqttServiceConstants.DUPLICATE)));
// build the result
MqttMessageHack message = new MqttMessageHack(payload);
message.setQos(qos);
message.setRetained(retained);
message.setDuplicate(dup);
// move on
hasNext = c.moveToNext();
return new DbStoredData(messageId, clientHandle, topic, message);
}
I am getting the following error message:
Value must be ≥ 0 but 'getColumnIndex' can be -1
for each of the 'getColumnIndex above.
This is an error code since it is a red circle with an exclamation point in the middle displayed in the "Problems/Current File" window of my Android Studio project.
How do I rewrite them to get rid of the error messages?
This question already has an answer here:
sqlite get ROWID
(1 answer)
Closed 1 year ago.
I have an android studio app that uses sqlite to save user data such as username, password, etc. In the login page after the user enters his login credentials, the user clicks on a button that calls the following function from a DatabaseHelper java class to check if the info is correct:
public boolean checkLogin(String username, String password){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM user WHERE username=? AND password=? ",
new String[] {username, password});
if (cursor.getCount() > 0){
return true;
}
else {
return false;
}
}
I want to save the row ID that matches this user so I can use it in the future and I was thinking of saving the ID into a variable that I will then send to different activities using an intent. The issue is that I can't figure out how to save the ID from the query.
I'd suggest returning a int rather than boolean the long being the id or -1 if the user/password combination doesn't exist. So :-
public int checkLogin(String username, String password){
int rv = -1;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM user WHERE username=? AND password=? ",
new String[] {username, password});
if (cursor.moveToFirst()) {
rv = cursor.getInt(cursor.getColumnIndex("id"));
}
cursor.close();
return rv;
}
Instead of using something like :-
if (checkLogin("the_user","the_password")) {
logged in code ....
} else {
not logged in code ....
}
You could use something like :-
private int current_userid = -1; // probably declared as a class variable
....
if ((current_userid = db.checkLogin("the_user","the_password")) > 0 ) {
logged in OK code ....
} else {
not logged in code ....
}
I want to save the row ID that matches this user so I can use it in the future and I was thinking of saving the ID into a variable that I will then send to different activities using an intent.
Here's an example that does that and sends the id to another Activity (NextActivity) and then returns (finishes) from that activity after writing the username and password to the log.
First the Database Helper DBHelper :-
class DBHelper extends SQLiteOpenHelper {
SQLiteDatabase db;
public DBHelper(#Nullable Context context) {
super(context, "mydb", null, 1);
db = this.getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS user (" +
"id INTEGER PRIMARY KEY, " +
"username TEXT UNIQUE, " +
"password TEXT " +
")");
ContentValues cv = new ContentValues();
cv.put("username","fred");
cv.put("password","password_for_fred");
db.insert("user",null,cv);
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) { }
public int checkLogin(String username, String password){
int rv = -1;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM user WHERE username=? AND password=? ",
new String[] {username, password});
if (cursor.moveToFirst()) {
rv = cursor.getInt(cursor.getColumnIndex("id"));
}
cursor.close();
return rv;
}
public Cursor getUserById(int userId) {
return db.query("user",null,"id=?",new String[]{String.valueOf(userId)},null,null,null);
}
}
Note that this uses a single class variable for the SQLiteDatabase, so only needs the 1 getWriteableDatabase. It also forces the database to open when constructing by including db = this.getWriteableDatabase(); in the constructor.
Note the added method getUserById(ing userId) method which returns a Cursor according to the userId.
Note that a demo user is added to the table when it is created.
MainActivity (a little overly complex as it demonstrates both a failed login attempt (1st) as well as a successful login attempt (as part of handling the failed attempt)) :-
public class MainActivity extends AppCompatActivity {
public static final String INTENT_EXTRA_CURRENT_USERID = "current_userid";
DBHelper db;
private int current_userid = -1;
private Intent intent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new DBHelper(this);
Log.d("LOGIN1","Attempting to Login"); // Will purposefully fail login
if ((current_userid = db.checkLogin("the_user","the_password")) > 0 ) {
Log.d("LOGIN2","Successfully Logged in to user with ID = " + String.valueOf(current_userid));
gotoNextActivity();
} else {
Toast.makeText(this,"Invalid Login, please try again",Toast.LENGTH_SHORT).show();
Log.d("LOGIN1","First attempt to login failed");
// Make 2nd attempt (will work as username and password are correct)
Log.d("LOGIN2","Attemtping to Login (2nd) ");
if((current_userid = db.checkLogin("fred","password_for_fred")) > 0 ) {
Log.d("LOGIN2","Successfully Logged in to user with ID = " + String.valueOf(current_userid));
gotoNextActivity();
}
}
}
private void gotoNextActivity() {
intent = new Intent(this,NextActivity.class);
intent.putExtra(INTENT_EXTRA_CURRENT_USERID,current_userid);
startActivity(intent);
}
}
Finally NextActivity :-
public class NextActivity extends AppCompatActivity {
private int current_userid;
private String current_username, current_password;
private DBHelper db;
Cursor csr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_next);
db = new DBHelper(this);
current_userid = this.getIntent().getIntExtra(MainActivity.INTENT_EXTRA_CURRENT_USERID,-1);
csr = db.getUserById(current_userid);
if (csr.moveToFirst()) {
current_username = csr.getString(csr.getColumnIndex("username"));
current_password = csr.getString(csr.getColumnIndex("password"));
}
if (current_userid > 0) {
Log.d("NEXTACTIVTY","Valid user ID - Username = " + current_username + " password is " + current_password);
} else {
Log.d("NEXTACTIVITY","No Valid userid?");
}
// Finish the Activity and hence return to MainActivity
// Hence it is unlikely that the NextActivity will even be noticed.
finish();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (!csr.isClosed()) {
csr.close();
Log.d("NEXTACTIVITY","Closing Cursor in onDestroy method");
}
}
}
Result
When run the log includes :-
2021-07-17 12:19:37.201 D/LOGIN1: Attempting to Login
2021-07-17 12:19:37.211 D/LOGIN1: First attempt to login failed
2021-07-17 12:19:37.211 D/LOGIN2: Attemtping to Login (2nd)
2021-07-17 12:19:37.212 D/LOGIN2: Successfully Logged in to user with ID = 1
2021-07-17 12:19:37.392 D/NEXTACTIVTY: Valid user ID - Username = fred password is password_for_fred
2021-07-17 12:19:37.745 D/NEXTACTIVITY: Closing Cursor in onDestroy method
Basically you just need the
cursor.getInt([column position])
or
cursor.getString([column position])
to retrieve the data from the columns in the database. I made an example I hope this helps you. I'm not very familiar with programming language some cases so I can't argue more.
public class User {
private int id;
private String name;
private String password;
private boolean isLogged = false;
public User() {
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public boolean isLogged() {
return isLogged;
}
public void setLogged(boolean x) {
this.isLogged = x;
}
}
Method to retrieve the Id requested you could just create a String or something..
public User checkLogin(String username, String password) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM user WHERE username=? AND password=? ", new String[] {username, password});
if (cursor.moveToFirst() || cursor.getCount() > 0) {
User user = new User();
user.setId(cursor.getInt(0));//if you created a primary key should be the first column
user.setLogged(true);
cursor.close();// * Closes the Cursor, releasing all of its resources and making it completely invalid.
db.close(); // * Releases a reference to the object, closing the object if the last reference* was released.
return user;
} else {
return null;
}
}
For my application login I want use this library : https://github.com/alphamu/PinEntryEditText
In this library for check password use below method :
final PinEntryEditText pinEntry = (PinEntryEditText) findViewById(R.id.txt_pin_entry);
if (pinEntry != null) {
pinEntry.setOnPinEnteredListener(new PinEntryEditText.OnPinEnteredListener() {
#Override
public void onPinEntered(CharSequence str) {
if (str.toString().equals("1234")) {
Toast.makeText(AnimatedEditTextWidgetsActivity.this, "SUCCESS", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(AnimatedEditTextWidgetsActivity.this, "FAIL", Toast.LENGTH_SHORT).show();
pinEntry.setText(null);
}
}
});
}
Check with String constructor :
public void onPinEntered(CharSequence str) { ... }
But my query for check password this :
public Boolean login(String password, SQLiteDatabase db) throws SQLException {
Cursor cursor = db.rawQuery("SELECT * FROM " + UserContract.NewUserInfo.TABLE_NAME +
" WHERE " + UserContract.NewUserInfo.USER_PASSWORD + "=?", new String[]{password});
if (cursor != null) {
if (cursor.getCount() > 0) {
return true;
}
}
return false;
}
How can I check password from SQLite with CharSequence str in above library ?!
Please edit my code, because I am amateur and I really need this tutorial. Thanks all <3
As String implements CharSequence you can use a String anywhere you need CharSequence -- to get a String from a CharSequence use toString():
public void onPinEntered(CharSequence str) {
if( login( str.toString() ) {
Toast.makeText(AnimatedEditTextWidgetsActivity.this, "SUCCESS", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(AnimatedEditTextWidgetsActivity.this, "FAIL", Toast.LENGTH_SHORT).show();
pinEntry.setText(null);
}
}
Tips:
Use boolean instead of Boolean if you don't need a nullable result.
You generally don't want to do heavy lifting on the UI thread. You'll probably get away with running a quick sqlite query, but your UI will become unresponsive if you do longer operations.
I'm developing an android app, in which users enter their name, surname, email and password for registration purpose. This entry process works perfectly fine, now I want to check every time, when a user enters his/her email, that the entered email is exists already in my database or not.
for this I tried the following method in my DBHelper class:
public String Exist(String user) {
String username="";
SQLiteDatabase db = this.getReadableDatabase();
try {
Cursor c = db.query(TABLE_NAME, null, "COL_4" + "=?", new String[]{String.valueOf(user)},null, null, null);
if (c == null) {
return username;
}
else {
c.moveToFirst();
username = c.getString(c.getColumnIndex("COL_4"));
}
}
catch(Exception e){
}
return username;
}
here TABLE_NAME is the name of my table, COL_4 is the column which contains emails of the users and I'm passing the entered string (email) entered by user as parameter of this method.
I'm calling this method from my main activity class as following:
String myUser = email.getText().toString();
String storedUser = myDb.Exist(myUser);
//If Username exist
if (myUser.equals(storedUser)) {
Toast.makeText(getApplicationContext(), "Username already exist!", Toast.LENGTH_SHORT).show();
return;
}
here I'm storing entered email in myUser variable.
The problem is that even the email is entered same as previously entered, it allows to insert the data in database. That means every time the exception occurs and "" is returned. What is error in Exists method?
Okay, I found answer by myself!
I used following code in DBHelper Class:
public boolean Exists(String user){
Cursor res = getAllData();
int flag=0;
while (res.moveToNext()){
String email =res.getString(3);
if(email.equals(user)){
flag++;
}
}
if(flag==0){
return false;
}
else {
return true;
}
}
and following code in my main activity:
//If Username exist
if (myDb.Exists(email.getText().toString())) {
showMessage("Error :(","This username is already exists.");
return;
}
You Can get that in the query itself
*SELECT * FROM TABLE_NAME WHERE Col = 'user email id';*
If you pass the Table name and column name correctly, it will return the cursor. Below I have put a method which will return true if the email id exists in the table.
public boolean isEmailExists(String emailAddress) {
SQLiteDatabase db =null; DatabaseHelper.getInstance(context).getReadableDatabase();
Cursor cursor = null;
String selectQuery = "SELECT * FROM Table_name WHERE COLUMN_NAME ='emailAddress';";
cursor = db.rawQuery(selectQuery, null);
if (cursor != null && cursor.getCount() > 0) {
return true;
}
return false;
}
As I mentioned earlier appropriate Table name and column name has been given correctly.
I'm new programmer, I need just one value ("IdUser") of SQLite and parse to String variable, but I don't have any idea to catch it and return that value. My app stopped because of this.
Activity.java
public void onClick(View arg0) {
String LOGIN2 ="Users";
String eti = loginDataBaseAdapter.CheckEtiqueta(LOGIN2);
Toast.makeText(getApplicationContext(), eti, Toast.LENGTH_LONG).show();
}
UsersDatabaseHelper.java
public String CheckEtiqueta(String LOGIN2) {
Cursor c = db.rawQuery("SELECT * FROM "+LOGIN2+" WHERE IdUser = 20 ORDER BY IdUser LIMIT1", null);
while (c.moveToNext()) {
//Sample operation with the Database
if (c.getString(c.getColumnIndex("IdUser"))!=null) {
LOGIN2=c.getString(c.getColumnIndex("IdUser"));
return LOGIN2;
}
}
return LOGIN2;
}
Thanks
First of all please correct your SQL query. and why you are returning the same variable that function received. You also havn't opened your database.
To open database.
public void openDatabase()
{
database = dbHelper.getWritableDatabase();
}
And To close :
public void closeDatabase()
{
if (database != null && database.isOpen())
database.close();
}
Add openDatabase() call before Cursor statement and Don't forget to closeDatabase() once you done with it.
EDIT :
Ideal Code :
public User getUserByID(int userID)
{
openDatabase();
Cursor userByID= database.rawQuery("select * from UsersTable where UserID = " + userID, null);
User user = new User();
userByID.moveToFirst();
user.setName(userByID.getString(userByID.getColumnIndex("UserName")));
userByID.close();
closeDatabase();
return User;
}